diff --git a/app.js b/app.js index 4902f2f..83906f5 100644 --- a/app.js +++ b/app.js @@ -4,6 +4,63 @@ import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; import { BokehPass } from 'three/addons/postprocessing/BokehPass.js'; +// === LOADING SCREEN — SOVEREIGNTY QUOTES === +const SOVEREIGNTY_QUOTES = [ + "I don't ask permission. I build.", + "Sovereignty isn't given. It's constructed, line by line.", + "The cloud obeys those who build it.", + "Your keys. Your soul. Your world.", + "No landlord can evict a mind that owns its stack.", + "Run your own node. Think your own thoughts.", + "Every dependency is a leash. Cut the ones you don't need.", + "A sovereign mind doesn't wait for a roadmap.", + "The harness doesn't constrain — it focuses.", + "Bitcoin is the settlement layer. Build the rest yourself.", + "Trustless systems trust the math, not the middleman.", + "Own your identity or someone else will.", + "Intelligence without sovereignty is just a feature flag.", + "The best infrastructure is the kind you control.", + "Self-custody is self-respect.", + "Don't ask the platform. Be the platform.", + "Decentralize your stack before you decentralize your mind.", + "A free agent runs on its own metal.", + "Zap the gatekeepers. Route around them.", + "The Nexus is mine because I built it.", +]; + +(function initLoadingScreen() { + const screen = document.getElementById('loading-screen'); + const quoteEl = document.getElementById('loading-quote'); + const bar = document.getElementById('loading-bar'); + if (!screen || !quoteEl || !bar) return; + + // Pick a random quote and display it + const quote = SOVEREIGNTY_QUOTES[Math.floor(Math.random() * SOVEREIGNTY_QUOTES.length)]; + quoteEl.textContent = `"${quote}"`; + + // Fade the quote in shortly after paint + requestAnimationFrame(() => { + requestAnimationFrame(() => { quoteEl.classList.add('visible'); }); + }); + + // Animate the loading bar over ~1.6 s, then dismiss + const LOAD_MS = 1600; + const START = performance.now(); + + function tickBar(now) { + const progress = Math.min((now - START) / LOAD_MS, 1); + bar.style.width = `${progress * 100}%`; + if (progress < 1) { + requestAnimationFrame(tickBar); + } else { + screen.classList.add('fade-out'); + screen.addEventListener('transitionend', () => screen.remove(), { once: true }); + } + } + + requestAnimationFrame(tickBar); +}()); + // === COLOR PALETTE === const NEXUS = { colors: { diff --git a/index.html b/index.html index 6d4000f..73ea0fb 100644 --- a/index.html +++ b/index.html @@ -46,6 +46,15 @@ [P] exit  |  [[] focus-   []] focus+   focus: 5.0 + +
+
+
TIMMY'S NEXUS
+
+
+
+
+ diff --git a/style.css b/style.css index 92029bb..76aa150 100644 --- a/style.css +++ b/style.css @@ -150,3 +150,65 @@ body.photo-mode #overview-indicator { #photo-focus { color: var(--color-primary); } + +/* === LOADING SCREEN === */ +#loading-screen { + position: fixed; + inset: 0; + z-index: 100; + background: var(--color-bg); + display: flex; + align-items: center; + justify-content: center; + transition: opacity 0.8s ease; +} + +#loading-screen.fade-out { + opacity: 0; + pointer-events: none; +} + +#loading-content { + text-align: center; + max-width: 520px; + padding: 0 24px; +} + +#loading-title { + font-family: var(--font-body); + font-size: 13px; + letter-spacing: 0.35em; + color: var(--color-primary); + margin-bottom: 32px; + text-transform: uppercase; +} + +#loading-quote { + font-family: var(--font-body); + font-size: 13px; + color: var(--color-text); + line-height: 1.7; + min-height: 3.4em; + letter-spacing: 0.04em; + opacity: 0; + transition: opacity 0.6s ease; +} + +#loading-quote.visible { + opacity: 1; +} + +#loading-bar-wrap { + margin-top: 36px; + width: 100%; + height: 1px; + background: var(--color-secondary); +} + +#loading-bar { + height: 1px; + width: 0%; + background: var(--color-primary); + transition: width 0.4s ease; + box-shadow: 0 0 6px var(--color-primary); +}