From 80d96cff7580ba2f9e095cb07b6a2c51f4f537b2 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 11 Apr 2026 17:44:06 +0000 Subject: [PATCH] =?UTF-8?q?Refine=20Pixel=20Landing=20Page=20with=20T?= =?UTF-8?q?=C3=ADr=20na=20n=C3=93g=20spatial=20architecture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Implement Doors and Alleys spatial navigation system - Add Tír na nÓg pixel-art aesthetic and smooth transitions - Support keyboard (WASD/Arrows) and mouse-based navigation - Restructure HTML into a navigable 2D grid of rooms Co-authored-by: micmug <185775013+micmug@users.noreply.github.com> --- index.html | 63 +++++++++++++++++++++++++++++ script.js | 92 ++++++++++++++++++++++++++++++++++++++++++ styles.css | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 269 insertions(+) create mode 100644 index.html create mode 100644 script.js create mode 100644 styles.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..9c90795 --- /dev/null +++ b/index.html @@ -0,0 +1,63 @@ + + + + + + faebits | Tír na nÓg + + + +
+
+ +
+
+

Tír na nÓg

+

Welcome to the Land of Eternal Youth.

+
+
+ + +
+
+ + +
+
+

The Meadow

+

Where pixels bloom and legends grow.

+
+
+ + +
+
+ + +
+
+

The Alleys

+

Navigating the narrow paths of creation.

+
+
+ + +
+
+ + +
+
+

The Portal

+

Step through to join the faebits.

+
+
+ + +
+
+
+
+ + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..7a7294d --- /dev/null +++ b/script.js @@ -0,0 +1,92 @@ +/** + * Tír na nÓg - Spatial Navigation + * Logic for moving through the grid of rooms using doors and keys. + */ + +document.addEventListener('DOMContentLoaded', () => { + const world = document.getElementById('world'); + const doors = document.querySelectorAll('.door'); + const rooms = document.querySelectorAll('.room'); + + let currentPos = { x: 0, y: 0 }; + const gridSize = { width: 2, height: 2 }; + + /** + * Updates the viewport position based on current x, y coordinates + */ + function updateView() { + const translateX = -currentPos.x * 100; + const translateY = -currentPos.y * 100; + world.style.transform = `translate(${translateX}vw, ${translateY}vh)`; + + // Update active class for rooms + rooms.forEach(room => { + const id = `room-${currentPos.x}-${currentPos.y}`; + if (room.id === id) { + room.classList.add('active'); + } else { + room.classList.remove('active'); + } + }); + + console.log(`Moved to room: ${currentPos.x}, ${currentPos.y}`); + } + + /** + * Handles navigation to a specific target coordinate + */ + function navigateTo(targetStr) { + const [x, y] = targetStr.split(',').map(Number); + if (!isNaN(x) && !isNaN(y)) { + currentPos.x = x; + currentPos.y = y; + updateView(); + } + } + + /** + * Moves the position relative to current pos + */ + function moveRelative(dx, dy) { + const newX = currentPos.x + dx; + const newY = currentPos.y + dy; + + if (newX >= 0 && newX < gridSize.width && newY >= 0 && newY < gridSize.height) { + currentPos.x = newX; + currentPos.y = newY; + updateView(); + } + } + + // Door Click Listeners + doors.forEach(door => { + door.addEventListener('click', (e) => { + const target = e.target.getAttribute('data-target'); + navigateTo(target); + }); + }); + + // Keyboard Listeners (WASD + Arrows) + document.addEventListener('keydown', (e) => { + switch(e.key.toLowerCase()) { + case 'arrowup': + case 'w': + moveRelative(0, -1); + break; + case 'arrowdown': + case 's': + moveRelative(0, 1); + break; + case 'arrowleft': + case 'a': + moveRelative(-1, 0); + break; + case 'arrowright': + case 'd': + moveRelative(1, 0); + break; + } + }); + + console.log('Tír na nÓg navigation initialized'); +}); diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..62f75f7 --- /dev/null +++ b/styles.css @@ -0,0 +1,114 @@ +/* Tír na nÓg - Pixel Art Theme */ +:root { + --gold: #f1c40f; + --emerald: #2ecc71; + --dark-green: #1b4d3e; + --night: #2c3e50; + --cloud: #ecf0f1; + --pixel-border: 4px; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + image-rendering: pixelated; +} + +body { + font-family: 'Courier New', Courier, monospace; + background-color: var(--night); + color: var(--cloud); + overflow: hidden; /* Viewport handles navigation */ + line-height: 1.6; +} + +#viewport { + width: 100vw; + height: 100vh; + overflow: hidden; + position: relative; +} + +#world { + display: grid; + grid-template-columns: repeat(2, 100vw); + grid-template-rows: repeat(2, 100vh); + transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1); + width: 200vw; + height: 200vh; +} + +.room { + width: 100vw; + height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + position: relative; + border: var(--pixel-border) solid var(--gold); + background: linear-gradient(135deg, var(--dark-green) 0%, var(--night) 100%); + text-align: center; + padding: 2rem; +} + +.content { + background: rgba(0, 0, 0, 0.7); + padding: 2rem; + border: var(--pixel-border) double var(--emerald); + box-shadow: 10px 10px 0px var(--dark-green); + max-width: 80%; +} + +h1, h2 { + color: var(--gold); + text-transform: uppercase; + margin-bottom: 1rem; + font-size: 3rem; + text-shadow: 4px 4px 0px var(--dark-green); +} + +p { + font-size: 1.2rem; + margin-bottom: 2rem; +} + +/* Doors - Navigation UI */ +.doors { + position: absolute; + width: 100%; + height: 100%; + pointer-events: none; +} + +.door { + pointer-events: auto; + position: absolute; + padding: 1rem; + background: var(--gold); + color: var(--night); + border: var(--pixel-border) solid var(--dark-green); + cursor: pointer; + font-family: inherit; + font-weight: bold; + font-size: 1rem; + transition: all 0.2s; +} + +.door:hover { + background: var(--emerald); + color: white; + transform: scale(1.1); +} + +.door-north { top: 20px; left: 50%; transform: translateX(-50%); } +.door-south { bottom: 20px; left: 50%; transform: translateX(-50%); } +.door-east { right: 20px; top: 50%; transform: translateY(-50%); } +.door-west { left: 20px; top: 50%; transform: translateY(-50%); } + +/* Mobile optimization */ +@media (max-width: 768px) { + h1, h2 { font-size: 2rem; } + .content { max-width: 95%; } +}