Skip to content

Commit ec2f07f

Browse files
highdaclaude
andcommitted
Add custom animated landing page
Replace the themed README homepage with a self-contained index.html: retro CGA/CRT styling, responsive card grid, drifting nebula and a parallax canvas starfield. No front matter, so Jekyll serves it verbatim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent c4ec4e7 commit ec2f07f

1 file changed

Lines changed: 388 additions & 0 deletions

File tree

‎index.html‎

Lines changed: 388 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,388 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>highda archives — free useless stuff</title>
7+
<meta name="description" content="Free useless stuff! Just as nature intended. Image glitch tools, CSS helpers, and guitar learning toys.">
8+
<meta name="color-scheme" content="dark">
9+
10+
<!-- Open Graph -->
11+
<meta property="og:type" content="website">
12+
<meta property="og:title" content="highda archives">
13+
<meta property="og:description" content="Free useless stuff! Just as nature intended.">
14+
15+
<link rel="preconnect" href="https://fonts.googleapis.com">
16+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17+
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700;800&family=VT323&display=swap" rel="stylesheet">
18+
19+
<style>
20+
:root{
21+
--bg:#08080f;
22+
--bg-2:#0e0e1c;
23+
--ink:#d7d7e6;
24+
--muted:#7a7a96;
25+
--cyan:#55ffff;
26+
--magenta:#ff55ff;
27+
--line:rgba(85,255,255,.16);
28+
--card:rgba(255,255,255,.025);
29+
--radius:14px;
30+
--mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
31+
}
32+
33+
*{box-sizing:border-box}
34+
html{scroll-behavior:smooth}
35+
body{
36+
margin:0;
37+
background:var(--bg);
38+
color:var(--ink);
39+
font-family:var(--mono);
40+
line-height:1.6;
41+
-webkit-font-smoothing:antialiased;
42+
overflow-x:hidden;
43+
}
44+
45+
/* ---- ambient background ---- */
46+
.bg-fx{position:fixed;inset:0;z-index:-3;pointer-events:none;
47+
background:linear-gradient(180deg,var(--bg) 0%, var(--bg-2) 100%)}
48+
/* deep-space base tint */
49+
.bg-fx::before{
50+
content:"";position:absolute;inset:0;
51+
background:
52+
radial-gradient(40% 35% at 80% 90%, rgba(120,60,200,.10), transparent 70%),
53+
radial-gradient(50% 45% at 10% 95%, rgba(0,120,180,.08), transparent 70%);
54+
}
55+
/* drifting nebula clouds */
56+
.bg-fx::after{
57+
content:"";position:absolute;inset:-20%;opacity:.9;
58+
background:
59+
radial-gradient(38% 30% at 18% 12%, rgba(255,85,255,.22), transparent 62%),
60+
radial-gradient(42% 34% at 92% 18%, rgba(85,255,255,.20), transparent 62%),
61+
radial-gradient(30% 26% at 60% 60%, rgba(150,90,255,.14), transparent 60%);
62+
filter:blur(8px);
63+
animation:nebula 38s ease-in-out infinite alternate;
64+
}
65+
@keyframes nebula{
66+
0% {transform:translate3d(0,0,0) scale(1)}
67+
50% {transform:translate3d(-3%,2%,0) scale(1.08)}
68+
100%{transform:translate3d(2%,-2%,0) scale(1.04)}
69+
}
70+
/* canvas starfield */
71+
#space{position:fixed;inset:0;z-index:-2;pointer-events:none;display:block}
72+
/* CRT scanlines */
73+
.scanlines{position:fixed;inset:0;z-index:50;pointer-events:none;
74+
background:repeating-linear-gradient(180deg,rgba(0,0,0,0) 0 2px,rgba(0,0,0,.22) 2px 3px);
75+
mix-blend-mode:multiply;opacity:.5}
76+
77+
.wrap{max-width:1280px;margin:0 auto;padding:0 22px}
78+
79+
/* ---- header ---- */
80+
header{padding:clamp(56px,12vw,120px) 0 28px}
81+
.badge{
82+
display:inline-flex;align-items:center;gap:8px;
83+
font-size:12px;letter-spacing:.18em;text-transform:uppercase;
84+
color:var(--cyan);border:1px solid var(--line);
85+
padding:6px 12px;border-radius:999px;background:rgba(85,255,255,.05);
86+
}
87+
.badge .dot{width:7px;height:7px;border-radius:50%;background:var(--cyan);
88+
box-shadow:0 0 10px var(--cyan);animation:blink 2.4s steps(1) infinite}
89+
@keyframes blink{50%{opacity:.25}}
90+
91+
h1{
92+
font-family:'VT323',var(--mono);
93+
font-weight:400;
94+
font-size:clamp(54px,13vw,128px);
95+
line-height:.92;
96+
margin:20px 0 6px;
97+
letter-spacing:1px;
98+
color:#fff;
99+
position:relative;
100+
width:max-content;max-width:100%;
101+
}
102+
/* chromatic glitch */
103+
h1[data-text]::before,h1[data-text]::after{
104+
content:attr(data-text);position:absolute;inset:0;
105+
clip-path:inset(0);
106+
}
107+
h1[data-text]::before{color:var(--magenta);transform:translate(-2px,0);mix-blend-mode:screen;
108+
animation:gl1 5.5s infinite steps(1)}
109+
h1[data-text]::after{color:var(--cyan);transform:translate(2px,0);mix-blend-mode:screen;
110+
animation:gl2 5.5s infinite steps(1)}
111+
@keyframes gl1{0%,93%{clip-path:inset(100% 0 0 0)}94%{clip-path:inset(10% 0 78% 0)}96%{clip-path:inset(55% 0 28% 0)}98%{clip-path:inset(30% 0 50% 0)}}
112+
@keyframes gl2{0%,93%{clip-path:inset(100% 0 0 0)}95%{clip-path:inset(70% 0 12% 0)}97%{clip-path:inset(20% 0 65% 0)}99%{clip-path:inset(45% 0 35% 0)}}
113+
114+
.tagline{font-size:clamp(16px,2.4vw,21px);color:var(--ink);margin:14px 0 0;max-width:50ch}
115+
.tagline em{color:var(--magenta);font-style:normal}
116+
.sub{color:var(--muted);font-size:14px;margin-top:10px}
117+
118+
/* ---- sections ---- */
119+
main{padding-bottom:80px}
120+
section{margin-top:clamp(40px,7vw,72px)}
121+
.sec-head{display:flex;align-items:baseline;gap:14px;margin-bottom:22px}
122+
.sec-head h2{
123+
font-size:14px;letter-spacing:.22em;text-transform:uppercase;
124+
color:var(--cyan);margin:0;white-space:nowrap;font-weight:700;
125+
}
126+
.sec-head h2 .num{color:var(--magenta);margin-right:8px}
127+
.sec-head .rule{flex:1;height:1px;background:linear-gradient(90deg,var(--line),transparent)}
128+
129+
/* ---- card grid ---- */
130+
.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(248px,1fr))}
131+
.card{
132+
position:relative;display:flex;flex-direction:column;
133+
padding:22px 22px 20px;
134+
background:var(--card);
135+
border:1px solid var(--line);
136+
border-radius:var(--radius);
137+
text-decoration:none;color:inherit;
138+
overflow:hidden;
139+
transition:transform .18s ease,border-color .18s ease,background .18s ease,box-shadow .18s ease;
140+
}
141+
.card::after{ /* corner accent */
142+
content:"";position:absolute;top:0;right:0;width:46px;height:46px;
143+
background:linear-gradient(225deg,rgba(85,255,255,.22),transparent 60%);
144+
opacity:0;transition:opacity .2s ease;
145+
}
146+
.card:hover,.card:focus-visible{
147+
transform:translateY(-4px);
148+
border-color:var(--cyan);
149+
background:rgba(85,255,255,.05);
150+
box-shadow:0 10px 40px -12px rgba(85,255,255,.4),
151+
inset 0 0 0 1px rgba(85,255,255,.12);
152+
outline:none;
153+
}
154+
.card:hover::after,.card:focus-visible::after{opacity:1}
155+
.card:hover .c-title{color:var(--cyan)}
156+
157+
.c-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px}
158+
.c-icon{font-size:24px;line-height:1;filter:saturate(1.2)}
159+
.c-tag{font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
160+
color:var(--muted);border:1px solid var(--line);border-radius:999px;padding:3px 9px}
161+
.c-title{font-size:18px;font-weight:700;margin:0 0 6px;color:#fff;transition:color .18s ease}
162+
.c-desc{font-size:13.5px;color:var(--muted);margin:0;flex:1}
163+
.c-go{margin-top:16px;font-size:12px;letter-spacing:.1em;text-transform:uppercase;
164+
color:var(--cyan);display:inline-flex;align-items:center;gap:8px}
165+
.c-go .arrow{transition:transform .18s ease}
166+
.card:hover .c-go .arrow{transform:translateX(5px)}
167+
168+
/* ---- footer ---- */
169+
footer{border-top:1px solid var(--line);padding:30px 0 60px;margin-top:30px}
170+
.foot{display:flex;flex-wrap:wrap;gap:14px 26px;align-items:center;justify-content:space-between}
171+
.foot a{color:var(--ink);text-decoration:none;border-bottom:1px dotted var(--muted)}
172+
.foot a:hover{color:var(--cyan);border-color:var(--cyan)}
173+
.foot .meta{color:var(--muted);font-size:12.5px}
174+
175+
@media (max-width:520px){
176+
.grid{grid-template-columns:1fr}
177+
.sec-head{flex-wrap:wrap}
178+
}
179+
@media (prefers-reduced-motion:reduce){
180+
*{animation:none !important;scroll-behavior:auto}
181+
.card{transition:none}
182+
}
183+
</style>
184+
</head>
185+
<body>
186+
<div class="bg-fx" aria-hidden="true"></div>
187+
<canvas id="space" aria-hidden="true"></canvas>
188+
<div class="scanlines" aria-hidden="true"></div>
189+
190+
<div class="wrap">
191+
<header>
192+
<span class="badge"><span class="dot"></span>highda archives — online</span>
193+
<h1 data-text="highda">highda</h1>
194+
<p class="tagline">Free useless stuff! <em>Just as nature intended.</em></p>
195+
<p class="sub">A pile of vibecoded browser toys. Everything runs locally in your tab — no uploads, no accounts, no point.</p>
196+
</header>
197+
198+
<main>
199+
<!-- IMAGE TOOLS -->
200+
<section>
201+
<div class="sec-head">
202+
<h2><span class="num">01</span>Image Tools</h2>
203+
<div class="rule"></div>
204+
</div>
205+
<div class="grid">
206+
<a class="card" href="/vibecode-snippets/convertto-cga.html">
207+
<div class="c-top"><span class="c-icon">🎨</span><span class="c-tag">WASM · Magick</span></div>
208+
<h3 class="c-title">Convert to CGA — v1</h3>
209+
<p class="c-desc">Crunch any image down to the glorious 4-color CGA palette via WebAssembly ImageMagick. Slower, but thorough.</p>
210+
<span class="c-go">Launch <span class="arrow">→</span></span>
211+
</a>
212+
213+
<a class="card" href="/vibecode-snippets/convertto-cga-v2.html">
214+
<div class="c-top"><span class="c-icon">📼</span><span class="c-tag">JS · Mediabunny</span></div>
215+
<h3 class="c-title">Convert to CGA — v2</h3>
216+
<p class="c-desc">Faster pure-JS rewrite with video support. Feed it a clip, get retro frames back.</p>
217+
<span class="c-go">Launch <span class="arrow">→</span></span>
218+
</a>
219+
220+
<a class="card" href="/vibecode-snippets/pixel-sorter.html">
221+
<div class="c-top"><span class="c-icon">🌈</span><span class="c-tag">Glitch</span></div>
222+
<h3 class="c-title">Pixel Sorter on Steroids</h3>
223+
<p class="c-desc">Threshold-driven pixel sorting with way too many knobs. Make your photos drip.</p>
224+
<span class="c-go">Launch <span class="arrow">→</span></span>
225+
</a>
226+
227+
<a class="card" href="/vibecode-snippets/glitch-lab/">
228+
<div class="c-top"><span class="c-icon">⚡</span><span class="c-tag">Multi-FX</span></div>
229+
<h3 class="c-title">Glitch Lab</h3>
230+
<p class="c-desc">A stackable playground of databending effects. Chain them, break things, export the wreckage.</p>
231+
<span class="c-go">Launch <span class="arrow">→</span></span>
232+
</a>
233+
</div>
234+
</section>
235+
236+
<!-- CSS HELPERS -->
237+
<section>
238+
<div class="sec-head">
239+
<h2><span class="num">02</span>CSS Helpers</h2>
240+
<div class="rule"></div>
241+
</div>
242+
<div class="grid">
243+
<a class="card" href="/vibecode-snippets/gradient-maskimage-compositor.html">
244+
<div class="c-top"><span class="c-icon">🧪</span><span class="c-tag">CSS</span></div>
245+
<h3 class="c-title">mask-image Gradient Compositor</h3>
246+
<p class="c-desc">Visually layer and composite CSS <code>mask-image</code> gradients, then copy the ready-to-paste rule.</p>
247+
<span class="c-go">Launch <span class="arrow">→</span></span>
248+
</a>
249+
</div>
250+
</section>
251+
252+
<!-- GUITAR -->
253+
<section>
254+
<div class="sec-head">
255+
<h2><span class="num">03</span>Guitar Learning Helpers</h2>
256+
<div class="rule"></div>
257+
</div>
258+
<div class="grid">
259+
<a class="card" href="/vibecode-snippets/chords-trainer/">
260+
<div class="c-top"><span class="c-icon">🎸</span><span class="c-tag">Practice</span></div>
261+
<h3 class="c-title">Chord Transition Trainer</h3>
262+
<p class="c-desc">Drills the muscle memory of switching between chords. Added to and updated as I keep learning.</p>
263+
<span class="c-go">Launch <span class="arrow">→</span></span>
264+
</a>
265+
</div>
266+
</section>
267+
</main>
268+
269+
<footer>
270+
<div class="foot">
271+
<span class="meta">built in browsers, for browsers</span>
272+
<span class="meta">
273+
<a href="https://github.com/highda" rel="noopener">github.com/highda</a>
274+
</span>
275+
</div>
276+
</footer>
277+
</div>
278+
279+
<script>
280+
(function(){
281+
var canvas = document.getElementById('space');
282+
if(!canvas) return;
283+
var ctx = canvas.getContext('2d');
284+
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
285+
286+
var dpr, W, H, stars = [], shoot = null, nextShoot = 0;
287+
var PALETTE = ['#ffffff','#cde9ff','#9fd9ff','#ff9ff0','#bfa8ff'];
288+
289+
function rand(a,b){ return a + Math.random()*(b-a); }
290+
291+
function build(){
292+
dpr = Math.min(window.devicePixelRatio || 1, 2);
293+
W = window.innerWidth; H = window.innerHeight;
294+
canvas.width = W * dpr;
295+
canvas.height = H * dpr;
296+
canvas.style.width = W + 'px';
297+
canvas.style.height = H + 'px';
298+
ctx.setTransform(dpr,0,0,dpr,0,0);
299+
300+
// density scales with viewport area, 3 parallax layers
301+
var count = Math.round((W * H) / 4200);
302+
count = Math.max(90, Math.min(420, count));
303+
stars = [];
304+
for(var i=0;i<count;i++){
305+
var layer = Math.random(); // 0..1 depth
306+
stars.push({
307+
x: Math.random()*W,
308+
y: Math.random()*H,
309+
r: rand(0.4, 1.6) * (0.6 + layer),
310+
baseA: rand(0.25, 0.95),
311+
tw: rand(0.6, 2.2), // twinkle speed
312+
ph: rand(0, Math.PI*2),
313+
vx: -(0.04 + layer*0.32), // drift left, far=slow
314+
color: PALETTE[(Math.random()*PALETTE.length)|0]
315+
});
316+
}
317+
}
318+
319+
function spawnShoot(){
320+
var fromTop = Math.random() < 0.5;
321+
shoot = {
322+
x: rand(W*0.1, W*0.9),
323+
y: fromTop ? rand(-40,-10) : rand(0, H*0.4),
324+
vx: rand(-7,-4),
325+
vy: rand(3,6),
326+
life: 0,
327+
max: rand(40,70),
328+
len: rand(80,160)
329+
};
330+
}
331+
332+
function draw(t){
333+
ctx.clearRect(0,0,W,H);
334+
for(var i=0;i<stars.length;i++){
335+
var s = stars[i];
336+
if(!reduce){
337+
s.x += s.vx;
338+
if(s.x < -2){ s.x = W+2; s.y = Math.random()*H; }
339+
}
340+
var a = reduce ? s.baseA
341+
: s.baseA * (0.55 + 0.45*Math.sin(s.ph + t*0.001*s.tw));
342+
ctx.globalAlpha = a;
343+
ctx.fillStyle = s.color;
344+
ctx.beginPath();
345+
ctx.arc(s.x, s.y, s.r, 0, Math.PI*2);
346+
ctx.fill();
347+
// soft glow on the brighter/closer stars
348+
if(s.r > 1.3){
349+
ctx.globalAlpha = a*0.25;
350+
ctx.beginPath();
351+
ctx.arc(s.x, s.y, s.r*2.6, 0, Math.PI*2);
352+
ctx.fill();
353+
}
354+
}
355+
ctx.globalAlpha = 1;
356+
357+
if(!reduce){
358+
if(!shoot && t > nextShoot){ spawnShoot(); }
359+
if(shoot){
360+
shoot.x += shoot.vx; shoot.y += shoot.vy; shoot.life++;
361+
var p = shoot.life / shoot.max;
362+
var fade = Math.sin(Math.min(p,1)*Math.PI); // ease in/out
363+
var tx = shoot.x - shoot.vx/Math.hypot(shoot.vx,shoot.vy)*shoot.len;
364+
var ty = shoot.y - shoot.vy/Math.hypot(shoot.vx,shoot.vy)*shoot.len;
365+
var g = ctx.createLinearGradient(shoot.x, shoot.y, tx, ty);
366+
g.addColorStop(0,'rgba(255,255,255,'+(0.9*fade)+')');
367+
g.addColorStop(0.4,'rgba(85,255,255,'+(0.5*fade)+')');
368+
g.addColorStop(1,'rgba(85,255,255,0)');
369+
ctx.strokeStyle = g; ctx.lineWidth = 2; ctx.lineCap = 'round';
370+
ctx.beginPath(); ctx.moveTo(shoot.x, shoot.y); ctx.lineTo(tx, ty); ctx.stroke();
371+
if(shoot.life > shoot.max || shoot.x < -200 || shoot.y > H+200){
372+
shoot = null; nextShoot = t + rand(3500, 9000);
373+
}
374+
}
375+
}
376+
if(!reduce) requestAnimationFrame(draw);
377+
}
378+
379+
build();
380+
nextShoot = 2000;
381+
var rt; window.addEventListener('resize', function(){
382+
clearTimeout(rt); rt = setTimeout(build, 150);
383+
});
384+
requestAnimationFrame(draw);
385+
})();
386+
</script>
387+
</body>
388+
</html>

0 commit comments

Comments
 (0)