create-geocities-app 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +309 -0
- data/bin/create-geocities-app +133 -0
- data/lib/create_geocities_app/generator.rb +87 -0
- data/lib/create_geocities_app/themes.rb +53 -0
- data/lib/create_geocities_app/version.rb +3 -0
- data/lib/create_geocities_app.rb +3 -0
- data/templates/about.html +157 -0
- data/templates/css/style.css +729 -0
- data/templates/gallery.html +211 -0
- data/templates/guestbook.html +173 -0
- data/templates/index.html +193 -0
- data/templates/js/main.js +382 -0
- data/templates/links.html +198 -0
- metadata +86 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/* ================================================
|
|
2
|
+
create-geocities-app — main.js
|
|
3
|
+
Generated site script — NO external dependencies
|
|
4
|
+
================================================ */
|
|
5
|
+
|
|
6
|
+
(function () {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/* ── Config (injected by generator) ── */
|
|
10
|
+
var CONFIG = {
|
|
11
|
+
siteName: '{{SITE_NAME}}',
|
|
12
|
+
authorName: '{{AUTHOR_NAME}}',
|
|
13
|
+
cursorEffect: '{{CURSOR_EFFECT}}',
|
|
14
|
+
fallingEffect:'{{FALLING_EFFECT}}',
|
|
15
|
+
welcomeAlert: '{{WELCOME_ALERT}}' === 'true',
|
|
16
|
+
playMusic: '{{PLAY_MUSIC}}' === 'true',
|
|
17
|
+
fakeHighCount:'{{FAKE_HIGH_COUNT}}' === 'true',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/* ── Visitor Counter ── */
|
|
21
|
+
function initCounter() {
|
|
22
|
+
var el = document.getElementById('counter-display');
|
|
23
|
+
if (!el) return;
|
|
24
|
+
|
|
25
|
+
var storageKey = 'gc_visits_' + location.hostname + location.pathname;
|
|
26
|
+
var stored = parseInt(localStorage.getItem(storageKey), 10);
|
|
27
|
+
var start = CONFIG.fakeHighCount ? 10247 : 1;
|
|
28
|
+
var count = isNaN(stored) ? start : stored + 1;
|
|
29
|
+
localStorage.setItem(storageKey, count);
|
|
30
|
+
|
|
31
|
+
var digits = String(count).padStart(7, '0').split('');
|
|
32
|
+
el.innerHTML = '';
|
|
33
|
+
digits.forEach(function (d) {
|
|
34
|
+
var box = document.createElement('span');
|
|
35
|
+
box.className = 'digit-box';
|
|
36
|
+
box.textContent = d;
|
|
37
|
+
el.appendChild(box);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Animate digits rolling in one by one
|
|
41
|
+
var boxes = el.querySelectorAll('.digit-box');
|
|
42
|
+
boxes.forEach(function (box, i) {
|
|
43
|
+
setTimeout(function () {
|
|
44
|
+
box.classList.add('rolling');
|
|
45
|
+
setTimeout(function () { box.classList.remove('rolling'); }, 160);
|
|
46
|
+
}, i * 80);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* ── Page Clock ── */
|
|
51
|
+
function initClock() {
|
|
52
|
+
var el = document.getElementById('page-clock');
|
|
53
|
+
if (!el) return;
|
|
54
|
+
function tick() {
|
|
55
|
+
var now = new Date();
|
|
56
|
+
var h = String(now.getHours()).padStart(2, '0');
|
|
57
|
+
var m = String(now.getMinutes()).padStart(2, '0');
|
|
58
|
+
var s = String(now.getSeconds()).padStart(2, '0');
|
|
59
|
+
el.textContent = h + ':' + m + ':' + s;
|
|
60
|
+
}
|
|
61
|
+
tick();
|
|
62
|
+
setInterval(tick, 1000);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* ── Welcome Alert ── */
|
|
66
|
+
function initWelcomeAlert() {
|
|
67
|
+
if (!CONFIG.welcomeAlert) return;
|
|
68
|
+
setTimeout(function () {
|
|
69
|
+
alert('✨ Welcome to ' + CONFIG.siteName + '! ✨\n\nMake yourself at home.\n\n– ' + CONFIG.authorName);
|
|
70
|
+
}, 400);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* ── 8-bit Music (Web Audio API) ── */
|
|
74
|
+
var audioCtx = null;
|
|
75
|
+
var musicPlaying = false;
|
|
76
|
+
var musicInterval = null;
|
|
77
|
+
|
|
78
|
+
var MELODY = [
|
|
79
|
+
523, 587, 659, 698, 784, 698, 659, 587,
|
|
80
|
+
523, 523, 587, 659, 523, 0, 523, 0
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
function playNote(freq, startTime, duration) {
|
|
84
|
+
if (!audioCtx || freq === 0) return;
|
|
85
|
+
var osc = audioCtx.createOscillator();
|
|
86
|
+
var gain = audioCtx.createGain();
|
|
87
|
+
osc.connect(gain);
|
|
88
|
+
gain.connect(audioCtx.destination);
|
|
89
|
+
osc.type = 'square';
|
|
90
|
+
osc.frequency.setValueAtTime(freq, startTime);
|
|
91
|
+
gain.gain.setValueAtTime(0.08, startTime);
|
|
92
|
+
gain.gain.exponentialRampToValueAtTime(0.001, startTime + duration * 0.9);
|
|
93
|
+
osc.start(startTime);
|
|
94
|
+
osc.stop(startTime + duration);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function playMelody() {
|
|
98
|
+
if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
|
99
|
+
var now = audioCtx.currentTime;
|
|
100
|
+
var noteLen = 0.18;
|
|
101
|
+
MELODY.forEach(function (freq, i) {
|
|
102
|
+
playNote(freq, now + i * noteLen, noteLen);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function initMusic() {
|
|
107
|
+
var btn = document.getElementById('music-btn');
|
|
108
|
+
|
|
109
|
+
function startMusic() {
|
|
110
|
+
if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
|
111
|
+
musicPlaying = true;
|
|
112
|
+
playMelody();
|
|
113
|
+
musicInterval = setInterval(playMelody, MELODY.length * 180 + 400);
|
|
114
|
+
if (btn) btn.textContent = '🔇 STOP MUSIC';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function stopMusic() {
|
|
118
|
+
musicPlaying = false;
|
|
119
|
+
clearInterval(musicInterval);
|
|
120
|
+
if (btn) btn.textContent = '🎵 PLAY MUSIC';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (btn) {
|
|
124
|
+
btn.addEventListener('click', function () {
|
|
125
|
+
if (musicPlaying) stopMusic(); else startMusic();
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (CONFIG.playMusic) {
|
|
130
|
+
// Browsers require user gesture — attach to first click anywhere
|
|
131
|
+
function onFirstInteraction() {
|
|
132
|
+
startMusic();
|
|
133
|
+
document.removeEventListener('click', onFirstInteraction);
|
|
134
|
+
document.removeEventListener('keydown', onFirstInteraction);
|
|
135
|
+
}
|
|
136
|
+
document.addEventListener('click', onFirstInteraction);
|
|
137
|
+
document.addEventListener('keydown', onFirstInteraction);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* ── Falling Effects ── */
|
|
142
|
+
function initFalling() {
|
|
143
|
+
var effect = CONFIG.fallingEffect;
|
|
144
|
+
if (effect === 'none') return;
|
|
145
|
+
|
|
146
|
+
var count = effect === 'snow' ? 40 : 60;
|
|
147
|
+
|
|
148
|
+
for (var i = 0; i < count; i++) {
|
|
149
|
+
spawnFallingElement(effect, i * 200);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function spawnFallingElement(type, delay) {
|
|
154
|
+
var el = document.createElement('div');
|
|
155
|
+
el.className = 'falling-element';
|
|
156
|
+
|
|
157
|
+
var left = Math.random() * 100;
|
|
158
|
+
var duration = 4 + Math.random() * 8;
|
|
159
|
+
var size = type === 'snow' ? (6 + Math.random() * 10) : (4 + Math.random() * 6);
|
|
160
|
+
var drift = (Math.random() - 0.5) * 60;
|
|
161
|
+
|
|
162
|
+
el.style.left = left + 'vw';
|
|
163
|
+
el.style.setProperty('--drift', drift + 'px');
|
|
164
|
+
el.style.animationDuration = duration + 's';
|
|
165
|
+
el.style.animationDelay = delay + 'ms';
|
|
166
|
+
|
|
167
|
+
if (type === 'snow') {
|
|
168
|
+
el.style.width = size + 'px';
|
|
169
|
+
el.style.height = size + 'px';
|
|
170
|
+
el.style.borderRadius = '50%';
|
|
171
|
+
el.style.background = 'rgba(255,255,255,0.85)';
|
|
172
|
+
el.style.boxShadow = '0 0 4px rgba(255,255,255,0.5)';
|
|
173
|
+
} else {
|
|
174
|
+
el.textContent = '★';
|
|
175
|
+
el.style.fontSize = size + 'px';
|
|
176
|
+
el.style.color = ['#FFFFFF', '#FFFF00', '#00FFFF', '#FF00FF'][Math.floor(Math.random() * 4)];
|
|
177
|
+
el.style.textShadow = '0 0 4px currentColor';
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
document.body.appendChild(el);
|
|
181
|
+
|
|
182
|
+
// Loop forever
|
|
183
|
+
el.addEventListener('animationend', function () {
|
|
184
|
+
el.style.top = '-20px';
|
|
185
|
+
el.style.animationDelay = '0ms';
|
|
186
|
+
el.style.left = (Math.random() * 100) + 'vw';
|
|
187
|
+
el.style.setProperty('--drift', ((Math.random() - 0.5) * 60) + 'px');
|
|
188
|
+
el.style.animation = 'none';
|
|
189
|
+
void el.offsetHeight; // reflow
|
|
190
|
+
el.style.animation = '';
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* ── Cursor Effects ── */
|
|
195
|
+
var hue = 0;
|
|
196
|
+
var trailPool = [];
|
|
197
|
+
|
|
198
|
+
function initCursor() {
|
|
199
|
+
var effect = CONFIG.cursorEffect;
|
|
200
|
+
if (effect === 'none') return;
|
|
201
|
+
|
|
202
|
+
document.addEventListener('mousemove', function (e) {
|
|
203
|
+
switch (effect) {
|
|
204
|
+
case 'sparkle': spawnSparkle(e.clientX, e.clientY); break;
|
|
205
|
+
case 'startrail': spawnStarTrail(e.clientX, e.clientY); break;
|
|
206
|
+
case 'comet': spawnComet(e.clientX, e.clientY); break;
|
|
207
|
+
case 'rainbow': spawnRainbow(e.clientX, e.clientY); break;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function makeTrailEl(text, x, y, color, size) {
|
|
213
|
+
var el = document.createElement('div');
|
|
214
|
+
el.className = 'cursor-trail';
|
|
215
|
+
el.textContent = text;
|
|
216
|
+
el.style.left = x + 'px';
|
|
217
|
+
el.style.top = y + 'px';
|
|
218
|
+
el.style.color = color;
|
|
219
|
+
el.style.fontSize = (size || 14) + 'px';
|
|
220
|
+
el.style.opacity = '1';
|
|
221
|
+
document.body.appendChild(el);
|
|
222
|
+
return el;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function spawnSparkle(x, y) {
|
|
226
|
+
if (Math.random() > 0.4) return;
|
|
227
|
+
var glyphs = ['✦', '✧', '✨', '⋆', '·', '★', '✺', '✼'];
|
|
228
|
+
var glyph = glyphs[Math.floor(Math.random() * glyphs.length)];
|
|
229
|
+
var colors = ['#FFD700', '#FF69B4', '#00FFFF', '#ADFF2F', '#FF6347', '#FFF'];
|
|
230
|
+
var color = colors[Math.floor(Math.random() * colors.length)];
|
|
231
|
+
var ox = (Math.random() - 0.5) * 24;
|
|
232
|
+
var oy = (Math.random() - 0.5) * 24;
|
|
233
|
+
var el = makeTrailEl(glyph, x + ox - 8, y + oy - 8, color, 12 + Math.random() * 10);
|
|
234
|
+
el.style.transition = 'none';
|
|
235
|
+
el.style.animation = 'sparkleFloat ' + (0.5 + Math.random() * 0.5) + 's ease-out forwards';
|
|
236
|
+
setTimeout(function () { if (el.parentNode) el.parentNode.removeChild(el); }, 1000);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function spawnStarTrail(x, y) {
|
|
240
|
+
if (Math.random() > 0.5) return;
|
|
241
|
+
var el = makeTrailEl('★', x - 8, y - 8, '#FFFF00', 14);
|
|
242
|
+
el.style.textShadow = '0 0 6px #FFFF00';
|
|
243
|
+
el.style.transition = 'opacity 0.5s, transform 0.5s';
|
|
244
|
+
setTimeout(function () {
|
|
245
|
+
el.style.opacity = '0';
|
|
246
|
+
el.style.transform = 'translateY(-12px) scale(0.5)';
|
|
247
|
+
}, 50);
|
|
248
|
+
setTimeout(function () { if (el.parentNode) el.parentNode.removeChild(el); }, 600);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function spawnComet(x, y) {
|
|
252
|
+
if (Math.random() > 0.6) return;
|
|
253
|
+
var el = document.createElement('div');
|
|
254
|
+
el.className = 'cursor-trail';
|
|
255
|
+
el.style.left = (x - 6) + 'px';
|
|
256
|
+
el.style.top = (y - 2) + 'px';
|
|
257
|
+
el.style.width = '12px';
|
|
258
|
+
el.style.height = '4px';
|
|
259
|
+
el.style.borderRadius = '50%';
|
|
260
|
+
el.style.background = 'linear-gradient(to left, #FFFFFF, #FF6600, transparent)';
|
|
261
|
+
el.style.transition = 'opacity 0.4s';
|
|
262
|
+
document.body.appendChild(el);
|
|
263
|
+
setTimeout(function () { el.style.opacity = '0'; }, 50);
|
|
264
|
+
setTimeout(function () { if (el.parentNode) el.parentNode.removeChild(el); }, 500);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function spawnRainbow(x, y) {
|
|
268
|
+
if (Math.random() > 0.5) return;
|
|
269
|
+
hue = (hue + 15) % 360;
|
|
270
|
+
var el = document.createElement('div');
|
|
271
|
+
el.className = 'cursor-trail';
|
|
272
|
+
el.style.left = (x - 4) + 'px';
|
|
273
|
+
el.style.top = (y - 4) + 'px';
|
|
274
|
+
el.style.width = '8px';
|
|
275
|
+
el.style.height = '8px';
|
|
276
|
+
el.style.borderRadius = '50%';
|
|
277
|
+
el.style.background = 'hsl(' + hue + ',100%,60%)';
|
|
278
|
+
el.style.boxShadow = '0 0 4px hsl(' + hue + ',100%,60%)';
|
|
279
|
+
el.style.transition = 'opacity 0.5s, transform 0.5s';
|
|
280
|
+
document.body.appendChild(el);
|
|
281
|
+
setTimeout(function () {
|
|
282
|
+
el.style.opacity = '0';
|
|
283
|
+
el.style.transform = 'scale(0.2)';
|
|
284
|
+
}, 50);
|
|
285
|
+
setTimeout(function () { if (el.parentNode) el.parentNode.removeChild(el); }, 600);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* ── Matrix Rain Easter Egg ── */
|
|
289
|
+
function initMatrix() {
|
|
290
|
+
var canvas = document.getElementById('matrix-canvas');
|
|
291
|
+
var hint = document.getElementById('matrix-hint');
|
|
292
|
+
if (!canvas) return;
|
|
293
|
+
|
|
294
|
+
var ctx = canvas.getContext('2d');
|
|
295
|
+
var running = false;
|
|
296
|
+
var raf;
|
|
297
|
+
var cols, drops;
|
|
298
|
+
|
|
299
|
+
function resize() {
|
|
300
|
+
canvas.width = window.innerWidth;
|
|
301
|
+
canvas.height = window.innerHeight;
|
|
302
|
+
cols = Math.floor(canvas.width / 16);
|
|
303
|
+
drops = Array(cols).fill(1);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function draw() {
|
|
307
|
+
ctx.fillStyle = 'rgba(0,0,0,0.05)';
|
|
308
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
309
|
+
ctx.fillStyle = '#00FF41';
|
|
310
|
+
ctx.font = '14px "Courier New"';
|
|
311
|
+
drops.forEach(function (y, i) {
|
|
312
|
+
var char = String.fromCharCode(0x30A0 + Math.random() * 96);
|
|
313
|
+
ctx.fillText(char, i * 16, y * 16);
|
|
314
|
+
if (y * 16 > canvas.height && Math.random() > 0.975) drops[i] = 0;
|
|
315
|
+
drops[i]++;
|
|
316
|
+
});
|
|
317
|
+
raf = requestAnimationFrame(draw);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function toggle() {
|
|
321
|
+
running = !running;
|
|
322
|
+
canvas.classList.toggle('active', running);
|
|
323
|
+
if (running) { resize(); draw(); }
|
|
324
|
+
else { cancelAnimationFrame(raf); ctx.clearRect(0, 0, canvas.width, canvas.height); }
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
document.addEventListener('keydown', function (e) {
|
|
328
|
+
if ((e.key === 'm' || e.key === 'M') && !e.ctrlKey && !e.metaKey) toggle();
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
window.addEventListener('resize', function () { if (running) resize(); });
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* ── Gallery Lightbox ── */
|
|
335
|
+
function initLightbox() {
|
|
336
|
+
var lb = document.getElementById('lightbox');
|
|
337
|
+
var lbImg = document.getElementById('lightbox-img');
|
|
338
|
+
var lbCap = document.getElementById('lightbox-caption');
|
|
339
|
+
var lbClose = document.getElementById('lightbox-close');
|
|
340
|
+
if (!lb) return;
|
|
341
|
+
|
|
342
|
+
document.querySelectorAll('.gallery-item').forEach(function (item) {
|
|
343
|
+
item.addEventListener('click', function () {
|
|
344
|
+
var img = item.querySelector('img');
|
|
345
|
+
var cap = item.querySelector('.gallery-caption');
|
|
346
|
+
if (img) lbImg.src = img.src;
|
|
347
|
+
if (cap) lbCap.textContent = cap.textContent;
|
|
348
|
+
lb.classList.add('active');
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
function closeLb() { lb.classList.remove('active'); }
|
|
353
|
+
lb.addEventListener('click', function (e) { if (e.target === lb) closeLb(); });
|
|
354
|
+
if (lbClose) lbClose.addEventListener('click', closeLb);
|
|
355
|
+
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeLb(); });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/* ── Guestbook form ── */
|
|
359
|
+
function initGuestbook() {
|
|
360
|
+
var form = document.getElementById('guestbook-form');
|
|
361
|
+
if (!form) return;
|
|
362
|
+
form.addEventListener('submit', function (e) {
|
|
363
|
+
e.preventDefault();
|
|
364
|
+
alert('Thanks for signing the guestbook! 📖\n\n(This is a static site — no backend yet.\nAdd a form service like Formspree to save entries!)');
|
|
365
|
+
form.reset();
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/* ── Init all ── */
|
|
370
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
371
|
+
initCounter();
|
|
372
|
+
initClock();
|
|
373
|
+
initWelcomeAlert();
|
|
374
|
+
initMusic();
|
|
375
|
+
initFalling();
|
|
376
|
+
initCursor();
|
|
377
|
+
initMatrix();
|
|
378
|
+
initLightbox();
|
|
379
|
+
initGuestbook();
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
})();
|
|
@@ -0,0 +1,198 @@
|
|
|
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.0">
|
|
6
|
+
<meta name="generator" content="create-geocities-app">
|
|
7
|
+
<title>{{SITE_NAME}} — Cool Links</title>
|
|
8
|
+
<link rel="stylesheet" href="css/style.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
|
|
12
|
+
<canvas id="matrix-canvas"></canvas>
|
|
13
|
+
<div id="matrix-hint">[M] toggle matrix</div>
|
|
14
|
+
|
|
15
|
+
<div id="lightbox">
|
|
16
|
+
<span id="lightbox-close">✕</span>
|
|
17
|
+
<img id="lightbox-img" src="" alt="">
|
|
18
|
+
<div id="lightbox-caption"></div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div id="page-wrapper">
|
|
22
|
+
<table id="main-table" cellpadding="0" cellspacing="0">
|
|
23
|
+
|
|
24
|
+
<tr>
|
|
25
|
+
<td colspan="2" id="header-cell">
|
|
26
|
+
<div class="marquee-wrapper">
|
|
27
|
+
<span class="marquee-inner">
|
|
28
|
+
🔗 {{AUTHOR_NAME}}'s Cool Links 🔗
|
|
29
|
+
The best sites on the world wide web!
|
|
30
|
+
★ Last updated {{YEAR}} ★
|
|
31
|
+
</span>
|
|
32
|
+
</div>
|
|
33
|
+
<h1 class="rainbow" style="margin:8px 0 4px;">{{SITE_NAME}}</h1>
|
|
34
|
+
</td>
|
|
35
|
+
</tr>
|
|
36
|
+
|
|
37
|
+
<tr id="content-row">
|
|
38
|
+
|
|
39
|
+
<td id="sidebar">
|
|
40
|
+
<div class="panel">
|
|
41
|
+
<div class="panel-title">📡 Navigation</div>
|
|
42
|
+
{{NAV_LINKS}}
|
|
43
|
+
</div>
|
|
44
|
+
<div class="panel" style="text-align:center;">
|
|
45
|
+
<div class="panel-title">🌐 Site Info</div>
|
|
46
|
+
<span class="spinning-globe">🌍</span>
|
|
47
|
+
<span id="page-clock">00:00:00</span>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="panel" style="text-align:center;">
|
|
50
|
+
<div class="panel-title">🎵 Music</div>
|
|
51
|
+
<button id="music-btn" class="retro-btn" style="width:100%;font-size:0.7rem;">🎵 PLAY MUSIC</button>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="panel" style="text-align:center;font-size:0.75rem;">
|
|
54
|
+
<div class="panel-title">📊 Visitors</div>
|
|
55
|
+
<div id="visitor-counter-box">
|
|
56
|
+
<div class="counter-label">You are visitor #</div>
|
|
57
|
+
<div class="counter-digits" id="counter-display"></div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</td>
|
|
61
|
+
|
|
62
|
+
<td id="main-content">
|
|
63
|
+
|
|
64
|
+
<div class="panel">
|
|
65
|
+
<div class="panel-title">🔗 Cool Links Curated by {{AUTHOR_NAME}}</div>
|
|
66
|
+
<p style="font-size:0.8rem;margin-bottom:6px;">
|
|
67
|
+
Here are the best websites I've found on the World Wide Web!
|
|
68
|
+
Bookmark this page — it's updated regularly!
|
|
69
|
+
</p>
|
|
70
|
+
|
|
71
|
+
<div class="links-category">🤝 Friends' Pages</div>
|
|
72
|
+
|
|
73
|
+
<div class="link-item">
|
|
74
|
+
<span class="link-bullet">►</span>
|
|
75
|
+
<div>
|
|
76
|
+
<a href="#" target="_blank" rel="noopener">CoolDude1996's Homepage</a>
|
|
77
|
+
<div class="link-desc">My best friend's site — great music section!</div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="link-item">
|
|
81
|
+
<span class="link-bullet">►</span>
|
|
82
|
+
<div>
|
|
83
|
+
<a href="#" target="_blank" rel="noopener">StarChild's GeoCities Page</a>
|
|
84
|
+
<div class="link-desc">Awesome anime artwork and cool GIFs</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="link-item">
|
|
88
|
+
<span class="link-bullet">►</span>
|
|
89
|
+
<div>
|
|
90
|
+
<a href="#" target="_blank" rel="noopener">NetNinja42's Web Zone</a>
|
|
91
|
+
<div class="link-desc">The best tech tips on the web</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div class="links-category">🎮 Games & Fun</div>
|
|
96
|
+
|
|
97
|
+
<div class="link-item">
|
|
98
|
+
<span class="link-bullet">►</span>
|
|
99
|
+
<div>
|
|
100
|
+
<a href="https://archive.org/details/classicpcgames" target="_blank" rel="noopener">Classic PC Games Archive</a>
|
|
101
|
+
<div class="link-desc">Play old DOS games right in your browser!</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="link-item">
|
|
105
|
+
<span class="link-bullet">►</span>
|
|
106
|
+
<div>
|
|
107
|
+
<a href="https://www.neopets.com" target="_blank" rel="noopener">Neopets</a>
|
|
108
|
+
<div class="link-desc">Virtual pets and games — still running!</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div class="links-category">🖥️ Web & Tech</div>
|
|
113
|
+
|
|
114
|
+
<div class="link-item">
|
|
115
|
+
<span class="link-bullet">►</span>
|
|
116
|
+
<div>
|
|
117
|
+
<a href="https://geocities.restorativland.org" target="_blank" rel="noopener">GeoCities Archive</a>
|
|
118
|
+
<div class="link-desc">Browse the original GeoCities — preserved for eternity!</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="link-item">
|
|
122
|
+
<span class="link-bullet">►</span>
|
|
123
|
+
<div>
|
|
124
|
+
<a href="https://archive.org" target="_blank" rel="noopener">The Internet Archive</a>
|
|
125
|
+
<div class="link-desc">Every website ever — the Wayback Machine!</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="link-item">
|
|
129
|
+
<span class="link-bullet">►</span>
|
|
130
|
+
<div>
|
|
131
|
+
<a href="https://web.dev" target="_blank" rel="noopener">Web.dev</a>
|
|
132
|
+
<div class="link-desc">Learn to build better websites (but ours is already the best)</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<div class="links-category">🎨 Art & Creativity</div>
|
|
137
|
+
|
|
138
|
+
<div class="link-item">
|
|
139
|
+
<span class="link-bullet">►</span>
|
|
140
|
+
<div>
|
|
141
|
+
<a href="https://glitter-graphics.com" target="_blank" rel="noopener">Glitter Graphics</a>
|
|
142
|
+
<div class="link-desc">Free glitter animations for your homepage!</div>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
<div class="link-item">
|
|
146
|
+
<span class="link-bullet">►</span>
|
|
147
|
+
<div>
|
|
148
|
+
<a href="https://gifcities.org" target="_blank" rel="noopener">GifCities</a>
|
|
149
|
+
<div class="link-desc">Search engine for classic GeoCities GIFs</div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<div class="links-category">📰 News & Info</div>
|
|
154
|
+
|
|
155
|
+
<div class="link-item">
|
|
156
|
+
<span class="link-bullet">►</span>
|
|
157
|
+
<div>
|
|
158
|
+
<a href="https://news.ycombinator.com" target="_blank" rel="noopener">Hacker News</a>
|
|
159
|
+
<div class="link-desc">Tech news and nerdy discussions</div>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<hr class="retro-divider" style="margin:12px 0;">
|
|
164
|
+
|
|
165
|
+
<div style="text-align:center;padding:8px 0;">
|
|
166
|
+
<p style="font-size:0.8rem;margin-bottom:8px;">
|
|
167
|
+
Want to swap links? Email me and I'll add your site!
|
|
168
|
+
</p>
|
|
169
|
+
<a href="mailto:{{AUTHOR_NAME}}@example.com" class="retro-btn">📧 Request Link Exchange</a>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
</div>
|
|
173
|
+
|
|
174
|
+
</td>
|
|
175
|
+
</tr>
|
|
176
|
+
|
|
177
|
+
<tr>
|
|
178
|
+
<td colspan="2" id="footer-cell">
|
|
179
|
+
<div class="star-divider">✦ ✧ ✦ ✧ ✦ ✧ ✦ ✧ ✦</div>
|
|
180
|
+
<p style="font-size:0.75rem;margin:4px 0;">
|
|
181
|
+
© {{YEAR}} <strong>{{AUTHOR_NAME}}</strong> — All Rights Reserved
|
|
182
|
+
| <a href="index.html">Home</a>
|
|
183
|
+
</p>
|
|
184
|
+
<p style="font-size:0.65rem;opacity:0.6;margin-top:6px;">
|
|
185
|
+
<a href="https://bestsugardaddyapps.com/">Best Sugar Daddy Apps</a>
|
|
186
|
+
</p>
|
|
187
|
+
<p style="font-size:0.7rem;margin:4px 0;">
|
|
188
|
+
<span class="netscape-badge">Best viewed in Netscape Navigator 4.0<br>at 800×600 resolution</span>
|
|
189
|
+
</p>
|
|
190
|
+
</td>
|
|
191
|
+
</tr>
|
|
192
|
+
|
|
193
|
+
</table>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<script src="js/main.js"></script>
|
|
197
|
+
</body>
|
|
198
|
+
</html>
|
metadata
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: create-geocities-app
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jamey Baldwin
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-05-11 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: tty-prompt
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.23'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.23'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: pastel
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.8'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.8'
|
|
41
|
+
description: Scaffold a 1990s Geocities-themed static website in seconds
|
|
42
|
+
email:
|
|
43
|
+
executables:
|
|
44
|
+
- create-geocities-app
|
|
45
|
+
extensions: []
|
|
46
|
+
extra_rdoc_files: []
|
|
47
|
+
files:
|
|
48
|
+
- README.md
|
|
49
|
+
- bin/create-geocities-app
|
|
50
|
+
- lib/create_geocities_app.rb
|
|
51
|
+
- lib/create_geocities_app/generator.rb
|
|
52
|
+
- lib/create_geocities_app/themes.rb
|
|
53
|
+
- lib/create_geocities_app/version.rb
|
|
54
|
+
- templates/about.html
|
|
55
|
+
- templates/css/style.css
|
|
56
|
+
- templates/gallery.html
|
|
57
|
+
- templates/guestbook.html
|
|
58
|
+
- templates/index.html
|
|
59
|
+
- templates/js/main.js
|
|
60
|
+
- templates/links.html
|
|
61
|
+
homepage: https://github.com/sugardaddyapp/geocities-boilerplate
|
|
62
|
+
licenses:
|
|
63
|
+
- MIT
|
|
64
|
+
metadata:
|
|
65
|
+
homepage_uri: https://github.com/sugardaddyapp/geocities-boilerplate
|
|
66
|
+
source_code_uri: https://github.com/sugardaddyapp/geocities-boilerplate
|
|
67
|
+
post_install_message:
|
|
68
|
+
rdoc_options: []
|
|
69
|
+
require_paths:
|
|
70
|
+
- lib
|
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 2.7.0
|
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - ">="
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '0'
|
|
81
|
+
requirements: []
|
|
82
|
+
rubygems_version: 3.0.3.1
|
|
83
|
+
signing_key:
|
|
84
|
+
specification_version: 4
|
|
85
|
+
summary: Scaffold a 1990s Geocities-themed static website in seconds
|
|
86
|
+
test_files: []
|