mirror of
https://github.com/mileswolfallen2/miles-web.git
synced 2026-09-08 11:23:17 +00:00
Add uses page and interactive features including toast notifications, cursor effects, and theme toggle
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<link rel="canonical" href="https://milesallen.site/404.html">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<style>
|
||||
:root{
|
||||
--bg:#000;--text:#fff;--muted:#666;--accent:#FF3D9A;--tape:#FFC93C;--red:#FF0000;
|
||||
@@ -72,6 +72,16 @@
|
||||
}
|
||||
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;}}
|
||||
</style>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://milesallen.site/" },
|
||||
{ "@type": "ListItem", "position": 2, "name": "404", "item": "https://milesallen.site/404.html" }
|
||||
]
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="cursor-dot" id="cursorDot"></div>
|
||||
@@ -88,37 +98,16 @@
|
||||
<a href="javascript:history.back()" class="btn btn-back">Go Back</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;revealCursor();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function revealCursor(){
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script src="projects/script.js"></script>
|
||||
<footer style="text-align:center;padding:40px 24px;font-family:var(--font-mono);font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;position:relative;z-index:20;">
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
+22
-91
@@ -11,8 +11,18 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="stylesheet" href="projects/style.css">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://milesallen.site/" },
|
||||
{ "@type": "ListItem", "position": 2, "name": "About Me", "item": "https://milesallen.site/about-me.html" }
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
.article-eyebrow{font-family:var(--font-pixel);font-size:10px;color:var(--tape);margin-bottom:12px;text-transform:uppercase;letter-spacing:.1em;}
|
||||
@@ -87,14 +97,14 @@
|
||||
<div class="article-body">
|
||||
|
||||
<h2>The Basics</h2>
|
||||
<img src="photos/me.jpeg" alt="Miles" style="float:left;width:240px;height:240px;border:2px solid var(--accent);object-fit:cover;margin:0 24px 16px 0;shape-outside:circle(50%);clip-path:circle(50%);">
|
||||
<img src="photos/me.jpeg" alt="Miles" loading="lazy" style="float:left;width:240px;height:240px;border:2px solid var(--accent);object-fit:cover;margin:0 24px 16px 0;shape-outside:circle(50%);clip-path:circle(50%);">
|
||||
<p>I'm Miles Wolf Allen. I build things on the internet — tools, games, apps, websites. Some of them are useful. Some of them are just fun. Most of them started because I got annoyed at something and decided I could do it better.</p>
|
||||
<p>I'm a Christian. Baptist. My faith is a big part of who I am and how I see the world. It shapes the way I build things — I care about doing good work, being honest, and building stuff that actually helps people instead of just looking cool.</p>
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
<h2>My Family</h2>
|
||||
<img src="photos/mom:dad.jpeg" alt="Mom and Dad" style="float:right;width:240px;height:240px;border:2px solid var(--tape);object-fit:cover;margin:0 0 16px 24px;shape-outside:circle(50%);clip-path:circle(50%);">
|
||||
<img src="photos/mom-dad.jpeg" alt="Mom and Dad" loading="lazy" style="float:right;width:240px;height:240px;border:2px solid var(--tape);object-fit:cover;margin:0 0 16px 24px;shape-outside:circle(50%);clip-path:circle(50%);">
|
||||
<p>My dad is Mark Allen. He's the founding lead pastor of <strong>Pursuit Community Church</strong> in Mounds View, Minnesota. He planted the church in November 2018 after spending over 15 years in youth ministry. Pursuit is a Converge-affiliated church that launched with over 300 people and has been growing ever since. Dad is passionate about reaching people who are far from God and building a church where everyone is known and knows others.</p>
|
||||
<p>When he's not preaching or meeting with people, you'll find him playing golf, softball, or vintage video games.</p>
|
||||
<p>My mom is a loving mother and fun person. I have a sister named Macy. Macy is a big fan of Forest Frank — if you know, you know.</p>
|
||||
@@ -109,7 +119,7 @@
|
||||
<p>My dad and I are both libertarian. We believe in personal freedom, limited government, and the idea that people should be left alone to live their lives as they see fit. We don't fit neatly into either political box, and honestly, we're fine with that.</p>
|
||||
|
||||
<h2>Pets</h2>
|
||||
<img src="photos/dog.jpeg" alt="Meeko" style="float:right;width:240px;height:240px;border:2px solid var(--accent);object-fit:cover;margin:0 0 16px 24px;shape-outside:circle(50%);clip-path:circle(50%);">
|
||||
<img src="photos/dog.jpeg" alt="Meeko" loading="lazy" style="float:right;width:240px;height:240px;border:2px solid var(--accent);object-fit:cover;margin:0 0 16px 24px;shape-outside:circle(50%);clip-path:circle(50%);">
|
||||
<p>This is Meeko. He's a mutt and a rescue, and he's the best dog I could ask for. He was named after Meeko from <em>Pocahontas</em> — if you've seen the movie, you know he's a little rascal who's always getting into trouble. Our Meeko lives up to the name.</p>
|
||||
<p>There's something about rescuing a dog that hits different. He needed a home, we had one, and now he's part of the family. He's proof that the best things in life aren't purebred or expensive — they just need someone to give them a chance.</p>
|
||||
|
||||
@@ -145,6 +155,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -177,92 +194,6 @@
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='index.html';
|
||||
if(e.key==='b'||e.key==='B')window.location.href='index.html#blog';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="projects/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -9,9 +9,27 @@
|
||||
<meta property="og:title" content="CommandMove: Cut & Paste on Mac | Miles Wolf Allen">
|
||||
<meta property="og:description" content="How I added true cut-and-paste to macOS Finder with CommandMove — global event taps, AppleScript, and Accessibility permissions.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="article:published_time" content="2026-02-15">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "CommandMove: Cut & Paste on Mac | Miles Wolf Allen",
|
||||
"description": "How I added true cut-and-paste to macOS Finder with CommandMove — global event taps, AppleScript, and Accessibility permissions.",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Miles Wolf Allen",
|
||||
"url": "https://milesallen.site/"
|
||||
},
|
||||
"datePublished": "2026-02-15",
|
||||
"url": "https://milesallen.site/blog/command-move-devlog.html",
|
||||
"mainEntityOfPage": "https://milesallen.site/blog/command-move-devlog.html"
|
||||
}
|
||||
</script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="../projects/style.css">
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
@@ -141,19 +159,23 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
fetch('https://api.github.com/repos/mileswolfallen2/')
|
||||
.then(r => r.json())
|
||||
.then(d => {})
|
||||
.catch(() => {});
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="../projects/script.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
@@ -174,92 +196,6 @@
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+28
-92
@@ -9,9 +9,27 @@
|
||||
<meta property="og:title" content="Running the FEDL | Miles Wolf Allen">
|
||||
<meta property="og:description" content="The story behind FEDL — running the Geometry Dash demon list, 3,800+ verified runs, and how a Discord conversation turned into a community.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="article:published_time" content="2025-06-15">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "Running the FEDL | Miles Wolf Allen",
|
||||
"description": "The story behind FEDL — running the Geometry Dash demon list, 3,800+ verified runs, and how a Discord conversation turned into a community.",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Miles Wolf Allen",
|
||||
"url": "https://milesallen.site/"
|
||||
},
|
||||
"datePublished": "2025-06-15",
|
||||
"url": "https://milesallen.site/blog/fedl-devlog.html",
|
||||
"mainEntityOfPage": "https://milesallen.site/blog/fedl-devlog.html"
|
||||
}
|
||||
</script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="../projects/style.css">
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
@@ -133,19 +151,23 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
fetch('https://api.github.com/repos/mileswolfallen2/')
|
||||
.then(r => r.json())
|
||||
.then(d => {})
|
||||
.catch(() => {});
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="../projects/script.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
@@ -166,92 +188,6 @@
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+27
-91
@@ -9,6 +9,24 @@
|
||||
<meta property="og:title" content="Why I Built Gelectron | Miles Wolf Allen">
|
||||
<meta property="og:description" content="Why I built Gelectron — a Firefox-engine alternative to Electron. Memory usage, efficiency, and why bundling Chromium with every app is a problem.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="article:published_time" content="2026-03-15">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "Why I Built Gelectron | Miles Wolf Allen",
|
||||
"description": "Why I built Gelectron — a Firefox-engine alternative to Electron. Memory usage, efficiency, and why bundling Chromium with every app is a problem.",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Miles Wolf Allen",
|
||||
"url": "https://milesallen.site/"
|
||||
},
|
||||
"datePublished": "2026-03-15",
|
||||
"url": "https://milesallen.site/blog/gelectron-devlog.html",
|
||||
"mainEntityOfPage": "https://milesallen.site/blog/gelectron-devlog.html"
|
||||
}
|
||||
</script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
@@ -151,19 +169,23 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
fetch('https://api.github.com/repos/mileswolfallen2/')
|
||||
.then(r => r.json())
|
||||
.then(d => {})
|
||||
.catch(() => {});
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="../projects/script.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
@@ -184,92 +206,6 @@
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+28
-92
@@ -9,9 +9,27 @@
|
||||
<meta property="og:title" content="Building Nova AI | Miles Wolf Allen">
|
||||
<meta property="og:description" content="How I built Nova AI — a local AI assistant with desktop GUI, web interface, and CLI. No cloud, no subscriptions, no data leaving your machine.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="article:published_time" content="2025-09-15">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "Building Nova AI | Miles Wolf Allen",
|
||||
"description": "How I built Nova AI — a local AI assistant with desktop GUI, web interface, and CLI. No cloud, no subscriptions, no data leaving your machine.",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Miles Wolf Allen",
|
||||
"url": "https://milesallen.site/"
|
||||
},
|
||||
"datePublished": "2025-09-15",
|
||||
"url": "https://milesallen.site/blog/nova-devlog.html",
|
||||
"mainEntityOfPage": "https://milesallen.site/blog/nova-devlog.html"
|
||||
}
|
||||
</script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="../projects/style.css">
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
@@ -141,19 +159,23 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
fetch('https://api.github.com/repos/mileswolfallen2/')
|
||||
.then(r => r.json())
|
||||
.then(d => {})
|
||||
.catch(() => {});
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="../projects/script.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
@@ -174,92 +196,6 @@
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+28
-92
@@ -9,9 +9,27 @@
|
||||
<meta property="og:title" content="Why I Built OmniEmu | Miles Wolf Allen">
|
||||
<meta property="og:description" content="The story behind OmniEmu 2.0 — why I built a cross-platform emulator manager because I was tired of opening 15 different apps.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="article:published_time" content="2026-01-15">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "Why I Built OmniEmu | Miles Wolf Allen",
|
||||
"description": "The story behind OmniEmu 2.0 — why I built a cross-platform emulator manager because I was tired of opening 15 different apps.",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Miles Wolf Allen",
|
||||
"url": "https://milesallen.site/"
|
||||
},
|
||||
"datePublished": "2026-01-15",
|
||||
"url": "https://milesallen.site/blog/omniemu-devlog.html",
|
||||
"mainEntityOfPage": "https://milesallen.site/blog/omniemu-devlog.html"
|
||||
}
|
||||
</script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="../projects/style.css">
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
@@ -126,19 +144,23 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
fetch('https://api.github.com/repos/mileswolfallen2/')
|
||||
.then(r => r.json())
|
||||
.then(d => {})
|
||||
.catch(() => {});
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="../projects/script.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
@@ -159,92 +181,6 @@
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Colophon | Miles Wolf Allen</title>
|
||||
<meta name="description" content="Behind the scenes of milesallen.site — the tech stack, fonts, design choices, and philosophy behind this portfolio.">
|
||||
<link rel="canonical" href="https://milesallen.site/colophon.html">
|
||||
<meta property="og:title" content="Colophon | Miles Wolf Allen">
|
||||
<meta property="og:description" content="Behind the scenes of milesallen.site — the tech stack, fonts, design choices, and philosophy behind this portfolio.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:url" content="https://milesallen.site/colophon.html">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="stylesheet" href="projects/style.css">
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
.article-eyebrow{font-family:var(--font-pixel);font-size:10px;color:var(--tape);margin-bottom:12px;text-transform:uppercase;letter-spacing:.1em;}
|
||||
.article-date{font-family:var(--font-mono);font-size:12px;color:var(--muted);margin-bottom:8px;}
|
||||
.article-header h1{font-family:var(--font-pixel);font-size:clamp(24px,5vw,44px);line-height:1.2;margin-bottom:16px;transform:rotate(-1deg);transform-origin:left center;text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--tape);animation:glitch 5s ease-in-out infinite;}
|
||||
@keyframes glitch{0%,90%,100%{text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--tape);}92%{text-shadow:3px 3px 0 var(--red),-2px -2px 0 var(--accent);transform:rotate(-1deg) translateX(2px);}94%{text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--red);transform:rotate(-1deg) translateX(-2px);}}
|
||||
.article-tagline{font-size:16px;color:var(--muted);max-width:600px;line-height:1.7;font-family:var(--font-mono);margin-bottom:24px;}
|
||||
.article-body{max-width:720px;}
|
||||
.article-body h2{font-family:var(--font-pixel);font-size:16px;color:var(--accent);margin:40px 0 16px;text-transform:uppercase;}
|
||||
.article-body h3{font-family:var(--font-mono);font-weight:700;font-size:16px;margin:32px 0 12px;color:var(--text);}
|
||||
.article-body p{font-size:14px;color:#ccc;line-height:1.9;font-family:var(--font-mono);margin-bottom:16px;}
|
||||
.article-body code{background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);padding:2px 6px;font-size:12px;font-family:var(--font-mono);}
|
||||
.article-body blockquote{border-left:3px solid var(--accent);padding:12px 20px;margin:24px 0;background:rgba(255,255,255,0.02);font-style:italic;color:var(--muted);font-family:var(--font-mono);font-size:13px;}
|
||||
.article-body ul{margin:12px 0 16px 20px;font-family:var(--font-mono);font-size:13px;color:#ccc;line-height:1.8;}
|
||||
.article-body ul li{margin-bottom:6px;}
|
||||
.article-body ul li::marker{color:var(--accent);}
|
||||
.article-body ul li strong{color:var(--text);}
|
||||
.back-link{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:12px;color:var(--muted);margin-top:40px;text-decoration:none;transition:color .2s;}
|
||||
.back-link:hover{color:var(--accent);}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="cursor-dot" id="cursorDot"></div>
|
||||
<div class="cursor-ring" id="cursorRing"></div>
|
||||
<div class="progress-bar" id="progressBar"></div>
|
||||
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme"></button>
|
||||
<div class="shortcut-modal" id="shortcutModal">
|
||||
<div class="shortcut-card">
|
||||
<h3>Keyboard Shortcuts</h3>
|
||||
<div class="shortcut-row"><span>Go Home</span><kbd>H</kbd></div>
|
||||
<div class="shortcut-row"><span>Go to GitHub</span><kbd>G</kbd></div>
|
||||
<div class="shortcut-row"><span>Toggle theme</span><kbd>T</kbd></div>
|
||||
<div class="shortcut-row"><span>Show shortcuts</span><kbd>?</kbd></div>
|
||||
<div class="close-hint">Press Esc or ? to close</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flash" id="flash"></div>
|
||||
<div class="toast-stack" id="toastStack"></div>
|
||||
<nav class="mobile-nav">
|
||||
<a href="index.html">Home</a>
|
||||
<a href="projects/fedl.html">FEDL</a>
|
||||
<a href="projects/omniemu.html">OmniEmu</a>
|
||||
<a href="projects/command-move.html">CommandMove</a>
|
||||
<a href="https://github.com/mileswolfallen2" target="_blank">GitHub</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<nav>
|
||||
<a href="index.html" class="nav-logo"><span class="logo-dot"></span> milesallen</a>
|
||||
<div class="nav-links">
|
||||
<a href="index.html#about">About</a>
|
||||
<a href="index.html#skills">Skills</a>
|
||||
<a href="index.html#projects">Projects</a>
|
||||
<a href="index.html#contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="article-header">
|
||||
<div class="breadcrumb">
|
||||
<a href="index.html">Home</a>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
<span>Colophon</span>
|
||||
</div>
|
||||
<div class="article-eyebrow">// BUILD NOTES</div>
|
||||
<div class="article-date">2026</div>
|
||||
<h1>Colophon</h1>
|
||||
<p class="article-tagline">Behind the scenes of milesallen.site — how it's built, what it runs on, and why it looks the way it does.</p>
|
||||
</section>
|
||||
|
||||
<section class="reveal">
|
||||
<div class="article-body">
|
||||
<h2>Tech Stack</h2>
|
||||
<ul>
|
||||
<li><strong>Vanilla HTML/CSS/JS</strong> — no frameworks, no build tools, no dependencies. Every page is hand-written. I wanted the site to be fast and simple.</li>
|
||||
<li><strong>GSAP</strong> — For scroll-triggered animations, parallax effects, and entrance sequences. I use ScrollTrigger for most of the scroll-based animations.</li>
|
||||
<li><strong>GitHub API</strong> — Live fetching of repository stats (stars, forks, language) on project pages.</li>
|
||||
<li><strong>FEDL API</strong> — Live stats from the FEDL server on the FEDL project page.</li>
|
||||
<li><strong>Netlify</strong> — Hosting and deployment. Push to main, it goes live. Simple.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Fonts</h2>
|
||||
<ul>
|
||||
<li><strong>Press Start 2P</strong> — Pixel font for headings, section titles, and tags. Gives the site its retro arcade feel.</li>
|
||||
<li><strong>Space Mono</strong> — Monospace font for body text, code, and technical content. Readable at small sizes, distinctive at large.</li>
|
||||
<li><strong>Inter</strong> — Sans-serif for readable paragraphs and descriptions. Balances out the chaos of the other two fonts.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Design Philosophy</h2>
|
||||
<p>The site is inspired by <strong>overrides.com</strong> and the early web — a time when websites weren't afraid to be ugly, weird, and full of personality. The tilted cards, the scan line overlay, the glitch effects, the chaotic navigation — they're intentional.</p>
|
||||
<p>I wanted the site to feel alive. The custom cursor, the progress bar, the hue-shifting background, the scroll-triggered animations — they're small touches that make the page feel responsive and present.</p>
|
||||
<p>The color palette is minimal: black background, white text, hot pink accents, and yellow tape strips. No gradients, no complex color schemes. Just high contrast and aggressive accent colors.</p>
|
||||
|
||||
<h2>Accessibility</h2>
|
||||
<p>The custom cursor hides the default cursor site-wide, but the Konami code (↑ ↑ ↓ ↓ ← → ← → B A) reveals it. The site supports keyboard navigation via the <code>?</code> shortcut modal. Light mode reduces eye strain in bright environments.</p>
|
||||
|
||||
<h2>Performance</h2>
|
||||
<p>No frameworks, no build step, no unnecessary dependencies. The site is static HTML with minimal JavaScript. Fonts are loaded with preconnect hints. GSAP is loaded from CDN with browser caching. Each page is under 50KB of HTML.</p>
|
||||
|
||||
<blockquote>Build for the web like it's 1999, but with today's tools.</blockquote>
|
||||
|
||||
<div style="margin-top:40px;padding-top:20px;border-top:2px solid rgba(255,255,255,0.12);font-family:var(--font-mono);font-size:12px;color:var(--muted);display:flex;gap:16px;flex-wrap:wrap;">
|
||||
<a href="uses.html" style="color:var(--accent);text-decoration:none;">→ What I use</a>
|
||||
<a href="now.html" style="color:var(--accent);text-decoration:none;">→ What I'm doing now</a>
|
||||
</div>
|
||||
|
||||
<a href="index.html" class="back-link">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><polyline points="15 18 9 12 15 6"/></svg>
|
||||
Back to Home
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script src="projects/script.js"></script>
|
||||
<script>
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
const heroTl = gsap.timeline({ defaults: { ease: 'power3.out' } });
|
||||
heroTl
|
||||
.from('.breadcrumb', { x: -30, opacity: 0, duration: 0.6 })
|
||||
.from('.article-header h1', { y: 50, opacity: 0, duration: 0.8 }, '-=0.3')
|
||||
.from('.article-tagline', { y: 30, opacity: 0, duration: 0.7 }, '-=0.4');
|
||||
gsap.from('nav', { y: -20, opacity: 0, duration: 0.6, ease: 'power2.out' });
|
||||
document.querySelectorAll('.article-body h2').forEach(title => {
|
||||
gsap.from(title, { scrollTrigger: { trigger: title, start: 'top 85%' }, y: 30, opacity: 0, duration: 0.7, ease: 'power3.out' });
|
||||
});
|
||||
document.querySelectorAll('.article-body p, .article-body ul, .article-body blockquote').forEach(el => {
|
||||
gsap.from(el, { scrollTrigger: { trigger: el, start: 'top 88%' }, y: 20, opacity: 0, duration: 0.6, ease: 'power3.out' });
|
||||
});
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='h'||e.key==='H')window.location.href='index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+42
-163
@@ -18,9 +18,25 @@
|
||||
<meta name="twitter:title" content="Miles Wolf Allen | Developer & 3D Artist">
|
||||
<meta name="twitter:description" content="Portfolio of Miles Wolf Allen — developer, 3D artist, and builder of emulators, games, and tools.">
|
||||
<meta name="twitter:image" content="https://milesallen.site/og.png">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.png">
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Person",
|
||||
"name": "Miles Wolf Allen",
|
||||
"url": "https://milesallen.site/",
|
||||
"image": "https://avatars.githubusercontent.com/u/115095719?v=4",
|
||||
"sameAs": [
|
||||
"https://github.com/mileswolfallen2",
|
||||
"https://replit.com/@mileswolfallen2"
|
||||
],
|
||||
"jobTitle": "Developer",
|
||||
"knowsAbout": ["Software Development", "Game Development", "Emulator Development"]
|
||||
}
|
||||
</script>
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="projects/style.css">
|
||||
<style>
|
||||
:root{
|
||||
--bg:#000;
|
||||
@@ -48,38 +64,16 @@
|
||||
}
|
||||
|
||||
.vignette{position:fixed;inset:0;pointer-events:none;z-index:9997;background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,0.7) 100%);}
|
||||
.flash{position:fixed;inset:0;pointer-events:none;z-index:10000;background:#fff;opacity:0;}
|
||||
.spark{position:fixed;z-index:9996;pointer-events:none;width:5px;height:5px;border-radius:50%;background:#fff;}
|
||||
|
||||
*{cursor:none !important;}
|
||||
.cursor-dot,.cursor-ring{position:fixed;top:0;left:0;pointer-events:none;z-index:99999;border-radius:50%;}
|
||||
.cursor-dot{
|
||||
width:6px;height:6px;background:var(--accent);
|
||||
transform:translate(-50%,-50%);transition:width .2s,height .2s,background .2s;
|
||||
}
|
||||
.cursor-ring{
|
||||
width:36px;height:36px;border:2px solid var(--accent);
|
||||
transform:translate(-50%,-50%);transition:width .3s,height .3s,border-color .3s,opacity .3s;
|
||||
opacity:.5;
|
||||
}
|
||||
.cursor-dot.hover{width:10px;height:10px;background:var(--tape);}
|
||||
.cursor-ring.hover{width:50px;height:50px;border-color:var(--tape);opacity:.8;}
|
||||
@media(max-width:720px){.cursor-dot,.cursor-ring{display:none;}}
|
||||
@media(hover:none){.cursor-dot,.cursor-ring{display:none;}}
|
||||
|
||||
|
||||
.signal{position:fixed;right:16px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column-reverse;gap:5px;z-index:500;}
|
||||
.signal .bar{width:8px;height:12px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);transition:all .3s;}
|
||||
.signal .bar.on{background:var(--accent);box-shadow:0 0 10px var(--accent);border-color:transparent;}
|
||||
@media(max-width:720px){.signal{display:none;}}
|
||||
|
||||
.toast-stack{position:fixed;bottom:20px;left:20px;z-index:9995;display:flex;flex-direction:column;gap:8px;}
|
||||
.toast{
|
||||
background:#111;border:2px solid var(--tape);
|
||||
padding:12px 18px;font-family:var(--font-mono);font-size:11px;
|
||||
display:flex;align-items:center;gap:10px;transform:translateX(-150%);max-width:260px;
|
||||
}
|
||||
.toast .icon{font-size:16px;}
|
||||
.toast .title{color:var(--tape);font-family:var(--font-pixel);font-size:8px;display:block;margin-bottom:3px;text-transform:uppercase;}
|
||||
|
||||
|
||||
.scattered-nav{
|
||||
position:fixed;top:0;left:0;right:0;z-index:400;
|
||||
@@ -220,6 +214,7 @@
|
||||
.avatar-frame:hover{transform:rotate(0deg) scale(1.02);}
|
||||
.avatar-frame img{width:200px;display:block;filter:contrast(1.2) grayscale(.3);}
|
||||
.avatar-tag{font-family:var(--font-pixel);font-size:8px;color:var(--accent);margin-top:12px;text-transform:uppercase;}
|
||||
.page-links a:hover{color:var(--accent)!important;transform:scale(1.05);}
|
||||
.about-card{
|
||||
background:rgba(255,255,255,0.02);border:2px solid rgba(255,255,255,0.12);
|
||||
padding:30px 32px;transform:rotate(1.5deg);transition:transform .3s;flex:1;min-width:280px;
|
||||
@@ -318,9 +313,8 @@
|
||||
|
||||
footer{text-align:center;padding:40px 24px 60px;font-family:var(--font-mono);font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;}
|
||||
|
||||
.reveal{opacity:0;transform:translateY(24px);}
|
||||
|
||||
.progress-bar{position:fixed;top:0;left:0;height:3px;background:var(--accent);z-index:10001;width:0;transition:width .1s linear;box-shadow:0 0 8px var(--accent);}
|
||||
|
||||
|
||||
body.light{
|
||||
--bg:#f5f5f0;--text:#111;--muted:#888;
|
||||
@@ -341,32 +335,11 @@
|
||||
body.light .section-sub{color:#888;}
|
||||
body.light .marquee{background:var(--tape);}
|
||||
body.light .marquee span{color:#000;}
|
||||
body.light .toast{background:#eee;border-color:#333;}
|
||||
body.light .toast .title{color:#333;}
|
||||
body.light .toast{color:#333;}
|
||||
|
||||
.theme-toggle{
|
||||
position:fixed;top:20px;right:20px;z-index:600;
|
||||
background:none;border:2px solid rgba(255,255,255,0.15);
|
||||
width:40px;height:40px;display:flex;align-items:center;justify-content:center;
|
||||
font-size:16px;cursor:none;transition:all .3s;color:var(--text);
|
||||
}
|
||||
.theme-toggle:hover{border-color:var(--accent);background:rgba(255,61,154,0.1);}
|
||||
@media(max-width:720px){.theme-toggle{display:none;}}
|
||||
|
||||
.shortcut-modal{
|
||||
position:fixed;inset:0;z-index:10002;background:rgba(0,0,0,0.85);
|
||||
display:none;align-items:center;justify-content:center;backdrop-filter:blur(6px);
|
||||
}
|
||||
.shortcut-modal.open{display:flex;}
|
||||
.shortcut-card{
|
||||
background:#111;border:2px solid var(--accent);padding:32px;max-width:400px;width:90%;
|
||||
font-family:var(--font-mono);font-size:12px;
|
||||
}
|
||||
.shortcut-card h3{font-family:var(--font-pixel);font-size:11px;color:var(--accent);margin-bottom:20px;text-transform:uppercase;}
|
||||
.shortcut-row{display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid rgba(255,255,255,0.08);color:var(--muted);}
|
||||
.shortcut-row kbd{background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.15);padding:2px 8px;font-family:var(--font-mono);font-size:11px;color:var(--text);}
|
||||
.shortcut-card .close-hint{margin-top:16px;font-size:10px;color:var(--muted);text-align:center;}
|
||||
|
||||
|
||||
|
||||
|
||||
.bg-gradient{
|
||||
position:fixed;inset:0;pointer-events:none;z-index:-1;
|
||||
@@ -425,24 +398,9 @@
|
||||
.easter-text .cursor-blink{display:inline-block;width:3px;height:1em;background:var(--accent);margin-left:2px;animation:blink .6s step-end infinite;vertical-align:middle;}
|
||||
@keyframes blink{0%,100%{opacity:1;}50%{opacity:0;}}
|
||||
|
||||
.mobile-nav{
|
||||
display:none;position:fixed;bottom:0;left:0;right:0;z-index:500;
|
||||
background:rgba(0,0,0,0.92);border-top:2px solid rgba(255,255,255,0.12);
|
||||
backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
|
||||
padding:8px 0 env(safe-area-inset-bottom,8px);
|
||||
}
|
||||
.mobile-nav a{
|
||||
display:inline-flex;flex:1;justify-content:center;align-items:center;
|
||||
font-family:var(--font-pixel);font-size:7px;color:var(--muted);
|
||||
padding:10px 6px;text-transform:uppercase;letter-spacing:.04em;
|
||||
text-decoration:none;transition:all .2s;border:none;background:none;
|
||||
-webkit-tap-highlight-color:transparent;
|
||||
}
|
||||
.mobile-nav a:active,.mobile-nav a.active{color:var(--accent);}
|
||||
|
||||
|
||||
@media(max-width:720px){
|
||||
.mobile-nav{display:flex;gap:4px;}
|
||||
|
||||
section{padding:60px 5vw 50px;}
|
||||
|
||||
.hero-giant{
|
||||
@@ -498,9 +456,6 @@
|
||||
h2.section-title{font-size:clamp(28px,8vw,48px);transform:rotate(-0.5deg);}
|
||||
.eyebrow{font-size:8px;}
|
||||
|
||||
.toast-stack{bottom:70px;left:12px;}
|
||||
.toast{max-width:220px;padding:10px 14px;font-size:10px;}
|
||||
|
||||
.scattered-nav a:not(.sn-logo){display:none!important;}
|
||||
}
|
||||
|
||||
@@ -594,7 +549,7 @@
|
||||
<div class="about-grid reveal">
|
||||
<div>
|
||||
<div class="avatar-frame">
|
||||
<img src="https://avatars.githubusercontent.com/u/115095719?v=4" alt="Miles Wolf Allen">
|
||||
<img src="https://avatars.githubusercontent.com/u/115095719?v=4" alt="Miles Wolf Allen" loading="lazy" width="200" height="200">
|
||||
</div>
|
||||
<div class="avatar-tag">@mileswolfallen2</div>
|
||||
</div>
|
||||
@@ -607,6 +562,11 @@
|
||||
<span class="badge">Quickdraw</span>
|
||||
</div>
|
||||
<a href="about-me.html" style="display:inline-block;margin-top:20px;font-family:var(--font-pixel);font-size:10px;color:var(--accent);border:1px solid var(--accent);padding:10px 20px;text-transform:uppercase;letter-spacing:.05em;transition:all .2s;">More About Me →</a>
|
||||
<div class="page-links" style="margin-top:20px;display:flex;gap:16px;flex-wrap:wrap;border-top:2px solid rgba(255,255,255,0.1);padding-top:16px;">
|
||||
<a href="uses.html" style="font-family:var(--font-pixel);font-size:9px;color:var(--tape);text-transform:uppercase;letter-spacing:.08em;transition:color .2s;">Uses</a>
|
||||
<a href="now.html" style="font-family:var(--font-pixel);font-size:9px;color:var(--tape);text-transform:uppercase;letter-spacing:.08em;transition:color .2s;">Now</a>
|
||||
<a href="colophon.html" style="font-family:var(--font-pixel);font-size:9px;color:var(--tape);text-transform:uppercase;letter-spacing:.08em;transition:color .2s;">Colophon</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -802,30 +762,23 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>Built by Miles * 2026 * Powered by too much coffee and the Konami code (try it)</footer>
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
|
||||
<script src="projects/script.js"></script>
|
||||
<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>
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.proj-card,.term-btn,.chip,.hl-cell').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var colors=['#fff','#FF3D9A','#FFC93C'];
|
||||
var last=0;
|
||||
@@ -848,16 +801,6 @@ gsap.registerPlugin(ScrollTrigger);
|
||||
},{passive:true});
|
||||
})();
|
||||
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-count]').forEach(function(el){
|
||||
var target=parseInt(el.getAttribute('data-count'),10);var suffix=el.getAttribute('data-suffix')||'';
|
||||
ScrollTrigger.create({trigger:el,start:'top 88%',once:true,onEnter:function(){
|
||||
@@ -907,70 +850,6 @@ function setActive(id){
|
||||
},{passive:true});
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='1')document.getElementById('about').scrollIntoView({behavior:'smooth'});
|
||||
if(e.key==='2')document.getElementById('skills').scrollIntoView({behavior:'smooth'});
|
||||
if(e.key==='3')document.getElementById('projects').scrollIntoView({behavior:'smooth'});
|
||||
if(e.key==='4')document.getElementById('highlights').scrollIntoView({behavior:'smooth'});
|
||||
if(e.key==='5')document.getElementById('blog').scrollIntoView({behavior:'smooth'});
|
||||
if(e.key==='6')document.getElementById('contact').scrollIntoView({behavior:'smooth'});
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var grad=document.getElementById('bgGradient');
|
||||
window.addEventListener('scroll',function(){
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Now | Miles Wolf Allen</title>
|
||||
<meta name="description" content="What I'm currently focused on — building Gelectron, maintaining the FEDL, and more.">
|
||||
<link rel="canonical" href="https://milesallen.site/now.html">
|
||||
<meta property="og:title" content="Now | Miles Wolf Allen">
|
||||
<meta property="og:description" content="What I'm currently focused on — building Gelectron, maintaining the FEDL, and more.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:url" content="https://milesallen.site/now.html">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="stylesheet" href="projects/style.css">
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
.article-eyebrow{font-family:var(--font-pixel);font-size:10px;color:var(--tape);margin-bottom:12px;text-transform:uppercase;letter-spacing:.1em;}
|
||||
.article-date{font-family:var(--font-mono);font-size:12px;color:var(--muted);margin-bottom:8px;}
|
||||
.article-header h1{font-family:var(--font-pixel);font-size:clamp(24px,5vw,44px);line-height:1.2;margin-bottom:16px;transform:rotate(-1deg);transform-origin:left center;text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--tape);animation:glitch 5s ease-in-out infinite;}
|
||||
@keyframes glitch{0%,90%,100%{text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--tape);}92%{text-shadow:3px 3px 0 var(--red),-2px -2px 0 var(--accent);transform:rotate(-1deg) translateX(2px);}94%{text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--red);transform:rotate(-1deg) translateX(-2px);}}
|
||||
.article-tagline{font-size:16px;color:var(--muted);max-width:600px;line-height:1.7;font-family:var(--font-mono);margin-bottom:24px;}
|
||||
.article-body{max-width:720px;}
|
||||
.article-body h2{font-family:var(--font-pixel);font-size:16px;color:var(--accent);margin:40px 0 16px;text-transform:uppercase;}
|
||||
.article-body h3{font-family:var(--font-mono);font-weight:700;font-size:16px;margin:32px 0 12px;color:var(--text);}
|
||||
.article-body p{font-size:14px;color:#ccc;line-height:1.9;font-family:var(--font-mono);margin-bottom:16px;}
|
||||
.article-body code{background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);padding:2px 6px;font-size:12px;font-family:var(--font-mono);}
|
||||
.article-body blockquote{border-left:3px solid var(--accent);padding:12px 20px;margin:24px 0;background:rgba(255,255,255,0.02);font-style:italic;color:var(--muted);font-family:var(--font-mono);font-size:13px;}
|
||||
.article-body ul{margin:12px 0 16px 20px;font-family:var(--font-mono);font-size:13px;color:#ccc;line-height:1.8;}
|
||||
.article-body ul li{margin-bottom:6px;}
|
||||
.article-body ul li::marker{color:var(--accent);}
|
||||
.back-link{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:12px;color:var(--muted);margin-top:40px;text-decoration:none;transition:color .2s;}
|
||||
.back-link:hover{color:var(--accent);}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="cursor-dot" id="cursorDot"></div>
|
||||
<div class="cursor-ring" id="cursorRing"></div>
|
||||
<div class="progress-bar" id="progressBar"></div>
|
||||
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme"></button>
|
||||
<div class="shortcut-modal" id="shortcutModal">
|
||||
<div class="shortcut-card">
|
||||
<h3>Keyboard Shortcuts</h3>
|
||||
<div class="shortcut-row"><span>Go Home</span><kbd>H</kbd></div>
|
||||
<div class="shortcut-row"><span>Go to GitHub</span><kbd>G</kbd></div>
|
||||
<div class="shortcut-row"><span>Toggle theme</span><kbd>T</kbd></div>
|
||||
<div class="shortcut-row"><span>Show shortcuts</span><kbd>?</kbd></div>
|
||||
<div class="close-hint">Press Esc or ? to close</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flash" id="flash"></div>
|
||||
<div class="toast-stack" id="toastStack"></div>
|
||||
<nav class="mobile-nav">
|
||||
<a href="index.html">Home</a>
|
||||
<a href="projects/fedl.html">FEDL</a>
|
||||
<a href="projects/omniemu.html">OmniEmu</a>
|
||||
<a href="projects/command-move.html">CommandMove</a>
|
||||
<a href="https://github.com/mileswolfallen2" target="_blank">GitHub</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<nav>
|
||||
<a href="index.html" class="nav-logo"><span class="logo-dot"></span> milesallen</a>
|
||||
<div class="nav-links">
|
||||
<a href="index.html#about">About</a>
|
||||
<a href="index.html#skills">Skills</a>
|
||||
<a href="index.html#projects">Projects</a>
|
||||
<a href="index.html#contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="article-header">
|
||||
<div class="breadcrumb">
|
||||
<a href="index.html">Home</a>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
<span>Now</span>
|
||||
</div>
|
||||
<div class="article-eyebrow">// CURRENT FOCUS</div>
|
||||
<div class="article-date">2026</div>
|
||||
<h1>What I'm Doing Now</h1>
|
||||
<p class="article-tagline">Inspired by the nownownow.com movement — a snapshot of what I'm focused on right now.</p>
|
||||
</section>
|
||||
|
||||
<section class="reveal">
|
||||
<div class="article-body">
|
||||
<h2>Building Gelectron</h2>
|
||||
<p>My main project right now is <strong>Gelectron</strong> — a Firefox-engine alternative to Electron, powered by Servo. It's early, experimental, and a lot of fun. I'm building a drop-in replacement for Electron that uses less memory and produces smaller binaries. Drop-in replacement — just run <code>gelectron .</code> instead of <code>electron .</code>.</p>
|
||||
<p>Right now I'm focused on filling out the Electron API compatibility layer (BrowserWindow, IPC, Menu, Tray) and getting the Servo rendering pipeline working properly. It's a Rust + Node.js project and it's teaching me a ton about browser engines, FFI, and systems programming.</p>
|
||||
|
||||
<h2>Maintaining the FEDL</h2>
|
||||
<p>The Geometry Dash demon list is still going strong. Nearly 4,000 verified runs, 340+ ranked levels, and a community that keeps me busy. I'm working on better moderation tools and a cleaner submission pipeline.</p>
|
||||
|
||||
<h2>This Site</h2>
|
||||
<p>I've been putting a lot of time into milesallen.site — the portfolio you're on right now. I keep adding features, fixing things, and rewriting parts of it. It's my digital home and I want it to be good.</p>
|
||||
|
||||
<p><em>Last updated: July 2026</em></p>
|
||||
|
||||
<div style="margin-top:40px;padding-top:20px;border-top:2px solid rgba(255,255,255,0.12);font-family:var(--font-mono);font-size:12px;color:var(--muted);display:flex;gap:16px;flex-wrap:wrap;">
|
||||
<a href="uses.html" style="color:var(--accent);text-decoration:none;">→ What I use</a>
|
||||
<a href="colophon.html" style="color:var(--accent);text-decoration:none;">→ How this site is built</a>
|
||||
</div>
|
||||
|
||||
<a href="index.html" class="back-link">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><polyline points="15 18 9 12 15 6"/></svg>
|
||||
Back to Home
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script src="projects/script.js"></script>
|
||||
<script>
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
const heroTl = gsap.timeline({ defaults: { ease: 'power3.out' } });
|
||||
heroTl
|
||||
.from('.breadcrumb', { x: -30, opacity: 0, duration: 0.6 })
|
||||
.from('.article-header h1', { y: 50, opacity: 0, duration: 0.8 }, '-=0.3')
|
||||
.from('.article-tagline', { y: 30, opacity: 0, duration: 0.7 }, '-=0.4');
|
||||
gsap.from('nav', { y: -20, opacity: 0, duration: 0.6, ease: 'power2.out' });
|
||||
document.querySelectorAll('.article-body h2').forEach(title => {
|
||||
gsap.from(title, { scrollTrigger: { trigger: title, start: 'top 85%' }, y: 30, opacity: 0, duration: 0.7, ease: 'power3.out' });
|
||||
});
|
||||
document.querySelectorAll('.article-body p, .article-body ul, .article-body blockquote').forEach(el => {
|
||||
gsap.from(el, { scrollTrigger: { trigger: el, start: 'top 88%' }, y: 20, opacity: 0, duration: 0.6, ease: 'power3.out' });
|
||||
});
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='h'||e.key==='H')window.location.href='index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 138 KiB |
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -198,6 +198,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -274,92 +281,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -146,6 +146,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -238,92 +245,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+9
-88
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -194,6 +194,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -317,92 +324,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+9
-88
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -210,6 +210,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -302,92 +309,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+9
-88
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -178,6 +178,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -270,92 +277,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -143,6 +143,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -235,92 +242,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -164,6 +164,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -256,92 +263,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+9
-88
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -163,6 +163,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -255,92 +262,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+9
-88
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -209,6 +209,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -301,92 +308,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+9
-88
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -192,6 +192,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -284,92 +291,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+9
-88
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -251,6 +251,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -343,92 +350,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.png">
|
||||
<link rel="icon" type="image/svg+xml" href="../favicon.svg">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -157,6 +157,13 @@
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="../uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="../colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
@@ -249,92 +256,6 @@
|
||||
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
var toastQueue=document.getElementById('toastStack');var shownToasts={};
|
||||
function showToast(id,title,body,icon){
|
||||
if(shownToasts[id])return;shownToasts[id]=true;
|
||||
var t=document.createElement('div');t.className='toast';
|
||||
t.innerHTML='<span class="icon">'+(icon||'!')+'</span><span><span class="title">'+title+'</span>'+body+'</span>';
|
||||
toastQueue.appendChild(t);
|
||||
gsap.to(t,{x:0,duration:.6,ease:'power3.out'});
|
||||
setTimeout(function(){gsap.to(t,{x:'-150%',opacity:0,duration:.4,ease:'power2.in',onComplete:function(){t.remove();}});},3000);
|
||||
}
|
||||
(function(){
|
||||
var seq=['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
var pos=0;
|
||||
window.addEventListener('keydown',function(e){
|
||||
var key=e.key.length===1?e.key.toLowerCase():e.key;
|
||||
if(key===seq[pos]){pos++;if(pos===seq.length){pos=0;triggerKonami();}}
|
||||
else{pos=(key===seq[0])?1:0;}
|
||||
});
|
||||
function triggerKonami(){
|
||||
showToast('konami','SECRET FOUND','Konami Code Activated','*');
|
||||
var flash=document.getElementById('flash');
|
||||
gsap.fromTo(flash,{opacity:.5},{opacity:0,duration:.5});
|
||||
gsap.to('body',{x:'random(-5,5)',y:'random(-5,5)',duration:.05,repeat:10,ease:'sine.inOut',onComplete:function(){gsap.set('body',{x:0,y:0});}});
|
||||
document.body.style.cursor='auto';
|
||||
var style=document.createElement('style');style.id='konami-cursor';
|
||||
style.textContent='*{cursor:auto !important;}';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var dot=document.getElementById('cursorDot');
|
||||
var ring=document.getElementById('cursorRing');
|
||||
if(!dot||!ring)return;
|
||||
var mx=0,my=0,rx=0,ry=0;
|
||||
document.addEventListener('mousemove',function(e){mx=e.clientX;my=e.clientY;dot.style.left=mx+'px';dot.style.top=my+'px';});
|
||||
(function loop(){
|
||||
rx+=(mx-rx)*0.15;ry+=(my-ry)*0.15;
|
||||
ring.style.left=rx+'px';ring.style.top=ry+'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a,button,.meta-chip,.tech-badge,.feature-card').forEach(function(el){
|
||||
el.addEventListener('mouseenter',function(){dot.classList.add('hover');ring.classList.add('hover');});
|
||||
el.addEventListener('mouseleave',function(){dot.classList.remove('hover');ring.classList.remove('hover');});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
(function(){
|
||||
var bar=document.getElementById('progressBar');
|
||||
window.addEventListener('scroll',function(){
|
||||
var pct=window.scrollY/(document.body.scrollHeight-window.innerHeight)*100;
|
||||
bar.style.width=pct+'%';
|
||||
},{passive:true});
|
||||
})();
|
||||
(function(){
|
||||
var btn=document.getElementById('themeToggle');
|
||||
var saved=localStorage.getItem('theme');
|
||||
if(saved==='light')document.body.classList.add('light');
|
||||
function updateIcon(){btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';}
|
||||
updateIcon();
|
||||
btn.addEventListener('click',function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
(function(){
|
||||
var modal=document.getElementById('shortcutModal');
|
||||
function toggleModal(){modal.classList.toggle('open');}
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='?'){e.preventDefault();toggleModal();}
|
||||
if(e.key==='Escape')modal.classList.remove('open');
|
||||
if(e.key==='t'||e.key==='T'){
|
||||
if(document.activeElement&&document.activeElement.tagName==='INPUT')return;
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme',document.body.classList.contains('light')?'light':'dark');
|
||||
var btn=document.getElementById('themeToggle');
|
||||
btn.textContent=document.body.classList.contains('light')?'\u263E':'\u2600';
|
||||
}
|
||||
if(e.key==='h'||e.key==='H')window.location.href='../index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
modal.addEventListener('click',function(e){if(e.target===modal)modal.classList.remove('open');});
|
||||
})();
|
||||
</script>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
(function(){
|
||||
/* TOAST SYSTEM */
|
||||
const toastQueue = document.getElementById('toastStack');
|
||||
const shownToasts = {};
|
||||
window.showToast = function(id, title, body, icon){
|
||||
if (shownToasts[id]) return;
|
||||
shownToasts[id] = true;
|
||||
const t = document.createElement('div');
|
||||
t.className = 'toast';
|
||||
t.innerHTML = '<span class="icon">' + (icon || '!') + '</span><span><span class="title">' + title + '</span>' + body + '</span>';
|
||||
toastQueue.appendChild(t);
|
||||
if (window.gsap) {
|
||||
window.gsap.to(t, { x: 0, duration: 0.6, ease: 'power3.out' });
|
||||
setTimeout(function(){
|
||||
window.gsap.to(t, { x: '-150%', opacity: 0, duration: 0.4, ease: 'power2.in', onComplete: function(){ t.remove(); } });
|
||||
}, 3000);
|
||||
}
|
||||
};
|
||||
|
||||
/* KONAMI CODE */
|
||||
(function(){
|
||||
const seq = ['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
|
||||
let pos = 0;
|
||||
window.addEventListener('keydown', function(e){
|
||||
const key = e.key.length === 1 ? e.key.toLowerCase() : e.key;
|
||||
if (key === seq[pos]) {
|
||||
pos++;
|
||||
if (pos === seq.length) {
|
||||
pos = 0;
|
||||
triggerKonami();
|
||||
}
|
||||
} else {
|
||||
pos = (key === seq[0]) ? 1 : 0;
|
||||
}
|
||||
});
|
||||
function triggerKonami(){
|
||||
try { window.showToast('konami', 'SECRET FOUND', 'Konami Code Activated', '*'); } catch(e) {}
|
||||
const flash = document.getElementById('flash');
|
||||
if (flash && window.gsap) {
|
||||
window.gsap.fromTo(flash, { opacity: 0.5 }, { opacity: 0, duration: 0.5 });
|
||||
}
|
||||
if (window.gsap) {
|
||||
window.gsap.to('body', { x: 'random(-5,5)', y: 'random(-5,5)', duration: 0.05, repeat: 10, ease: 'sine.inOut', onComplete: function(){ window.gsap.set('body', { x: 0, y: 0 }); } });
|
||||
}
|
||||
document.body.style.cursor = 'auto';
|
||||
let s = document.getElementById('konami-cursor');
|
||||
if (!s) {
|
||||
s = document.createElement('style');
|
||||
s.id = 'konami-cursor';
|
||||
document.head.appendChild(s);
|
||||
}
|
||||
s.textContent = '*{cursor:auto !important;}';
|
||||
}
|
||||
})();
|
||||
|
||||
/* CURSOR */
|
||||
(function(){
|
||||
const dot = document.getElementById('cursorDot');
|
||||
const ring = document.getElementById('cursorRing');
|
||||
if (!dot || !ring) return;
|
||||
let mx = 0, my = 0, rx = 0, ry = 0;
|
||||
document.addEventListener('mousemove', function(e){
|
||||
mx = e.clientX;
|
||||
my = e.clientY;
|
||||
dot.style.left = mx + 'px';
|
||||
dot.style.top = my + 'px';
|
||||
});
|
||||
(function loop(){
|
||||
rx += (mx - rx) * 0.15;
|
||||
ry += (my - ry) * 0.15;
|
||||
ring.style.left = rx + 'px';
|
||||
ring.style.top = ry + 'px';
|
||||
requestAnimationFrame(loop);
|
||||
})();
|
||||
document.querySelectorAll('a, button, .meta-chip, .tech-badge, .feature-card, .proj-card, .blog-card, .hl-cell, .term-btn, .chip').forEach(function(el){
|
||||
el.addEventListener('mouseenter', function(){ dot.classList.add('hover'); ring.classList.add('hover'); });
|
||||
el.addEventListener('mouseleave', function(){ dot.classList.remove('hover'); ring.classList.remove('hover'); });
|
||||
});
|
||||
})();
|
||||
|
||||
/* PROGRESS BAR */
|
||||
(function(){
|
||||
const bar = document.getElementById('progressBar');
|
||||
if (!bar) return;
|
||||
window.addEventListener('scroll', function(){
|
||||
const pct = window.scrollY / (document.body.scrollHeight - window.innerHeight) * 100;
|
||||
bar.style.width = pct + '%';
|
||||
}, { passive: true });
|
||||
})();
|
||||
|
||||
/* THEME TOGGLE */
|
||||
(function(){
|
||||
const btn = document.getElementById('themeToggle');
|
||||
if (!btn) return;
|
||||
const saved = localStorage.getItem('theme');
|
||||
if (saved === 'light') document.body.classList.add('light');
|
||||
function updateIcon(){
|
||||
btn.textContent = document.body.classList.contains('light') ? '\u263E' : '\u2600';
|
||||
}
|
||||
updateIcon();
|
||||
btn.addEventListener('click', function(){
|
||||
document.body.classList.toggle('light');
|
||||
localStorage.setItem('theme', document.body.classList.contains('light') ? 'light' : 'dark');
|
||||
updateIcon();
|
||||
});
|
||||
})();
|
||||
|
||||
/* KEYBOARD SHORTCUTS (shared) */
|
||||
(function(){
|
||||
const modal = document.getElementById('shortcutModal');
|
||||
if (!modal) return;
|
||||
function toggleModal(){ modal.classList.toggle('open'); }
|
||||
modal.addEventListener('click', function(e){ if (e.target === modal) modal.classList.remove('open'); });
|
||||
window.addEventListener('keydown', function(e){
|
||||
if (e.key === '?') { e.preventDefault(); toggleModal(); }
|
||||
if (e.key === 'Escape') modal.classList.remove('open');
|
||||
});
|
||||
})();
|
||||
})();
|
||||
@@ -332,6 +332,10 @@ body.light .breadcrumb{color:#888;}
|
||||
.toast{max-width:220px;padding:10px 14px;font-size:10px;}
|
||||
}
|
||||
|
||||
.footer-links{display:flex;justify-content:center;gap:16px;flex-wrap:wrap;}
|
||||
.footer-links a{font-family:var(--font-pixel);font-size:8px;color:var(--tape);letter-spacing:.08em;text-transform:uppercase;transition:color .2s;}
|
||||
.footer-links a:hover{color:var(--accent);}
|
||||
|
||||
@media(prefers-reduced-motion:reduce){
|
||||
*{animation:none!important;transition:none!important;}
|
||||
}
|
||||
|
||||
+79
-1
@@ -2,62 +2,140 @@
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://milesallen.site/</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/about-me.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/omniemu.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/fedl.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/gelectron.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/command-move.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/noto.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/nova.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/music-app.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/rhythm-game.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/geode-mod.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/decompilations.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/issue-tracker.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/moon-gaming.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/projects/command-move.html</loc>
|
||||
<loc>https://milesallen.site/uses.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/now.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/colophon.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/blog/omniemu-devlog.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/blog/command-move-devlog.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/blog/fedl-devlog.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/blog/nova-devlog.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/blog/gelectron-devlog.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.7</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://milesallen.site/404.html</loc>
|
||||
<lastmod>2026-07-28</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.1</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
@@ -0,0 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Uses | Miles Wolf Allen</title>
|
||||
<meta name="description" content="The hardware and software I use daily — M4 MacBook Air, VS Code, opencode, Firefox, Brave, and more.">
|
||||
<link rel="canonical" href="https://milesallen.site/uses.html">
|
||||
<meta property="og:title" content="Uses | Miles Wolf Allen">
|
||||
<meta property="og:description" content="The hardware and software I use daily — M4 MacBook Air, VS Code, opencode, Firefox, Brave, and more.">
|
||||
<meta property="og:image" content="https://milesallen.site/og.png">
|
||||
<meta property="og:url" content="https://milesallen.site/uses.html">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="favicon.svg">
|
||||
<link rel="stylesheet" href="projects/style.css">
|
||||
<style>
|
||||
.article-header{padding:100px 0 40px;}
|
||||
.article-eyebrow{font-family:var(--font-pixel);font-size:10px;color:var(--tape);margin-bottom:12px;text-transform:uppercase;letter-spacing:.1em;}
|
||||
.article-date{font-family:var(--font-mono);font-size:12px;color:var(--muted);margin-bottom:8px;}
|
||||
.article-header h1{font-family:var(--font-pixel);font-size:clamp(24px,5vw,44px);line-height:1.2;margin-bottom:16px;transform:rotate(-1deg);transform-origin:left center;text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--tape);animation:glitch 5s ease-in-out infinite;}
|
||||
@keyframes glitch{0%,90%,100%{text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--tape);}92%{text-shadow:3px 3px 0 var(--red),-2px -2px 0 var(--accent);transform:rotate(-1deg) translateX(2px);}94%{text-shadow:3px 3px 0 var(--accent),-2px -2px 0 var(--red);transform:rotate(-1deg) translateX(-2px);}}
|
||||
.article-tagline{font-size:16px;color:var(--muted);max-width:600px;line-height:1.7;font-family:var(--font-mono);margin-bottom:24px;}
|
||||
.article-body{max-width:720px;}
|
||||
.article-body h2{font-family:var(--font-pixel);font-size:16px;color:var(--accent);margin:40px 0 16px;text-transform:uppercase;}
|
||||
.article-body h3{font-family:var(--font-mono);font-weight:700;font-size:16px;margin:32px 0 12px;color:var(--text);}
|
||||
.article-body p{font-size:14px;color:#ccc;line-height:1.9;font-family:var(--font-mono);margin-bottom:16px;}
|
||||
.article-body code{background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.12);padding:2px 6px;font-size:12px;font-family:var(--font-mono);}
|
||||
.article-body blockquote{border-left:3px solid var(--accent);padding:12px 20px;margin:24px 0;background:rgba(255,255,255,0.02);font-style:italic;color:var(--muted);font-family:var(--font-mono);font-size:13px;}
|
||||
.article-body ul{margin:12px 0 16px 20px;font-family:var(--font-mono);font-size:13px;color:#ccc;line-height:1.8;}
|
||||
.article-body ul li{margin-bottom:6px;}
|
||||
.article-body ul li::marker{color:var(--accent);}
|
||||
.article-body ul li strong{color:var(--text);}
|
||||
.back-link{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:12px;color:var(--muted);margin-top:40px;text-decoration:none;transition:color .2s;}
|
||||
.back-link:hover{color:var(--accent);}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="cursor-dot" id="cursorDot"></div>
|
||||
<div class="cursor-ring" id="cursorRing"></div>
|
||||
<div class="progress-bar" id="progressBar"></div>
|
||||
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme"></button>
|
||||
<div class="shortcut-modal" id="shortcutModal">
|
||||
<div class="shortcut-card">
|
||||
<h3>Keyboard Shortcuts</h3>
|
||||
<div class="shortcut-row"><span>Go Home</span><kbd>H</kbd></div>
|
||||
<div class="shortcut-row"><span>Go to GitHub</span><kbd>G</kbd></div>
|
||||
<div class="shortcut-row"><span>Toggle theme</span><kbd>T</kbd></div>
|
||||
<div class="shortcut-row"><span>Show shortcuts</span><kbd>?</kbd></div>
|
||||
<div class="close-hint">Press Esc or ? to close</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flash" id="flash"></div>
|
||||
<div class="toast-stack" id="toastStack"></div>
|
||||
<nav class="mobile-nav">
|
||||
<a href="index.html">Home</a>
|
||||
<a href="projects/fedl.html">FEDL</a>
|
||||
<a href="projects/omniemu.html">OmniEmu</a>
|
||||
<a href="projects/command-move.html">CommandMove</a>
|
||||
<a href="https://github.com/mileswolfallen2" target="_blank">GitHub</a>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<nav>
|
||||
<a href="index.html" class="nav-logo"><span class="logo-dot"></span> milesallen</a>
|
||||
<div class="nav-links">
|
||||
<a href="index.html#about">About</a>
|
||||
<a href="index.html#skills">Skills</a>
|
||||
<a href="index.html#projects">Projects</a>
|
||||
<a href="index.html#contact">Contact</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="article-header">
|
||||
<div class="breadcrumb">
|
||||
<a href="index.html">Home</a>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
|
||||
<span>Uses</span>
|
||||
</div>
|
||||
<div class="article-eyebrow">// THE SETUP</div>
|
||||
<div class="article-date">2026</div>
|
||||
<h1>What I Use</h1>
|
||||
<p class="article-tagline">The hardware, software, and tools I reach for every day. No sponsors, no affiliate links — just what actually works for me.</p>
|
||||
</section>
|
||||
|
||||
<section class="reveal">
|
||||
<div class="article-body">
|
||||
<h2>Hardware</h2>
|
||||
<h3>MacBook Air M4 (2024)</h3>
|
||||
<p>16GB RAM, 256GB storage. This thing is fast. The M4 chip handles everything I throw at it — VS Code with 10+ tabs, a dozen terminal windows, Docker containers, multiple browsers with 30+ tabs each, GSAP animations running in dev, and it doesn't break a sweat. Fanless design means it's completely silent. Best laptop I've ever owned.</p>
|
||||
|
||||
<h2>Software</h2>
|
||||
<h3>VS Code</h3>
|
||||
<p>My main editor. Cursor's AI features are nice, but VS Code with the right extensions is unbeatable. I run the GitHub Copilot extension, ESLint, Prettier, and a handful of theme and icon packs. My config is mostly default — I don't spend time tweaking my editor, I spend time writing code.</p>
|
||||
|
||||
<h3>opencode</h3>
|
||||
<p>The CLI tool I use for AI-assisted development. It runs in the terminal, integrates with my workflow, and doesn't try to replace my editor. I use it for refactoring, code review, and bouncing off ideas when I'm stuck.</p>
|
||||
|
||||
<h3>Brave</h3>
|
||||
<p>My main browser. Fast, Chromium-based, and the built-in ad blocking means I don't need extensions for the basics. Shields Up mode is the default everywhere. I use it for everything — dev work, browsing, media, you name it.</p>
|
||||
|
||||
<h3>Firefox</h3>
|
||||
<p>I keep Firefox around for testing and for a few extensions that work better in its ecosystem. The container tabs are great for separating work/personal stuff when I need it. Still respect what Mozilla does, just not my daily driver anymore.</p>
|
||||
|
||||
<h2>Terminal</h2>
|
||||
<p>I use the built-in macOS terminal with zsh. Nothing fancy — just a clean prompt, a few aliases, and git integration. I spent years customizing my terminal setup and eventually realized I was just procrastinating. Now it's minimal and I get work done.</p>
|
||||
|
||||
<h2>Other Tools</h2>
|
||||
<ul>
|
||||
<li><strong>GitHub:</strong> Where everything lives. 147+ repos and counting.</li>
|
||||
<li><strong>Cloudflare:</strong> DNS, domain management, and some worker scripts.</li>
|
||||
<li><strong>Blender:</strong> For 3D modeling when I need it.</li>
|
||||
<li><strong>Unity / Unreal:</strong> Game engines I dip into for prototypes.</li>
|
||||
</ul>
|
||||
|
||||
<blockquote>The best tool is the one you don't notice using.</blockquote>
|
||||
|
||||
<div style="margin-top:40px;padding-top:20px;border-top:2px solid rgba(255,255,255,0.12);font-family:var(--font-mono);font-size:12px;color:var(--muted);display:flex;gap:16px;flex-wrap:wrap;">
|
||||
<a href="now.html" style="color:var(--accent);text-decoration:none;">→ What I'm doing now</a>
|
||||
<a href="colophon.html" style="color:var(--accent);text-decoration:none;">→ How this site is built</a>
|
||||
</div>
|
||||
|
||||
<a href="index.html" class="back-link">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><polyline points="15 18 9 12 15 6"/></svg>
|
||||
Back to Home
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="footer-links" style="margin-bottom: 12px;">
|
||||
<a href="uses.html" style="color:var(--muted);text-decoration:none;">Uses</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="now.html" style="color:var(--muted);text-decoration:none;">Now</a>
|
||||
<span style="color:var(--muted);margin:0 8px;">·</span>
|
||||
<a href="colophon.html" style="color:var(--muted);text-decoration:none;">Colophon</a>
|
||||
</div>
|
||||
Built by Miles · 2026 · Powered by too much coffee and the Konami code
|
||||
</footer>
|
||||
</div>
|
||||
<script src="projects/script.js"></script>
|
||||
<script>
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/gsap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/[email protected]/ScrollTrigger.min.js"></script>
|
||||
<script>
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
const heroTl = gsap.timeline({ defaults: { ease: 'power3.out' } });
|
||||
heroTl
|
||||
.from('.breadcrumb', { x: -30, opacity: 0, duration: 0.6 })
|
||||
.from('.article-header h1', { y: 50, opacity: 0, duration: 0.8 }, '-=0.3')
|
||||
.from('.article-tagline', { y: 30, opacity: 0, duration: 0.7 }, '-=0.4');
|
||||
gsap.from('nav', { y: -20, opacity: 0, duration: 0.6, ease: 'power2.out' });
|
||||
document.querySelectorAll('.article-body h2').forEach(title => {
|
||||
gsap.from(title, { scrollTrigger: { trigger: title, start: 'top 85%' }, y: 30, opacity: 0, duration: 0.7, ease: 'power3.out' });
|
||||
});
|
||||
document.querySelectorAll('.article-body p, .article-body ul, .article-body blockquote').forEach(el => {
|
||||
gsap.from(el, { scrollTrigger: { trigger: el, start: 'top 88%' }, y: 20, opacity: 0, duration: 0.6, ease: 'power3.out' });
|
||||
});
|
||||
gsap.from('footer', { scrollTrigger: { trigger: 'footer', start: 'top 95%' }, opacity: 0, duration: 0.8 });
|
||||
window.addEventListener('load', () => ScrollTrigger.refresh());
|
||||
</script>
|
||||
<script>
|
||||
window.addEventListener('keydown',function(e){
|
||||
if(e.key==='h'||e.key==='H')window.location.href='index.html';
|
||||
if(e.key==='g'||e.key==='G')window.location.href='https://github.com/mileswolfallen2';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user