Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. <html> <style> @font-face { font-family: 'Forevs'; src: url('/wiki/lib/tpl/bootstrap3/fonts/ForevsDemo-Regular.otf') format('opentype'); font-weight: normal; } @font-face { font-family: 'Forevs'; src: url('/wiki/lib/tpl/bootstrap3/fonts/ForevsDemo-Bold.otf') format('opentype'); font-weight: bold; } /* Grid fills full viewport — navbar floats over it */ .js-wrap { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 999; display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(2, 50vh); gap: 4px; background: #120F29; } /* Scanline overlay */ .js-wrap::after { content: ''; position: absolute; inset: 0; z-index: 100; pointer-events: none; background: repeating-linear-gradient( to bottom, rgba(0,0,0,0.03) 0px, rgba(0,0,0,0.03) 1px, transparent 1px, transparent 3px ); } /* Edge vignette */ .js-wrap::before { content: ''; position: absolute; inset: 0; z-index: 101; pointer-events: none; background: linear-gradient(to right, rgba(10,6,26,0.7) 0%, transparent 12%, transparent 88%, rgba(10,6,26,0.7) 100%), linear-gradient(to bottom, rgba(10,6,26,0.7) 0%, transparent 12%, transparent 88%, rgba(10,6,26,0.7) 100%); } .js-card { position: relative; display: block; overflow: hidden; text-decoration: none; } .js-card video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; transform: scale(1); filter: brightness(0.6) saturate(0.8); transition: transform 0.6s ease, filter 0.6s ease; } .js-card:hover video { transform: scale(1.02); filter: brightness(1) saturate(1.1); } .js-overlay { position: absolute; inset: 0; z-index: 2; background: linear-gradient(to bottom, rgba(26,20,51,0.0) 0%, rgba(26,20,51,0.85) 100%); transition: opacity 0.4s ease; } .js-card:hover .js-overlay { opacity: 0.3; } .js-label { position: absolute; left: 0; width: 100%; z-index: 3; padding: 16px; font-family: 'Forevs', serif; font-size: 2.7em; color: rgba(237,232,245,0.85); letter-spacing: 6px; text-align: center; text-transform: uppercase; text-shadow: 0 1px 0 rgba(0,0,0,0.9), 0 -1px 0 rgba(255,255,255,0.05); top: 50%; transform: translateY(-50%); transition: top 0.35s ease, transform 0.35s ease, letter-spacing 0.4s ease, color 0.4s ease, text-shadow 0.4s ease, opacity 0.4s ease; opacity: 0.7; } .js-card:hover .js-label { top: 88%; transform: translateY(-50%); letter-spacing: 10px; color: #ffffff; opacity: 1; text-shadow: 0 0 1px rgba(255,255,255,0.9), 0 0 2px rgba(255,255,255,0.5), 1px 1px 0 rgba(0,0,0,1), -1px -1px 0 rgba(0,0,0,1), 1px -1px 0 rgba(0,0,0,1), -1px 1px 0 rgba(0,0,0,1), 0 2px 8px rgba(0,0,0,0.9), inset 0 0 0 1px rgba(255,255,255,0.1); filter: contrast(1.2) brightness(1.1); } /* Dark vignette behind title */ .js-title-bg { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 1100px; height: 550px; z-index: 1000; pointer-events: none; background: radial-gradient(ellipse at center, rgba(10,6,26,0.92) 0%, rgba(10,6,26,0.6) 45%, transparent 70%); animation: fadeIn 0.8s ease 0.2s both; } /* Title — centered in full viewport */ .js-title { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 1002; pointer-events: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; animation: floatY 4s ease-in-out infinite; } @keyframes floatY { 0%, 100% { transform: translateY(0px); } 50% { transform: translateY(-8px); } } .js-title-sub { font-family: 'Forevs', serif; font-weight: normal; font-size: 3.2em; letter-spacing: 10px; text-transform: uppercase; color: rgba(184,173,219,0.9); text-shadow: 0 2px 10px rgba(0,0,0,0.9); animation: revealUp 0.8s cubic-bezier(0.16,1,0.3,1) 0.6s both; } .js-title-main { font-family: 'Forevs', serif; font-weight: bold; font-size: 8.2em; letter-spacing: 8px; text-transform: uppercase; color: #EDE8F5; line-height: 1; text-shadow: 0 0 60px rgba(107,79,187,0.9), 0 0 20px rgba(107,79,187,0.5), 0 4px 15px rgba(0,0,0,0.9); animation: revealUp 0.9s cubic-bezier(0.16,1,0.3,1) 0.3s both, glowPulse 4s 1.5s ease-in-out infinite; } .js-title-divider { display: flex; align-items: center; gap: 10px; margin-top: 4px; animation: fadeIn 0.6s ease 1s both; } .js-title-divider-line { height: 1px; width: 100px; background: linear-gradient(to right, transparent, rgba(184,173,219,0.6), transparent); } .js-title-divider-diamond { width: 5px; height: 5px; background: rgba(184,173,219,0.9); transform: rotate(45deg); box-shadow: 0 0 6px rgba(184,173,219,0.8); } /* Particle canvas — full viewport */ #js-particles { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 1001; pointer-events: none; } @keyframes revealUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes glowPulse { 0%, 100% { text-shadow: 0 0 60px rgba(107,79,187,0.9), 0 0 20px rgba(107,79,187,0.5), 0 4px 15px rgba(0,0,0,0.9); } 50% { text-shadow: 0 0 90px rgba(107,79,187,1), 0 0 40px rgba(184,173,219,0.5), 0 4px 15px rgba(0,0,0,0.9); } } @keyframes fadeUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } } .js-card:nth-child(1) { animation: fadeUp 0.6s 0.15s ease both; } .js-card:nth-child(2) { animation: fadeUp 0.6s 0.25s ease both; } .js-card:nth-child(3) { animation: fadeUp 0.6s 0.35s ease both; } .js-card:nth-child(4) { animation: fadeUp 0.6s 0.45s ease both; } /* VHS chromatic aberration — JS controlled */ .js-card { position: relative; display: block; overflow: hidden; text-decoration: none; transition: filter 0.25s ease !important; } .js-card.js-fading { filter: saturate(0.55) brightness(0.92) !important; } /* Scanline overlay on fading cards */ .js-card.js-fading::after { content: '' !important; position: absolute !important; inset: 0 !important; z-index: 12 !important; pointer-events: none !important; background: repeating-linear-gradient( 0deg, transparent 0px, transparent 3px, rgba(0, 0, 0, 0.08) 3px, rgba(0, 0, 0, 0.08) 4px ) !important; } /* RGB canvas overlay */ .js-rgb-canvas { position: absolute; inset: 0; z-index: 11; pointer-events: none; opacity: 0; transition: opacity 0.6s ease; } .js-card.js-fading .js-rgb-canvas { opacity: 1; } /* Block card hover effects when title zone is active */ .js-wrap.js-title-active .js-card:hover video { transform: scale(1) !important; filter: brightness(0.6) saturate(0.8) !important; } .js-wrap.js-title-active .js-card:hover .js-overlay { opacity: 1 !important; } .js-wrap.js-title-active .js-card:hover .js-label { top: 50% !important; transform: translateY(-50%) !important; letter-spacing: 4px !important; color: #EDE8F5 !important; text-shadow: 0 1px 0 rgba(0,0,0,0.9), 0 -1px 0 rgba(255,255,255,0.05) !important; opacity: 0.7 !important; } .js-wrap.js-title-active .js-card:hover .js-label::before { transform: translateX(-50%) scaleX(0) !important; } .js-wrap.js-title-active .js-card:hover .js-label::after { opacity: 0 !important; } /* Etched label underline */ .js-label::before { content: ''; position: absolute; bottom: 6px; left: 50%; transform: translateX(-50%) scaleX(0); width: 80%; height: 1px; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent); transition: transform 0.4s ease; } .js-card:hover .js-label::before { transform: translateX(-50%) scaleX(1); } /* Film grain overlay on label hover */ .js-label::after { content: ''; position: absolute; inset: 0; background: repeating-linear-gradient( 0deg, transparent, transparent 2px, rgba(0,0,0,0.08) 2px, rgba(0,0,0,0.08) 3px ); pointer-events: none; opacity: 0; transition: opacity 0.4s ease; } .js-card:hover .js-label::after { opacity: 1; } </style> <div class="js-title-bg"></div> <div class="js-title"> <div class="js-title-sub">Movement Wiki</div> <div class="js-title-main">JumpStart</div> <div class="js-title-divider"> <div class="js-title-divider-line"></div> <div class="js-title-divider-diamond"></div> <div class="js-title-divider-line"></div> </div> </div> <canvas id="js-particles"></canvas> <div class="js-wrap"> <a href="/wiki/doku.php?id=guides:start" class="js-card"> <video loop muted playsinline autoplay> <source src="/wiki/lib/exe/fetch.php?media=0%3Awiki1.mp4" type="video/mp4"> </video> <div class="js-overlay"></div> <div class="js-label">Guides</div> </a> <a href="/wiki/doku.php?id=characters:start" class="js-card"> <video loop muted playsinline autoplay> <source src="/wiki/lib/exe/fetch.php?media=0%3Awiki2.mp4" type="video/mp4"> </video> <div class="js-overlay"></div> <div class="js-label">Characters</div> </a> <a href="/wiki/doku.php?id=universaltech:start" class="js-card"> <video loop muted playsinline autoplay> <source src="/wiki/lib/exe/fetch.php?media=0%3Awiki3.mp4" type="video/mp4"> </video> <div class="js-overlay"></div> <div class="js-label">Universal Tech</div> </a> <a href="/wiki/doku.php?id=items:start" class="js-card"> <video loop muted playsinline autoplay> <source src="/wiki/lib/exe/fetch.php?media=0%3Awiki4.mp4" type="video/mp4"> </video> <div class="js-overlay"></div> <div class="js-label">Items & Abilities</div> </a> </div> <script> const canvas = document.getElementById('js-particles'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; const cx = canvas.width / 2; const cy = canvas.height / 2; const particles = []; function randomRange(a, b) { return a + Math.random() * (b - a); } for (let i = 0; i < 60; i++) { particles.push({ x: cx + randomRange(-180, 180), y: cy + randomRange(-80, 80), vx: randomRange(-0.3, 0.3), vy: randomRange(-0.8, -0.2), size: randomRange(1, 2.5), alpha: randomRange(0.4, 1), fade: randomRange(0.003, 0.008), color: Math.random() > 0.5 ? '184,173,219' : '107,79,187' }); } function resetParticle(p) { p.x = cx + randomRange(-180, 180); p.y = cy + randomRange(-80, 80); p.vx = randomRange(-0.3, 0.3); p.vy = randomRange(-0.8, -0.2); p.alpha = randomRange(0.4, 1); p.size = randomRange(1, 2.5); p.fade = randomRange(0.003, 0.008); } function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach(p => { p.x += p.vx; p.y += p.vy; p.alpha -= p.fade; if (p.alpha <= 0) resetParticle(p); ctx.beginPath(); ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); ctx.fillStyle = `rgba(${p.color},${p.alpha})`; ctx.fill(); }); requestAnimationFrame(draw); } draw(); window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }); </script> <script> // VHS RGB chromatic aberration using canvas (function() { const cards = document.querySelectorAll('.js-card'); const wrap = document.querySelector('.js-wrap'); const titleEl = document.querySelector('.js-title-main'); let activeCard = null; let fadeTimeout = null; const canvases = new Map(); const animFrames = new Map(); // Create a canvas overlay for each card cards.forEach(card => { const canvas = document.createElement('canvas'); canvas.className = 'js-rgb-canvas'; card.appendChild(canvas); canvases.set(card, canvas); }); function drawRGB(card) { const canvas = canvases.get(card); const video = card.querySelector('video'); if (!video || !canvas) return; const w = card.offsetWidth; const h = card.offsetHeight; canvas.width = w; canvas.height = h; const ctx = canvas.getContext('2d'); function frame() { if (!card.classList.contains('js-fading')) { ctx.clearRect(0, 0, w, h); animFrames.delete(card); return; } ctx.clearRect(0, 0, w, h); ctx.save(); ctx.globalCompositeOperation = 'screen'; ctx.globalAlpha = 0.18; ctx.filter = 'saturate(4) hue-rotate(-20deg)'; ctx.drawImage(video, 4, 0, w, h); ctx.restore(); ctx.save(); ctx.globalCompositeOperation = 'screen'; ctx.globalAlpha = 0.14; ctx.filter = 'saturate(4) hue-rotate(160deg)'; ctx.drawImage(video, -4, 0, w, h); ctx.restore(); animFrames.set(card, requestAnimationFrame(frame)); } if (!animFrames.has(card)) { animFrames.set(card, requestAnimationFrame(frame)); } } function isTitleZone(e) { const sub = document.querySelector('.js-title-sub'); const main = document.querySelector('.js-title-main'); const divider = document.querySelector('.js-title-divider'); if (!sub || !main) return false; const top = sub.getBoundingClientRect().top - 20; const bottom = (divider || main).getBoundingClientRect().bottom + 20; const left = main.getBoundingClientRect().left - 40; const right = main.getBoundingClientRect().right + 40; return e.clientX >= left && e.clientX <= right && e.clientY >= top && e.clientY <= bottom; } function setTitleGlow(on) { if (!titleEl) return; if (on) { titleEl.style.transition = 'text-shadow 0.3s ease'; titleEl.style.textShadow = '0 0 120px rgba(184,173,219,1), 0 0 60px rgba(107,79,187,1), 0 0 25px rgba(255,255,255,0.8), 0 4px 15px rgba(0,0,0,0.9)'; titleEl.style.color = '#ffffff'; } else { titleEl.style.transition = 'text-shadow 0.3s ease, color 0.3s ease'; titleEl.style.textShadow = ''; titleEl.style.color = ''; } } function setFading(hoveredCard) { if (activeCard === hoveredCard) return; activeCard = hoveredCard; setTitleGlow(false); wrap.classList.remove('js-title-active'); cards.forEach(card => { if (card !== hoveredCard) { card.classList.add('js-fading'); drawRGB(card); } else { card.classList.remove('js-fading'); } }); } function clearFading() { activeCard = null; setTitleGlow(false); wrap.classList.remove('js-title-active'); cards.forEach(card => card.classList.remove('js-fading')); } function enterTitleZone() { activeCard = 'title'; setTitleGlow(true); wrap.classList.add('js-title-active'); cards.forEach(card => card.classList.remove('js-fading')); } wrap.addEventListener('mousemove', function(e) { if (isTitleZone(e)) { clearTimeout(fadeTimeout); if (activeCard !== 'title') enterTitleZone(); return; } // Find which card the mouse is over let overCard = null; cards.forEach(card => { const rect = card.getBoundingClientRect(); if (e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom) { overCard = card; } }); if (overCard) { clearTimeout(fadeTimeout); setFading(overCard); } }); wrap.addEventListener('mouseleave', function() { clearTimeout(fadeTimeout); fadeTimeout = setTimeout(clearFading, 150); }); })(); </script> </html> start.txt Last modified: 2026/06/11 21:28by jumpstartadmin