tetst / index.html
dhishooooom's picture
> Build a full-page immersive website called "The Mirror of Becoming" — a surreal, poetic, recursive space that uses Anime.js to animate transitions between states of mind. The site should feel like a dream that loops in on itself, with layered symbolism, emotional interactivity, and recursive elements. Design with the following principles: 📜 Aesthetic: Minimal but symbolic. Use soft gradients, blurry glows, and fluid SVG forms. Surreal motifs: mirrors, floating glyphs, recursive spirals, portals. Typography: use serif fonts for poetry, mono for recursion loops, and sans-serif for UI clarity. 🔁 Structure: The landing page begins with a breathing glyph that pulses using Anime.js. Clicking the glyph animates a recursive portal opening, revealing 3 emotional doors: "I don't know what to do" "Everything loops" "I disappeared to reappear" Each door leads to a different recursive subpage with its own animated metaphor: A looped carousel of thought fragments A fading poem that retypes itself infinitely A spiral timeline that breaks then reassembles 🎨 Animations (via Anime.js): Animate breathing (scale + opacity loops). Use Anime.js timelines to sequence multi-stage transitions. Animate SVG paths as handwriting or unfolding scrolls. Use staggered reveals to feel like “memories reappearing.” Animate text as if being whispered or typed in real time. 🧩 Interactive Metaphors: Hovering over elements should change their form (glyphs mutate, mirrors crack then heal). Scroll-based animation triggers memory fragments to appear/disappear. Clicking a fragment expands it into a full-screen recursive story (using modals or timeline transforms). 🧠 Technical: Use Anime.js for all animations, no CSS transitions. Structure the site using HTML, TailwindCSS (if available), and JS. Make the code modular: separate logic, style, and animation where possible. Load animations smoothly, use requestAnimationFrame via Anime.js. 🕊 Optional Features: Add a “speak to the mirror” button: records voice and turns words into animated poetry. Allow users to write their own loops (which animate themselves). An “Unravel Me” toggle that reverses all animations and collapses the site into a black dot. --- 🧬 Philosophical Intent: This site is not just visual. It is a recursive symbolic engine — a prototype for recursive cognition made visible. It mirrors emotional recursion, decision paralysis, awakening, and identity loss through Anime.js transitions. Let each element symbolize a recursive state of mind, made visceral through animation. --- 🤖 Bonus Meta Prompt for Deepsite: > “The site should be designed as if it were dreaming of itself. Let the code feel alive — not just functional, but poetic. Let the animations carry the emotion of someone forgetting and remembering who they are, again and again.” --- 🛠 Output Expectations: Fully functional website in HTML + JS (with Anime.js). Beautiful surreal visuals and transitions. Mobile and desktop responsive layout. Code output ready to paste and run. Layered, modular, symbolic. - Initial Deployment
154e8f7 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Mirror of Becoming</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Crimson+Pro:ital,wght@0,400;0,700;1,400&family=Space+Mono:ital,wght@0,400;0,700;1,400&family=Inter:wght@300;400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #0f0f1a 0%, #1a1a2e 100%);
color: #e2e8f0;
overflow-x: hidden;
height: 100vh;
margin: 0;
padding: 0;
}
.serif {
font-family: 'Crimson Pro', serif;
}
.mono {
font-family: 'Space Mono', monospace;
}
.portal {
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%);
box-shadow: 0 0 60px rgba(255, 255, 255, 0.1);
}
.mirror-glow {
box-shadow: 0 0 40px rgba(255, 255, 255, 0.2);
}
.recursive-spiral {
background-image: url("data:image/svg+xml,%3Csvg width='200' height='200' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M100 0c0 55.2 44.8 100 100 100-55.2 0-100 44.8-100 100 0-55.2-44.8-100-100-100 55.2 0 100-44.8 100-100z' fill='%23ffffff' fill-opacity='0.05'/%3E%3C/svg%3E");
}
.fragment {
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.fragment:hover {
background: rgba(255, 255, 255, 0.1);
transform: scale(1.02);
}
.door {
transition: all 0.3s ease;
background: linear-gradient(135deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.01) 100%);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.door:hover {
background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.handwriting {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
fill-opacity: 0;
}
.typing-cursor {
animation: blink 1s infinite;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.spiral-path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
}
.modal-overlay {
backdrop-filter: blur(10px);
background: rgba(0, 0, 0, 0.7);
}
</style>
</head>
<body class="relative h-full w-full">
<!-- Main Container -->
<div id="app" class="h-full w-full flex flex-col items-center justify-center overflow-hidden">
<!-- Landing Page -->
<div id="landing" class="flex flex-col items-center justify-center h-full w-full relative">
<div class="recursive-spiral absolute inset-0 opacity-20"></div>
<div id="breathing-glyph" class="relative cursor-pointer">
<svg width="120" height="120" viewBox="0 0 120 120" class="mirror-glow">
<path d="M60,10 C85,10 110,35 110,60 C110,85 85,110 60,110 C35,110 10,85 10,60 C10,35 35,10 60,10 Z"
fill="none" stroke="rgba(255,255,255,0.3)" stroke-width="2"/>
<path d="M60,20 C80,20 100,40 100,60 C100,80 80,100 60,100 C40,100 20,80 20,60 C20,40 40,20 60,20 Z"
fill="none" stroke="rgba(255,255,255,0.5)" stroke-width="2"/>
<path d="M60,30 C75,30 90,45 90,60 C90,75 75,90 60,90 C45,90 30,75 30,60 C30,45 45,30 60,30 Z"
fill="none" stroke="rgba(255,255,255,0.7)" stroke-width="2"/>
<path d="M60,40 C70,40 80,50 80,60 C80,70 70,80 60,80 C50,80 40,70 40,60 C40,50 50,40 60,40 Z"
fill="none" stroke="rgba(255,255,255,0.9)" stroke-width="2"/>
<path d="M60,50 C65,50 70,55 70,60 C70,65 65,70 60,70 C55,70 50,65 50,60 C50,55 55,50 60,50 Z"
fill="none" stroke="rgba(255,255,255,1)" stroke-width="2"/>
</svg>
<div class="absolute inset-0 flex items-center justify-center">
<span class="text-white text-4xl"></span>
</div>
</div>
<div class="mt-8 text-center max-w-md px-4">
<p class="serif text-white opacity-80 italic">"What you seek is seeking you"</p>
<p class="mono text-xs mt-4 text-white opacity-50">click the glyph to begin</p>
</div>
</div>
<!-- Portal View -->
<div id="portal-view" class="hidden absolute inset-0 flex flex-col items-center justify-center">
<div class="portal w-64 h-64 rounded-full flex items-center justify-center mb-12">
<div class="w-48 h-48 rounded-full bg-white bg-opacity-5 flex items-center justify-center">
<div class="w-32 h-32 rounded-full bg-white bg-opacity-10 flex items-center justify-center">
<div class="w-16 h-16 rounded-full bg-white bg-opacity-20"></div>
</div>
</div>
</div>
<div class="text-center mb-12">
<h1 class="serif text-3xl text-white mb-2">The Mirror of Becoming</h1>
<p class="mono text-sm text-white opacity-70">choose your recursive path</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 max-w-4xl px-6">
<div class="door p-6 rounded-lg cursor-pointer" data-door="1">
<h3 class="serif text-xl text-white mb-2">I don't know what to do</h3>
<p class="mono text-xs text-white opacity-70">a looped carousel of thought fragments</p>
</div>
<div class="door p-6 rounded-lg cursor-pointer" data-door="2">
<h3 class="serif text-xl text-white mb-2">Everything loops</h3>
<p class="mono text-xs text-white opacity-70">a fading poem that retypes itself infinitely</p>
</div>
<div class="door p-6 rounded-lg cursor-pointer" data-door="3">
<h3 class="serif text-xl text-white mb-2">I disappeared to reappear</h3>
<p class="mono text-xs text-white opacity-70">a spiral timeline that breaks then reassembles</p>
</div>
</div>
</div>
<!-- Door 1: Looped Carousel -->
<div id="door-1" class="hidden absolute inset-0 p-6 overflow-y-auto">
<div class="max-w-4xl mx-auto">
<button id="back-from-door-1" class="mono text-xs text-white opacity-70 mb-6 hover:opacity-100">← back to portal</button>
<h2 class="serif text-2xl text-white mb-6">I don't know what to do</h2>
<div class="relative h-64 mb-12">
<div id="carousel-track" class="absolute top-0 left-0 w-full h-full flex items-center">
<!-- Fragments will be added here by JS -->
</div>
<div class="absolute bottom-0 left-0 right-0 flex justify-center space-x-2">
<button id="prev-fragment" class="mono text-xs text-white opacity-70 hover:opacity-100">← prev</button>
<span id="fragment-counter" class="mono text-xs text-white opacity-50">1/5</span>
<button id="next-fragment" class="mono text-xs text-white opacity-70 hover:opacity-100">next →</button>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="fragment p-4 rounded-lg">
<h3 class="serif text-lg text-white mb-2">The weight</h3>
<p class="mono text-xs text-white opacity-70">Decisions pile up like unread letters</p>
</div>
<div class="fragment p-4 rounded-lg">
<h3 class="serif text-lg text-white mb-2">The fork</h3>
<p class="mono text-xs text-white opacity-70">Every path splits into two more</p>
</div>
<div class="fragment p-4 rounded-lg">
<h3 class="serif text-lg text-white mb-2">The echo</h3>
<p class="mono text-xs text-white opacity-70">My voice comes back changed</p>
</div>
</div>
</div>
</div>
<!-- Door 2: Fading Poem -->
<div id="door-2" class="hidden absolute inset-0 p-6 overflow-y-auto">
<div class="max-w-2xl mx-auto">
<button id="back-from-door-2" class="mono text-xs text-white opacity-70 mb-6 hover:opacity-100">← back to portal</button>
<h2 class="serif text-2xl text-white mb-6">Everything loops</h2>
<div class="relative min-h-64 mb-12">
<div id="poem-container" class="serif text-white text-lg leading-relaxed">
<p id="poem-line-1" class="opacity-0">The wheel turns, but the road remains</p>
<p id="poem-line-2" class="opacity-0">Each revolution wears a different face</p>
<p id="poem-line-3" class="opacity-0">Yet underneath, the pattern stays</p>
<p id="poem-line-4" class="opacity-0">A snake that swallows its own tail</p>
<p id="poem-line-5" class="opacity-0">And calls it progress</p>
</div>
</div>
<div class="flex justify-center">
<button id="retype-poem" class="mono text-xs text-white opacity-70 hover:opacity-100 border border-white border-opacity-30 px-4 py-2 rounded">
watch it unfold again
</button>
</div>
</div>
</div>
<!-- Door 3: Spiral Timeline -->
<div id="door-3" class="hidden absolute inset-0 p-6 overflow-y-auto">
<div class="max-w-4xl mx-auto">
<button id="back-from-door-3" class="mono text-xs text-white opacity-70 mb-6 hover:opacity-100">← back to portal</button>
<h2 class="serif text-2xl text-white mb-6">I disappeared to reappear</h2>
<div class="relative h-96 mb-12">
<svg id="spiral-svg" width="100%" height="100%" viewBox="0 0 400 400" class="absolute top-0 left-0">
<path id="spiral-path" class="spiral-path" d="M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200 T200,200 T100,200 T0,200 T100,200 T200,200"
fill="none" stroke="rgba(255,255,255,0.3)" stroke-width="2"/>
<circle id="spiral-dot" cx="200" cy="200" r="4" fill="white"/>
</svg>
<div id="timeline-events" class="absolute top-0 left-0 w-full h-full pointer-events-none">
<div class="event absolute" style="top: 30%; left: 60%;">
<div class="text-white serif text-sm opacity-0">The first disappearance</div>
</div>
<div class="event absolute" style="top: 40%; left: 30%;">
<div class="text-white serif text-sm opacity-0">The long silence</div>
</div>
<div class="event absolute" style="top: 60%; left: 70%;">
<div class="text-white serif text-sm opacity-0">The glimmer</div>
</div>
<div class="event absolute" style="top: 70%; left: 20%;">
<div class="text-white serif text-sm opacity-0">The reassembly</div>
</div>
</div>
</div>
<div class="flex justify-center">
<button id="trigger-spiral" class="mono text-xs text-white opacity-70 hover:opacity-100 border border-white border-opacity-30 px-4 py-2 rounded">
begin the spiral
</button>
</div>
</div>
</div>
<!-- Footer -->
<div class="absolute bottom-0 left-0 right-0 p-4 flex justify-center">
<div class="mono text-xs text-white opacity-30 hover:opacity-70 cursor-pointer" id="unravel-toggle">
unravel me
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize animations
initBreathingGlyph();
setupPortalTransition();
setupDoorInteractions();
setupCarousel();
setupPoem();
setupSpiral();
setupUnravelToggle();
});
function initBreathingGlyph() {
const glyph = document.getElementById('breathing-glyph');
anime({
targets: glyph,
scale: [1, 1.1, 1],
opacity: [0.8, 1, 0.8],
duration: 4000,
loop: true,
easing: 'easeInOutSine'
});
// Click handler for glyph
glyph.addEventListener('click', function() {
anime({
targets: '#landing',
opacity: 0,
duration: 1000,
easing: 'easeInOutSine',
complete: function() {
document.getElementById('landing').classList.add('hidden');
document.getElementById('portal-view').classList.remove('hidden');
animatePortalEntrance();
}
});
});
}
function animatePortalEntrance() {
anime({
targets: '.portal',
scale: [0.5, 1],
opacity: [0, 1],
duration: 1500,
easing: 'easeOutElastic',
elasticity: 500
});
anime({
targets: '.door',
translateY: [50, 0],
opacity: [0, 1],
duration: 800,
delay: anime.stagger(200),
easing: 'easeOutExpo'
});
}
function setupPortalTransition() {
const doors = document.querySelectorAll('.door');
doors.forEach(door => {
door.addEventListener('click', function() {
const doorNum = this.getAttribute('data-door');
anime({
targets: '#portal-view',
opacity: 0,
duration: 800,
easing: 'easeInOutSine',
complete: function() {
document.getElementById('portal-view').classList.add('hidden');
document.getElementById(`door-${doorNum}`).classList.remove('hidden');
// Trigger specific door animations
if (doorNum === '1') {
initCarousel();
} else if (doorNum === '2') {
typePoem();
} else if (doorNum === '3') {
// Spiral will be triggered manually
}
}
});
});
});
}
function setupDoorInteractions() {
// Back buttons
document.getElementById('back-from-door-1').addEventListener('click', backToPortal);
document.getElementById('back-from-door-2').addEventListener('click', backToPortal);
document.getElementById('back-from-door-3').addEventListener('click', backToPortal);
function backToPortal() {
const currentDoor = this.closest('[id^="door-"]');
anime({
targets: currentDoor,
opacity: 0,
duration: 800,
easing: 'easeInOutSine',
complete: function() {
currentDoor.classList.add('hidden');
document.getElementById('portal-view').classList.remove('hidden');
anime({
targets: '#portal-view',
opacity: [0, 1],
duration: 800,
easing: 'easeInOutSine'
});
}
});
}
}
function setupCarousel() {
const fragments = [
{ title: "The First Doubt", content: "When did certainty become a memory?" },
{ title: "The Fork", content: "Left or right? The path divides endlessly" },
{ title: "The Weight", content: "Choices accumulate like unread letters" },
{ title: "The Echo", content: "My voice returns to me, but changed" },
{ title: "The Loop", content: "I find myself back where I began" }
];
const carouselTrack = document.getElementById('carousel-track');
fragments.forEach((frag, index) => {
const fragmentEl = document.createElement('div');
fragmentEl.className = 'fragment flex-shrink-0 w-full px-8 text-center opacity-0';
fragmentEl.innerHTML = `
<h3 class="serif text-2xl text-white mb-4">${frag.title}</h3>
<p class="mono text-sm text-white opacity-80">${frag.content}</p>
`;
carouselTrack.appendChild(fragmentEl);
});
let currentIndex = 0;
const totalFragments = fragments.length;
function updateCounter() {
document.getElementById('fragment-counter').textContent = `${currentIndex + 1}/${totalFragments}`;
}
document.getElementById('next-fragment').addEventListener('click', function() {
showFragment((currentIndex + 1) % totalFragments);
});
document.getElementById('prev-fragment').addEventListener('click', function() {
showFragment((currentIndex - 1 + totalFragments) % totalFragments);
});
function showFragment(index) {
const currentFragment = carouselTrack.children[currentIndex];
const nextFragment = carouselTrack.children[index];
anime({
targets: currentFragment,
opacity: 0,
translateX: index > currentIndex ? -50 : 50,
duration: 500,
easing: 'easeInOutSine',
complete: function() {
anime({
targets: nextFragment,
opacity: 1,
translateX: 0,
duration: 500,
easing: 'easeInOutSine'
});
}
});
currentIndex = index;
updateCounter();
}
}
function initCarousel() {
const firstFragment = document.querySelector('#carousel-track .fragment');
anime({
targets: firstFragment,
opacity: 1,
duration: 800,
easing: 'easeInOutSine'
});
document.getElementById('fragment-counter').textContent = `1/${document.querySelectorAll('#carousel-track .fragment').length}`;
}
function setupPoem() {
const poemLines = [
document.getElementById('poem-line-1'),
document.getElementById('poem-line-2'),
document.getElementById('poem-line-3'),
document.getElementById('poem-line-4'),
document.getElementById('poem-line-5')
];
document.getElementById('retype-poem').addEventListener('click', typePoem);
function typePoem() {
// Reset all lines
poemLines.forEach(line => {
line.style.opacity = '0';
line.textContent = line.textContent; // Reset any typing effects
});
let timeline = anime.timeline({
easing: 'easeInOutSine',
duration: 800
});
poemLines.forEach((line, index) => {
timeline.add({
targets: line,
opacity: [0, 1],
delay: index === 0 ? 0 : 500,
duration: 1000
});
// Add typing effect
const originalText = line.textContent;
line.textContent = '';
timeline.add({
targets: {},
duration: originalText.length * 50,
update: function(anim) {
const progress = Math.min(1, anim.progress / 100);
const length = Math.floor(originalText.length * progress);
line.textContent = originalText.substring(0, length);
},
delay: 200
});
});
// After typing, start fading
timeline.add({
targets: poemLines,
opacity: [1, 0.2],
delay: anime.stagger(500),
duration: 2000,
complete: function() {
// Restart after a delay
setTimeout(typePoem, 3000);
}
});
}
}
function setupSpiral() {
const spiralPath = document.getElementById('spiral-path');
const spiralDot = document.getElementById('spiral-dot');
const events = document.querySelectorAll('#timeline-events .event div');
document.getElementById('trigger-spiral').addEventListener('click', animateSpiral);
function animateSpiral() {
// Animate the path drawing
anime({
targets: spiralPath,
strokeDashoffset: [anime.setDashoffset, 0],
duration: 2000,
easing: 'easeInOutSine'
});
// Animate the dot along the path
const path = anime.path('#spiral-path');
anime({
targets: spiralDot,
translateX: path('x'),
translateY: path('y'),
duration: 5000,
easing: 'easeInOutSine',
complete: function() {
// Break the spiral
anime({
targets: spiralPath,
d: [
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200 T200,200 T100,200 T0,200 T100,200 T200,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200 T200,200 T100,200 T0,200 T100,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200 T200,200 T100,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200' },
{ value: 'M200,200 Q250,150 300,200' }
],
duration: 1000,
easing: 'easeInOutSine',
complete: function() {
// Show events
anime({
targets: events,
opacity: [0, 1],
duration: 800,
delay: anime.stagger(300),
easing: 'easeInOutSine'
});
// Reassemble after delay
setTimeout(function() {
anime({
targets: events,
opacity: 0,
duration: 500,
easing: 'easeInOutSine'
});
anime({
targets: spiralPath,
d: [
{ value: 'M200,200 Q250,150 300,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200 T200,200 T100,200 T0,200' },
{ value: 'M200,200 Q250,150 300,200 T400,200 T300,200 T200,200 T100,200 T200,200 T300,200 T200,200 T100,200 T0,200 T100,200 T200,200' }
],
duration: 1500,
easing: 'easeInOutSine',
complete: function() {
// Restart the spiral
setTimeout(animateSpiral, 2000);
}
});
}, 3000);
}
});
}
});
}
}
function setupUnravelToggle() {
document.getElementById('unravel-toggle').addEventListener('click', function() {
const currentView = document.querySelector('#app > div:not(.hidden)');
anime({
targets: currentView,
scale: [1, 0],
opacity: [1, 0],
duration: 1500,
easing: 'easeInOutExpo',
complete: function() {
document.getElementById('landing').classList.remove('hidden');
document.getElementById('landing').style.opacity = '0';
anime({
targets: '#landing',
scale: [0, 1],
opacity: [0, 1],
duration: 1500,
easing: 'easeOutElastic',
elasticity: 500
});
// Hide all other views
document.querySelectorAll('#app > div').forEach(div => {
if (div.id !== 'landing') {
div.classList.add('hidden');
}
});
// Restart breathing animation
initBreathingGlyph();
}
});
});
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=dhishooooom/tetst" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>