Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
Loading…
trippy.ch<div class="trippy-intro">
You stand at the edge of everything you know. The air hums with a frequency you can almost taste. Before you, a shimmering portal spirals — fractal tendrils reaching outward, folding into themselves, breathing.
</div>
The <span class="glow">void calls</span>. Do you choose your path... or let fate decide?
<div id="start-fate-dice" class="dice-container-start">
<div class="void-die-3d void-die-small" style="transform: rotateX(-15deg) rotateY(25deg);">
<div class="die-face die-face-front" data-passage="Portal"><span>⟡</span></div>
<div class="die-face die-face-back" data-passage="Listen"><span>🔊</span></div>
<div class="die-face die-face-top" data-passage="Hands"><span>✋</span></div>
<div class="die-face die-face-bottom" data-passage="FateRoll"><span>?</span></div>
<div class="die-face die-face-left" data-passage="Portal"><span>⚡</span></div>
<div class="die-face die-face-right" data-passage="Listen"><span>💫</span></div>
</div>
</div>
<<script>>
(function(){
var die = document.querySelector('.void-die-small');
if(!die) return;
die.addEventListener('click', function(e){
e.stopPropagation();
if(die.classList.contains('rolling')) return;
die.classList.add('rolling');
die.style.animationDuration = '1s';
setTimeout(function(){
die.classList.remove('rolling');
var faces = die.querySelectorAll('.die-face');
var result = faces[Math.floor(Math.random() * faces.length)];
var targetPassage = result.getAttribute('data-passage');
faces.forEach(function(f){ f.classList.remove('die-selected'); });
result.classList.add('die-selected');
setTimeout(function(){
Engine.play(targetPassage);
}, 900);
}, 1400);
});
})();
<</script>>
<div class="trippy-scene" style="margin: 1.2em 0; text-align: center; font-size: 0.85em;">
<span class="glow">Tap the floating die to let fate choose.</span><br><small>or make your own choice below:</small>
</div>
[[Step through the portal -> Portal]]
[[Listen to the hum -> Listen]]
[[Look down at your hands -> Hands]]<div class="trippy-scene portal">
Colors you've never seen bloom behind your eyelids. You're falling — no, floating — through a tunnel of impossible geometry. Angles that shouldn't exist fold around you like origami made of light.
</div>
Ahead, three doors materialize from the void. Each hums at a different frequency. <span class="glow">Choose one to open.</span>
<div id="void-doors">
<div class="void-door" data-target="VioletPath">
<div class="void-door-frame">
<div class="void-door-lightning"></div>
<div class="void-door-handle">⚡</div>
</div>
<span class="void-door-label">Lightning</span>
</div>
<div class="void-door" data-target="GoldPath">
<div class="void-door-frame">
<div class="void-door-gold"></div>
<div class="void-door-handle">🌊</div>
</div>
<span class="void-door-label">Flow</span>
</div>
<div class="void-door" data-target="CrystalPath">
<div class="void-door-frame">
<div class="void-door-crystal"></div>
<div class="void-door-handle">💎</div>
</div>
<span class="void-door-label">Crystal</span>
</div>
</div>
<<script>>
(function(){
var doors = document.querySelectorAll('.void-door');
doors.forEach(function(d){
d.addEventListener('click', function(){
doors.forEach(function(dd){
dd.classList.remove('void-door-chosen');
dd.classList.add('void-door-faded');
});
d.classList.remove('void-door-faded');
d.classList.add('void-door-chosen');
setTimeout(function(){
Engine.play(d.getAttribute('data-target'));
}, 800);
});
});
})();
<</script>>You close your eyes and let the sound wash over you. It's not one hum — it's thousands, layered like sedimentary time. Each frequency is a memory, a dream, a universe that almost existed.
<div class="trippy-reveal">
The hum reveals something: <em>this isn't your first time here.</em>
</div>
[[Open your eyes->EyesOpen]]
[[Sink deeper into the sound->DeeperSound]]You look down. Your fingers are trailing light — soft, iridescent threads that dissolve into the air like smoke. Each strand connects to something unseen, somewhere else.
<div class="trippy-scene hands">
Your palms hold a faint map — constellations of freckles you never noticed before. They're moving. Slowly rearranging. A message? A warning? A invitation?
</div>
[[Trace the constellation on your left palm->TraceLeft]]
[[Reach into the threads trailing from your fingers->ReachThreads]]
[[Look back up at the portal->Start]]The world has changed. Or rather — you've finally seen it as it is. The ground beneath you is transparent, revealing an infinite lattice of glowing nodes connected by threads of pure intention. You are standing on a network of consciousness.
Every step you take sends ripples through the lattice. Every ripple triggers a cascade of color.
<div class="trippy-reveal">
You remember now. You chose to forget. The question is: are you ready to remember more?
</div>
[[Walk forward — follow the brightest thread->WalkForward]]
[[Kneel and touch the lattice->TouchLattice]]
[[Call out into the void->CallOut]]You let go. The hum becomes a ocean, and you dissolve into it. There is no "you" anymore — just vibration, just resonance, just the fundamental frequency of existence.
<div class="trippy-scene deepsound">
For a moment that lasts forever, you ARE the sound. And the sound is beautiful. Terrifying. Infinite.
</div>
Then, gently, you resurface. But different. You carry a note inside you now — a frequency you can summon at will.
<span class="glow">You gained: The Resonance</span>
[[Return to the threshold->ReturnThreshold]]You trace the constellation on your palm. The lines glow where your finger passes, and the pattern completes itself — a sigil that burns itself into your memory.
The air around you shatters like glass, revealing — behind the thin veneer of reality — a garden. Bioluminescent flowers pulse in rhythm with your heartbeat. Trees made of crystallized sound sway in a wind you cannot feel.
<div class="trippy-reveal">
A figure made of starlight stands among the flowers, watching you. It smiles with too many eyes.
</div>
"Welcome back," it says. "We've been waiting."
[[Approach the figure->StarlightFigure]]
[[Ask "Back? I've never been here."->FirstTime]]You reach into the threads trailing from your fingertips. They're warm, alive. Each one vibrates with a different emotion — joy, sorrow, curiosity, love, terror, wonder.
<div class="trippy-scene threads">
As you pull on one thread, you feel a tug somewhere far away. Someone — something — is on the other end. You're connected now. Irrevocably.
</div>
The thread you pulled shimmers: it's the color of <span class="glow">possibility</span>.
<span class="glow">You gained: A Thread of Possibility</span>
[[Follow the thread->FollowThread]]
[[Return to the threshold->ReturnThreshold]]
[[Tug the thread->TugThread]]You stand again at the edge. The portal breathes before you, patient and eternal.
The void calls. It always has.
<div class="trippy-intro">
But now you carry something with you. Something the void gave you. Something that makes you more than you were.
</div>
[[Step through the portal->Portal]]
[[Sit with the void and just be->JustBe]]
<<if $hasResonance or $hasThread>>[[Use what you've gained->UseGift]]<</if>>You sit. You breathe. The void breathes with you.
There is no urgency here. No destination. Just this moment, stretching like taffy, like honey, like time itself decided to take a break and watch the colors shift.
<div class="trippy-reveal">
And in the stillness, you understand: the void was never empty. It was <em>full</em> — so full that it looked like nothing at all. Every possibility that ever was or could be, compressed into a singularity of potential.
</div>
You laugh. The void laughs with you. The sound bounces off nothing and becomes everything.
<span class="glow">You gained: The Laughter</span>
<<set $hasLaughter to true>>
[[Open your eyes — truly open them->EyesOpen]]<<if $hasResonance>>
You hum the frequency you carry. The portal responds — its fractals rearrange, aligning into a doorway you couldn't see before. A passage to somewhere deeper.
<</if>>
<<if $hasThread>>
The thread in your hand pulses and stretches across the portal, forming a bridge of light. Something on the other side pulls gently, welcoming.
<</if>>
<div class="trippy-scene gift">
The void recognizes its gifts. It opens for you like a flower greeting the sun.
</div>
[[Enter the deeper void->DeeperVoid]]Each step is a universe. Each universe is a thought. You walk through minds not your own, glimpsing lives lived in dimensions folded beside your own.
A child who dreams in fractals. A storm that feels loneliness. A star that writes poetry in its death throes.
<div class="trippy-reveal">
At the end of the brightest thread, you find a mirror. But the reflection isn't you — it's everyone you could have been, every choice unmade, every path not taken. They're all smiling at you.
</div>
[[Touch the mirror->TouchMirror]]
[[Thank them and turn away->TurnAway]]You kneel and press your palms flat against the transparent ground. The lattice hums beneath your touch, and information floods through you — not data, not words, but <em>knowing</em>.
You see the web that connects all things. Every person, every particle, every dream and nightmare — all nodes in an infinite network. And you — you are a node too. You always have been.
<div class="trippy-scene lattice">
The lattice shows you: you are not separate from this. You never were. The illusion of isolation is the thinnest, most persistent veil.
</div>
<span class="glow">You gained: The Knowing</span>
<<set $hasKnowing to true>>
[[Rise up->ReturnThreshold]]Your voice echoes into the void. It doesn't fade — it multiplies. Each echo becomes a new voice, each voice carries your words in a different emotion: wonder, grief, hope, rage, delight.
<div class="trippy-reveal">
Something answers. Not with words — with color. The void blooms in response to your call, painting itself in shades that have no names in any human language.
</div>
The colors coalesce into a shape. A door. No — a <em>question</em>, given form.
[[Answer the question->AnswerQuestion]]
[[Ask your own question->AskOwn]]The path of violet lightning crackles around you. Each step sends shocks of pure sensation through your body — not pain, but <em>intensity</em>. Every nerve ending is a tiny supernova.
<div class="trippy-scene violet">
You are moving through a space made of electricity and intention. The lightning doesn't strike randomly — it follows thought. Yours.
</div>
Think of something. Anything.
[[Think of home->ThinkHome]]
[[Think of the person you love most->ThinkLove]]
[[Think of nothing at all->ThinkNothing]]You dive into liquid gold. It's not wet, not warm — it's <em>meaningful</em>. Each molecule carries a fragment of truth, and as you swim, truths soak into your skin like sunlight.
<div class="trippy-scene gold">
The gold river carries you through caverns of crystallized time. You see moments frozen: first kisses, last goodbyes, the silence between heartbeats.
</div>
A golden figure forms from the current, walking beside you on the riverbank.
"You're close," it says. "Close to what?" you ask. It only smiles.
[[Follow the figure->GoldFigure]]
[[Dive deeper into the river->GoldDive]]The singing crystals harmonize as you approach. Each one is a note in a chord that predates the universe. Together, they sing the sound that was here before silence — before there was anything to be silent in.
<div class="trippy-scene crystal">
You press your ear against the nearest crystal. Inside, you hear a voice — your own voice — narrating a life you haven't lived yet. A future, or a possibility, or a warning.
</div>
<span class="glow">Tap a crystal to hear its song:</span>
<div id="crystal-choices">
<div class="crystal-orb crystal-listen" data-target="CrystalStory">
<div class="crystal-inner"></div>
<span>Listen</span>
</div>
<div class="crystal-orb crystal-sing" data-target="SingBack">
<div class="crystal-inner"></div>
<span>Sing back</span>
</div>
</div>
<<script>>
(function(){
var orbs = document.querySelectorAll('.crystal-orb');
orbs.forEach(function(o){
o.addEventListener('click', function(){
orbs.forEach(function(oo){ oo.classList.add('crystal-faded'); });
o.classList.remove('crystal-faded');
o.classList.add('crystal-active');
setTimeout(function(){
Engine.play(o.getAttribute('data-target'));
}, 700);
});
});
})();
<</script>>You pass through the doorway into a space beyond space. Here, there is no up or down, no before or after. There is only <em>presence</em>.
<div class="trippy-reveal">
In the deepest void, you find it: the seed. The first thought. The original "what if?" that began everything — every universe, every dream, every electron dancing around every atom.
</div>
It looks like a question mark made of light. It pulses gently, waiting.
<span class="glow">You have reached the Heart of the Void.</span>
[[Touch the seed->TheEnd1]]
[[Ask the seed a question->TheEnd2]]
[[Leave the seed in peace and return->TheEnd3]]You touch the seed. Light pours through you — every color, every frequency, every possible sensation compressed into a single eternal instant.
<div class="trippy-scene ending">
You understand now. You were never separate from the void. You were never "at its edge." You are the void, experiencing itself from a particular angle. And that angle — your angle — is beautiful.
</div>
<span class="glow">Thank you for playing.</span>
[[Begin again->Start]]You ask the seed: "Why?"
The seed answers not with words but with a feeling — the feeling of a question so vast that answering it would require a new universe to contain the answer. And then you feel it: the answer is being built. Always being built. Never finished. That's the point.
<div class="trippy-reveal">
The meaning isn't at the end. The meaning IS the journey. This journey. Every journey.
</div>
<span class="glow">Thank you for playing.</span>
[[Begin again->Start]]You smile at the seed. It doesn't need your question. It doesn't need your touch. It just needs to exist, and it does, and that's enough.
You turn and walk back through the void, carrying with you not answers but <em>wonder</em>. The best thing you can carry.
<div class="trippy-scene ending">
The portal waits for you, patient as always. You step back through, and the world you left behind is exactly as you left it — but you are not. You never will be again.
</div>
<span class="glow">Thank you for playing.</span>
[[Begin again->Start]]You walk through the bioluminescent garden toward the figure. With each step, flowers bloom in your wake, lighting the path behind you.
<div class="trippy-reveal">
"Every time you come here, you forget," the figure says. "And every time, you find your way back. That's the bravest thing — finding what you lost, over and over, without even knowing you lost it."
</div>
The figure extends a hand made of constellations.
[[Take the hand->TakeHand]]
[[Ask "How many times have I been here?"->HowMany]]The figure's too-many eyes blink in sequence, like a wave of amusement.
<div class="trippy-scene">
"That's what you say every time," it laughs, and the flowers pulse with its laughter. "Every. Single. Time."
</div>
It gestures around the garden. Look closely at the flowers — each one has a tiny face. Your face. Different ages, different expressions. Hundreds of you, blooming in eternal loops.
"Still want to claim it's your first visit?"
[[Accept the truth->AcceptTruth]]
[[Insist this feels like the first time->FirstTimeInsist]]You follow the thread of possibility. It leads you through landscapes that shift like dreams — first a desert of colored sand, then an ocean of liquid starlight, then a forest where the trees are made of equations that solve themselves as you watch.
<div class="trippy-scene">
At the end of the thread, you find a door. Plain, wooden, absurdly ordinary. It stands alone in the middle of the void, frame and all, nothing behind it.
</div>
But the thread goes straight through the keyhole.
[[Open the door->OpenDoor]]
[[Knock->KnockDoor]]You tug the thread. Something tugs back.
Hard.
You're pulled off your feet and through a cascade of realities — each one a variation on the life you know. In one, the sky is green. In another, music is visible. In a third, you are a thought being thought by something vast and dreaming.
<div class="trippy-reveal">
The tug was a greeting. Whatever is on the other end of this thread — it's saying hello.
</div>
[[Say hello back->SayHello]]
[[Hold on tight and see where it takes you->ThreadRide]]Your fingers meet the glass — but there is no glass. You pass through and become, for one impossible moment, all of your alternate selves simultaneously.
<div class="trippy-scene mirror">
You are the child who chose differently. You are the elder who chose nothing at all. You are every branching path, and every branching path is you. The mirror doesn't show reflections — it shows <em>completions</em>.
</div>
<span class="glow">You gained: The Wholeness</span>
You step back, yourself again, but more. The mirror ripples in farewell.
[[Return to the threshold->ReturnThreshold]]You smile at your unmade selves and turn away. They wave — some wave with hands you recognize, others with tendrils, tentacles, beams of light. They're happy for you. They chose to stay. You chose to go. Both are valid.
<div class="trippy-reveal">
Walking away from every possibility is its own kind of bravery. Or its own kind of foolishness. The void doesn't judge.
</div>
[[Return to the threshold->ReturnThreshold]]The door-shaped question asks nothing aloud. But you feel it, pressed against your mind like a thought trying to be born:
*What are you afraid to know?*
<div class="trippy-scene">
The void waits. It has always waited. It is infinitely patient.
</div>
[[Tell it your fear->TellFear]]
[[Refuse to answer — some things should stay unknown->RefuseAnswer]]You ask your question into the void. The void doesn't answer — instead, it gives you the space to sit with your question. To hold it. To turn it over like a gemstone and watch the light play through its facets.
<div class="trippy-reveal">
Some questions aren't meant to be answered. They're meant to be <em>lived</em>.
</div>
The void wraps around your question like a blanket, keeping it warm until you're ready to live it.
<span class="glow">You gained: A Living Question</span>
<<set $hasQuestion to true>>
[[Return to the threshold->ReturnThreshold]]<div class="trippy-scene fate-portal">
Fate hangs suspended in the void. Six paths stretch out before you — each representing a different possibility. But why choose when the universe can decide?
</div>
<span class="glow">Tap the floating die to let fate decide.</span>
<div id="fate-die-container" class="dice-container">
<div class="void-die-3d void-die-fate">
<div class="die-face die-face-front" data-passage="Start"><span>1</span></div>
<div class="die-face die-face-back" data-passage="Portal"><span>6</span></div>
<div class="die-face die-face-top" data-passage="Listen"><span>5</span></div>
<div class="die-face die-face-bottom" data-passage="Hands"><span>2</span></div>
<div class="die-face die-face-left" data-passage="VioletPath"><span>4</span></div>
<div class="die-face die-face-right" data-passage="GoldPath"><span>3</span></div>
</div>
</div>
<<script>>
(function(){
var die = document.querySelector('.void-die-fate');
if(!die) return;
die.addEventListener('click', function(e){
e.stopPropagation();
if(die.classList.contains('rolling')) return;
// Roll animation
die.classList.add('rolling');
die.style.animationDuration = (Math.random() * 0.5 + 0.8) + 's';
setTimeout(function(){
die.classList.remove('rolling');
die.style.animation = '';
// Pick random face
var faces = die.querySelectorAll('.die-face');
var result = faces[Math.floor(Math.random() * faces.length)];
var targetPassage = result.getAttribute('data-passage');
var faceName = result.classList[2].replace('die-face-', '').toUpperCase();
// Highlight the chosen face briefly
faces.forEach(function(f){ f.classList.remove('die-selected'); });
result.classList.add('die-selected');
// Optional: add a message based on outcome
var msgDiv = document.createElement('div');
msgDiv.className = 'trippy-reveal';
msgDiv.innerHTML = '<strong>Fate has chosen...</strong> The path of <span class="glow">' + faceName + '</span>.';
var container = document.getElementById('fate-die-container').parentNode;
container.insertBefore(msgDiv, container.firstChild);
setTimeout(function(){
Engine.play(targetPassage);
}, 1200);
}, 1400);
});
})();
<</script>>
<div class="trippy-scene" style="margin-top: 1.5em;">
Or walk your own way:
</div>You think of home. The lightning reorganizes itself instantly — becoming a perfect recreation of your kitchen, your street, your view from the window. But electrified, vibrating, more real than real.
<div class="trippy-scene">
Your home, seen through lightning, is beautiful. You never noticed how the light falls through the window at that particular angle, how the cracks in the ceiling trace a map to somewhere wonderful.
</div>
But something is different. There's a door in your home that wasn't there before. It shimmers with violet energy.
[[Open the new door->NewDoor]]
[[Look out the window->Window]]You think of the one you love. Lightning becomes warmth — soft, golden, pulsing with the exact rhythm of your heart when you're near them.
<div class="trippy-reveal">
In this space of pure electricity, you feel the truth that you sometimes forget: love is not a feeling. It's a frequency. And right now, you're broadcasting on their wavelength.
</div>
Somewhere, somehow, they feel it. A warmth. A sudden certainty that they are loved. They don't know why. They smile.
<span class="glow">You sent: An Invisible Love Letter</span>
[[Return to the threshold->ReturnThreshold]]You think of nothing. True nothing — not emptiness, not blankness, but the absence of thought itself.
The lightning stops. The violet dims. And in the silence between thoughts, you find it: the space where everything comes from.
<div class="trippy-scene">
It's not dark. It's not light. It's the canvas before the first brushstroke. The breath before the first word. The pause that makes music possible.
</div>
<span class="glow">You gained: The Pause</span>
<<set $hasPause to true>>
[[Sit in the silence forever (or until you're ready)->ReturnThreshold]]You follow the golden figure along the riverbank. It walks without leaving footprints, yet flowers of pure meaning bloom where it steps.
"You're close," it says again. "But close isn't the point."
"Then what is?"
<div class="trippy-reveal">
The figure stops. Turns. Its golden face is yours — a version of you made of truth so pure it shines.
"The point is <em>this</em>," it says, gesturing at everything — the river, the caverns, you, the void, the flowers. "The point is that you're here. Experiencing. Asking. <em>Being.</em>"
</div>
<span class="glow">You gained: The Presence</span>
<<set $hasPresence to true>>
[[Return to the threshold->ReturnThreshold]]You dive deeper. The gold thickens around you, becomes syrupy with significance. Every stroke reveals another layer of truth:
* The universe is a feedback loop experiencing itself.
* You are the universe's way of tasting its own beauty.
* Every goodbye is a hello in reverse.
<div class="trippy-scene">
At the very bottom, you find a pearl. Not golden — black. A pearl of absolute void, resting in a river of absolute meaning. They coexist. They always have.
</div>
The pearl shows you: meaning and emptiness are not opposites. They're partners in a dance that has no name.
[[Take the pearl->TakePearl]]
[[Leave it and float->ReturnThreshold]]You listen. The crystal tells you a story — YOUR story, but told from the perspective of the universe experiencing you. To the universe, you are a flavor. A texture. A unique pattern of thought and feeling that has never existed before and will never exist again.
<div class="trippy-reveal">
You are the universe's most precious experiment. And the universe is delighted by how you're turning out.
</div>
<span class="glow">You gained: Cosmic Perspective</span>
<<set $hasPerspective to true>>
[[Return to the threshold->ReturnThreshold]]You sing back. Your voice joins the crystal chord, and the harmony shifts — becomes richer, more complex, more <em>alive</em>.
<div class="trippy-scene">
The crystals around you begin to change shape, responding to your voice. They form patterns — your patterns. Your song made visible. It's the most beautiful thing you've ever seen, because it's you, translated into pure sound and light.
</div>
<span class="glow">You gained: Your Song</span>
<<set $hasSong to true>>
[[Return to the threshold->ReturnThreshold]]You take the black pearl. It's warm in your hand — impossibly warm, like holding a tiny universe that chose to be small for a while.
<div class="trippy-reveal">
The pearl whispers: "Emptiness is not absence. Emptiness is potential. Every void is a womb."
</div>
<span class="glow">You gained: The Pearl of Potential</span>
<<set $hasPearl to true>>
[[Return to the threshold->ReturnThreshold]]You take the constellation hand. Stars connect between your fingers — a bridge between two kinds of existence.
<div class="trippy-scene">
"You're ready," the figure says. "Not because you know everything, but because you're willing to not know. That's the only qualification that matters here."
</div>
The garden blooms brighter. The flowers with your face smile. The sky opens into fractals.
[[Step into the deeper garden->DeeperVoid]]The figure tilts its head. All its eyes narrow in calculation.
<div class="trippy-reveal">
"Seventeen thousand, four hundred and thirty-two," it says. "Give or take a few infinities." It pauses. "But who's counting? Oh wait — you are. You always ask this question. And you always forget the answer."
</div>
It smiles warmly. "That's okay. Forgetting is part of the design."
[[Accept the truth->AcceptTruth]]You take a breath. You've been here before — thousands of times — and each time the void feels new. That's not a flaw. That's a feature.
<div class="trippy-scene">
The garden pulses with recognition. Your flowers — your past visits — bloom brighter, welcoming you back. You are a regular at the edge of existence, and the void saves your seat.
</div>
<span class="glow">You gained: The Memory of Returning</span>
<<set $hasMemory to true>>
[[Explore the deeper garden->DeeperVoid]]The figure nods slowly, its too-many eyes softening with something like compassion.
"Then let it be the first time. Again. That's the gift, isn't it? The ability to experience wonder as if for the first time, even when it's the ten thousandth."
<div class="trippy-reveal">
It plucks a flower — your flower, from this visit — and offers it to you. "For your collection. You have a garden of these, somewhere you can't remember. They're all beautiful."
</div>
<span class="glow">You gained: A Flower of First Wonder</span>
<<set $hasFlower to true>>
[[Return to the threshold->ReturnThreshold]]You open the plain wooden door. Behind it is — everything. Every possible everything, compressed into a space the size of a breath. You see it all in an instant, and your mind does something remarkable: it doesn't break. It <em>expands</em>.
<div class="trippy-scene">
You step through into a room that is the size of the universe and the size of a single atom simultaneously. Here, the thread of possibility connects to every other thread, forming a web of infinite potential.
</div>
You understand: you are the spider and the web and the fly and the beauty of it all.
<span class="glow">You gained: The Web</span>
<<set $hasWeb to true>>
[[Return to the threshold->ReturnThreshold]]You knock. Three times. It feels right.
The door opens from the other side. But there's no one there — just a note, handwritten in ink that shimmers between all colors:
<div class="trippy-reveal">
*"Glad you knocked. Most people just barge in. Come in when you're ready — the tea is infinite and the conversation is eternal."*
</div>
The door stands open, patient. On the other side, you catch glimpses of impossible comfort — a fire that burns backwards, chairs that are also thoughts, a table set for a feast of questions.
[[Step inside->OpenDoor]]You say hello. Not with your voice — with your whole being. You radiate greeting like a star radiates light.
<div class="trippy-scene">
And something answers. Not with words. With a feeling of being <em>seen</em>. Completely. Without judgment. Just... acknowledged. Witnessed.
</div>
In the vast emptiness between realities, two threads touched. That's all it took. Connection.
<span class="glow">You gained: A Connection Beyond Realities</span>
<<set $hasConnection to true>>
[[Return to the threshold->ReturnThreshold]]You hold on. The thread accelerates — pulling you through realities faster and faster until they blur into a single streak of color-sound-feeling-meaning.
<div class="trippy-reveal">
And then it stops. Abruptly. You're floating in a space that is perfectly, absolutely still. A single point of silence in the infinite noise of existence.
</div>
Here, you can hear yourself think. Really think. Without the noise of the universe.
What do you hear?
[[A lullaby you forgot from childhood->Lullaby]]
[[The sound of your own heartbeat, steady and brave->Heartbeat]]
[[Nothing — beautiful, perfect nothing->PerfectNothing]]You whisper your fear into the void. It trembles as it leaves you — a dark, fragile thing exposed to infinite space.
<div class="trippy-scene">
The void doesn't judge. It doesn't fix. It holds your fear gently, like something precious, and shows you: your fear is not the opposite of courage. Your fear IS courage, in its earliest form — the part that hasn't decided to be brave yet.
</div>
Your fear transforms. Not into fearlessness — into <em>gentleness</em>. You are gentle with yourself now. That's the real magic.
<span class="glow">You gained: Self-Compassion</span>
<<set $hasCompassion to true>>
[[Return to the threshold->ReturnThreshold]]You shake your head. Some doors should stay closed. Some questions should stay unasked. Not out of fear — out of wisdom.
<div class="trippy-reveal">
The void nods. It respects your boundary. It has infinite patience and infinite space — it can wait until you're ready, even if that's never.
</div>
The question-door dissolves into a shower of light that settles around you like snow. Beautiful and harmless. Unanswered and fine.
<span class="glow">You gained: The Wisdom of Boundaries</span>
<<set $hasBoundaries to true>>
[[Return to the threshold->ReturnThreshold]]You open the door. Behind it is not a room but a view — your hometown, but seen from impossibly high up, like a god's-eye view. Every person is a glowing dot, connected by threads of interaction, love, conflict, coincidence.
<div class="trippy-reveal">
You see the pattern. Your town — every town — is a living thing. And you are one of its cells. Essential. Part of the whole.
</div>
<span class="glow">You gained: The Overview</span>
<<set $hasOverview to true>>
[[Return to the threshold->ReturnThreshold]]You look out the window. Your street is there, but transformed — every house pulses with the light of the lives inside. Every tree is a network of roots sharing nutrients with neighbors. Every car is a story in motion.
<div class="trippy-scene">
The ordinary, seen truly, is extraordinary. You always knew this. Now you <em>feel</em> it.
</div>
<span class="glow">You gained: Wonder for the Ordinary</span>
<<set $hasWonder to true>>
[[Return to the threshold->ReturnThreshold]]A lullaby you haven't heard since you were tiny, held in arms that felt like the whole world. The melody is incomplete — you've lost most of it — but the <em>feeling</em> remains. Safe. Loved. Home.
<div class="trippy-reveal">
The void sings it back to you, filling in the gaps. Not the notes — the feeling. You are held. You always were.
</div>
<span class="glow">You gained: The Lullaby</span>
<<set $hasLullaby to true>>
[[Return to the threshold->ReturnThreshold]]Thump. Thump. Thump. Steady. Alive. Yours.
<div class="trippy-scene">
In the perfect silence, your heartbeat is the loudest thing in existence. And it's beautiful. This rhythm has been with you through everything — every joy, every sorrow, every ordinary Tuesday. It has never stopped. It is your most loyal companion.
</div>
<span class="glow">You gained: Gratitude for the Beating</span>
<<set $hasGratitude to true>>
[[Return to the threshold->ReturnThreshold]]Nothing. No sound, no sight, no thought. Just — nothing.
<div class="trippy-reveal">
And it's perfect. The most restful thing you've ever experienced. A vacation for the soul. A reset. A deep, clean breath for the part of you that's been holding its breath without knowing it.
</div>
You rest in the nothing. You don't know how long. Time doesn't apply here.
When you're ready, you open your eyes, refreshed in a way you've never been before.
<span class="glow">You gained: Deep Rest</span>
<<set $hasRest to true>>
[[Return to the threshold->ReturnThreshold]]<<script>>
(function(){
/* ---- TRIPPY PARTICLE CANVAS ---- */
var c = document.createElement('canvas');
c.id = 'void-canvas';
c.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:-1;';
document.body.appendChild(c);
var ctx = c.getContext('2d');
var W, H, dpr;
function resize(){ dpr = window.devicePixelRatio||1; W = window.innerWidth; H = window.innerHeight; c.width = W*dpr; c.height = H*dpr; ctx.setTransform(dpr,0,0,dpr,0,0); }
resize(); window.addEventListener('resize', resize);
/* mouse / touch tracking */
var mx = W/2, my = H/2;
window.addEventListener('mousemove', function(e){ mx=e.clientX; my=e.clientY; });
window.addEventListener('touchmove', function(e){ mx=e.touches[0].clientX; my=e.touches[0].clientY; }, {passive:true});
/* particles */
var PARTICLE_COUNT = 80;
var particles = [];
var hueBase = 260;
function spawnParticle(){
return {
x: Math.random()*W, y: Math.random()*H,
vx: (Math.random()-0.5)*0.3, vy: (Math.random()-0.5)*0.3 - 0.1,
r: Math.random()*2.5+0.5,
hue: hueBase + Math.random()*60 - 30,
alpha: Math.random()*0.5+0.15,
life: Math.random()*600+200, maxLife: 0
};
}
for(var i=0;i<PARTICLE_COUNT;i++){ var p=spawnParticle(); p.maxLife=p.life; particles.push(p); }
/* sacred geometry ring (slowly rotating) */
var geoAngle = 0;
var geoPulse = 0;
/* passage transition burst */
var burstParticles = [];
function addBurst(bx, by){
for(var i=0;i<18;i++){
var a = Math.PI*2/18*i;
burstParticles.push({ x:bx, y:by, vx:Math.cos(a)*2.5+Math.random(), vy:Math.sin(a)*2.5+Math.random(), r:Math.random()*2+1, alpha:1, hue:hueBase+Math.random()*80, life:60 });
}
}
$(document).on(':passageend', function(){
geoPulse = 1.0;
hueBase = (hueBase + 17) % 360;
var rect = document.getElementById('passages');
if(rect) addBurst(W/2, rect.getBoundingClientRect().top + 40);
});
/* draw sacred geometry */
function drawGeo(cx, cy, radius, sides, rot, alpha){
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(rot);
ctx.beginPath();
for(var i=0;i<=sides;i++){
var a = Math.PI*2/sides*i;
var px = Math.cos(a)*radius, py = Math.sin(a)*radius;
i===0 ? ctx.moveTo(px,py) : ctx.lineTo(px,py);
}
ctx.closePath();
ctx.strokeStyle = 'hsla('+Math.round(hueBase)+',70%,60%,'+alpha.toFixed(3)+')';
ctx.lineWidth = 0.8;
ctx.stroke();
/* inner star connections */
if(sides > 4){
ctx.beginPath();
for(var i=0;i<sides;i++){
var a1=Math.PI*2/sides*i, a2=Math.PI*2/sides*((i+Math.floor(sides/2))%sides);
ctx.moveTo(Math.cos(a1)*radius, Math.sin(a1)*radius);
ctx.lineTo(Math.cos(a2)*radius, Math.sin(a2)*radius);
}
ctx.strokeStyle = 'hsla('+Math.round(hueBase+40)+',60%,55%,'+( alpha*0.5).toFixed(3)+')';
ctx.lineWidth = 0.5;
ctx.stroke();
}
ctx.restore();
}
/* main loop */
var t = 0;
function frame(){
t++;
ctx.clearRect(0,0,W,H);
/* ambient gradient that slowly shifts */
var gx1 = W*0.3 + Math.sin(t*0.003)*W*0.15;
var gy1 = H*0.4 + Math.cos(t*0.004)*H*0.15;
var grad = ctx.createRadialGradient(gx1,gy1,0, gx1,gy1,W*0.7);
grad.addColorStop(0, 'hsla('+Math.round(hueBase)+',50%,15%,0.12)');
grad.addColorStop(0.5, 'hsla('+Math.round(hueBase+60)+',40%,8%,0.06)');
grad.addColorStop(1, 'rgba(0,0,0,0)');
ctx.fillStyle = grad;
ctx.fillRect(0,0,W,H);
/* sacred geometry */
geoAngle += 0.002;
geoPulse *= 0.97;
var baseR = Math.min(W,H) * 0.18;
var pulseR = baseR * (1 + geoPulse * 0.3);
/* outer ring - reacts to mouse */
var gcx = W/2 + (mx - W/2)*0.05;
var gcy = H/2 + (my - H/2)*0.05;
drawGeo(gcx, gcy, pulseR, 6, geoAngle, 0.08 + geoPulse*0.2);
drawGeo(gcx, gcy, pulseR*0.65, 6, -geoAngle*0.7, 0.06 + geoPulse*0.15);
drawGeo(gcx, gcy, pulseR*1.3, 3, geoAngle*0.4, 0.04 + geoPulse*0.1);
/* third eye dot at center */
ctx.beginPath();
ctx.arc(gcx, gcy, 2 + geoPulse*4, 0, Math.PI*2);
ctx.fillStyle = 'hsla('+Math.round(hueBase+120)+',80%,70%,'+( 0.15+geoPulse*0.5).toFixed(3)+')';
ctx.fill();
/* particles */
for(var i=particles.length-1; i>=0; i--){
var p = particles[i];
/* gentle attraction to mouse */
var dx = mx - p.x, dy = my - p.y;
var dist = Math.sqrt(dx*dx+dy*dy)+1;
if(dist < 200){
p.vx += dx/dist*0.02;
p.vy += dy/dist*0.02;
}
p.x += p.vx; p.y += p.vy;
p.vx *= 0.998; p.vy *= 0.998;
p.life--;
/* wrap around */
if(p.x<-20) p.x=W+20; if(p.x>W+20) p.x=-20;
if(p.y<-20) p.y=H+20; if(p.y>H+20) p.y=-20;
var fadeAlpha = p.alpha * Math.min(1, p.life/60);
/* glow */
ctx.beginPath();
ctx.arc(p.x, p.y, p.r*3, 0, Math.PI*2);
ctx.fillStyle = 'hsla('+Math.round(p.hue)+',80%,60%,'+(fadeAlpha*0.15).toFixed(3)+')';
ctx.fill();
/* core */
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI*2);
ctx.fillStyle = 'hsla('+Math.round(p.hue)+',70%,75%,'+(fadeAlpha).toFixed(3)+')';
ctx.fill();
if(p.life <= 0){
particles[i] = spawnParticle();
particles[i].maxLife = particles[i].life;
}
}
/* connection lines between nearby particles */
for(var i=0; i<particles.length; i++){
for(var j=i+1; j<particles.length; j++){
var dx=particles[i].x-particles[j].x, dy=particles[i].y-particles[j].y;
var d2=dx*dx+dy*dy;
if(d2 < 6400){ /* 80px */
var a = (1 - d2/6400)*0.08;
ctx.beginPath();
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
ctx.strokeStyle = 'hsla('+Math.round(hueBase+30)+',50%,60%,'+a.toFixed(3)+')';
ctx.lineWidth = 0.5;
ctx.stroke();
}
}
}
/* burst particles */
for(var i=burstParticles.length-1; i>=0; i--){
var b = burstParticles[i];
b.x += b.vx; b.y += b.vy;
b.vx *= 0.96; b.vy *= 0.96;
b.life--; b.alpha *= 0.95;
ctx.beginPath();
ctx.arc(b.x, b.y, b.r, 0, Math.PI*2);
ctx.fillStyle = 'hsla('+Math.round(b.hue)+',80%,70%,'+(b.alpha).toFixed(3)+')';
ctx.fill();
if(b.life<=0) burstParticles.splice(i,1);
}
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
})();
<</script>>@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;600&display=swap');
:root {
--void-bg: #06060e;
--void-text: #ddd6f3;
--void-muted: #a99cc8;
--void-accent: #b080ff;
--void-glow: rgba(160, 100, 255, 0.5);
--void-border: rgba(100, 60, 200, 0.2);
--void-card: rgba(80, 50, 160, 0.08);
}
html { scroll-behavior: smooth; }
body {
background: var(--void-bg);
color: var(--void-text);
font-family: 'Cinzel', Georgia, 'Times New Roman', serif;
line-height: 1.8;
margin: 0;
padding: 0;
min-height: 100vh;
-webkit-font-smoothing: antialiased;
}
#passages {
max-width: 640px;
margin: 0 auto;
padding: 50px 24px 120px;
position: relative;
z-index: 1;
}
/* Passage entrance animation */
.passage {
opacity: 0;
transform: translateY(16px) scale(0.99);
animation: passageIn 1s cubic-bezier(0.23, 1, 0.32, 1) forwards;
}
@keyframes passageIn {
to { opacity: 1; transform: translateY(0) scale(1); }
}
/* Content blocks */
.trippy-intro {
font-size: 1.05em;
line-height: 2;
color: var(--void-muted);
margin-bottom: 1.8em;
border-left: 2px solid var(--void-border);
padding-left: 1.2em;
position: relative;
}
.trippy-intro::before {
content: '';
position: absolute;
left: -1px; top: 0; bottom: 0; width: 1px;
background: linear-gradient(to bottom, transparent, var(--void-accent), transparent);
opacity: 0.5;
}
.trippy-scene {
background: var(--void-card);
border: 1px solid var(--void-border);
border-radius: 12px;
padding: 1.4em 1.6em;
margin: 1.8em 0;
line-height: 1.9;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
position: relative;
overflow: hidden;
}
.trippy-scene::after {
content: '';
position: absolute;
top: -50%; left: -50%; width: 200%; height: 200%;
background: conic-gradient(from 0deg, transparent, rgba(160,100,255,0.03), transparent, rgba(100,60,200,0.03), transparent);
animation: sceneRotate 20s linear infinite;
pointer-events: none;
}
@keyframes sceneRotate {
to { transform: rotate(360deg); }
}
.trippy-reveal {
background: linear-gradient(135deg, rgba(160,80,255,0.06), rgba(100,40,200,0.04));
border-left: 3px solid rgba(200, 100, 255, 0.35);
padding: 1.1em 1.4em;
margin: 1.8em 0;
font-style: italic;
color: #d0b8f0;
border-radius: 0 8px 8px 0;
}
/* Glow text */
.glow {
color: var(--void-accent);
text-shadow: 0 0 20px var(--void-glow), 0 0 60px rgba(160, 100, 255, 0.15);
font-weight: 600;
}
/* Choice links */
a.link-internal, .passage a {
color: var(--void-accent);
text-decoration: none;
display: inline-block;
margin: 0.5em 0;
padding: 0.3em 0;
position: relative;
transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
border-bottom: 1px solid rgba(160, 128, 255, 0.15);
}
a.link-internal::before {
content: '⟡';
margin-right: 0.4em;
opacity: 0;
transform: translateX(-8px);
transition: all 0.3s ease;
display: inline-block;
}
a.link-internal:hover, .passage a:hover {
color: #d0b0ff;
border-bottom-color: rgba(192, 160, 255, 0.5);
text-shadow: 0 0 15px rgba(160, 100, 255, 0.5), 0 0 30px rgba(160, 100, 255, 0.2);
transform: translateX(4px);
}
a.link-internal:hover::before {
opacity: 1;
transform: translateX(0);
}
/* Clicked / visited links */
a.link-internal:active {
transform: translateX(8px) scale(0.98);
}
/* Disabled links */
a.link-disabled {
color: rgba(100, 80, 140, 0.3);
text-decoration: line-through;
cursor: default;
}
a.link-broken {
color: #664;
}
/* ---- SugarCube UI Bar restyling ---- */
#ui-bar {
background: transparent !important;
border-right: none !important;
width: 3.5em !important;
pointer-events: auto;
}
#ui-bar.stowed {
left: -3.5em !important;
}
#ui-bar-body {
visibility: hidden !important;
}
#story {
margin-left: 3.5em !important;
-o-transition: margin-left .3s cubic-bezier(.23,1,.32,1) !important;
transition: margin-left .3s cubic-bezier(.23,1,.32,1) !important;
}
#ui-bar.stowed ~ #story {
margin-left: 0 !important;
}
/* Toggle button — minimal glowing orb */
#ui-bar-toggle {
position: fixed !important;
top: 16px !important;
left: 8px !important;
z-index: 10000 !important;
width: 36px !important;
height: 36px !important;
padding: 0 !important;
border: 1px solid rgba(100, 60, 200, 0.3) !important;
border-radius: 50% !important;
background: rgba(20, 10, 40, 0.6) !important;
backdrop-filter: blur(8px) !important;
-webkit-backdrop-filter: blur(8px) !important;
color: rgba(176, 128, 255, 0.5) !important;
font-size: 14px !important;
line-height: 36px !important;
text-align: center !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
overflow: hidden !important;
}
#ui-bar-toggle::before {
content: '✦' !important;
font-family: inherit !important;
}
#ui-bar-toggle:hover {
border-color: rgba(160, 100, 255, 0.6) !important;
background: rgba(40, 20, 80, 0.8) !important;
color: rgba(192, 160, 255, 0.9) !important;
box-shadow: 0 0 20px rgba(160, 100, 255, 0.2) !important;
}
/* History buttons */
#ui-bar-history {
position: fixed !important;
top: 60px !important;
left: 8px !important;
z-index: 9999 !important;
display: flex !important;
flex-direction: column !important;
gap: 6px !important;
}
#ui-bar-history [id|=history] {
width: 36px !important;
height: 36px !important;
padding: 0 !important;
border: 1px solid rgba(100, 60, 200, 0.2) !important;
border-radius: 50% !important;
background: rgba(20, 10, 40, 0.4) !important;
backdrop-filter: blur(8px) !important;
-webkit-backdrop-filter: blur(8px) !important;
color: rgba(176, 128, 255, 0.4) !important;
font-size: 13px !important;
line-height: 36px !important;
text-align: center !important;
transition: all 0.3s ease !important;
margin-left: 0 !important;
}
#ui-bar-history [id|=history]:hover:not(:disabled) {
border-color: rgba(160, 100, 255, 0.5) !important;
background: rgba(40, 20, 80, 0.7) !important;
color: rgba(192, 160, 255, 0.9) !important;
}
#ui-bar-history [id|=history]:disabled {
color: rgba(100, 80, 140, 0.2) !important;
border-color: rgba(60, 40, 100, 0.1) !important;
background: transparent !important;
}
#ui-bar-history #history-jumpto::before { content: '↻' !important; font-family: inherit !important; }
#ui-bar-history #history-back::before { content: '←' !important; font-family: inherit !important; }
#ui-bar-history #history-forward::before { content: '→' !important; font-family: inherit !important; }
/* Menu items when sidebar is open */
#menu ul {
background: rgba(15, 10, 30, 0.8) !important;
backdrop-filter: blur(12px) !important;
border: 1px solid rgba(100, 60, 200, 0.15) !important;
border-radius: 8px !important;
overflow: hidden !important;
}
#menu li a {
color: rgba(176, 128, 255, 0.7) !important;
text-transform: none !important;
letter-spacing: 0.05em !important;
font-family: 'Cinzel', Georgia, serif !important;
font-size: 0.85em !important;
transition: all 0.3s ease !important;
}
#menu li a:hover {
background: rgba(60, 30, 120, 0.3) !important;
color: rgba(192, 160, 255, 0.95) !important;
}
#menu li:not(:first-child) {
border-top: 1px solid rgba(100, 60, 200, 0.1) !important;
}
#story-title {
color: var(--void-accent) !important;
font-family: 'Cinzel', Georgia, serif !important;
text-shadow: 0 0 20px rgba(160, 100, 255, 0.3) !important;
}
#story-author {
color: var(--void-muted) !important;
font-family: 'Cinzel', Georgia, serif !important;
}
#ui-bar hr {
border-color: rgba(100, 60, 200, 0.15) !important;
}
/* Stowed state — hide history too */
#ui-bar.stowed #ui-bar-history {
visibility: hidden !important;
opacity: 0 !important;
transition: all 0.2s ease !important;
}
#ui-bar:not(.stowed) #ui-bar-body {
visibility: visible !important;
}
/* Hide SugarCube header */
#story-title, #passages-header { display: none; }
/* ---- Interactive doors ---- */
#void-doors {
display: flex;
justify-content: center;
gap: 20px;
margin: 2em 0 1em;
perspective: 800px;
}
.void-door {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}
.void-door-frame {
width: 80px; height: 120px;
border: 2px solid rgba(100, 60, 200, 0.3);
border-radius: 6px 6px 0 0;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
background: rgba(10, 6, 20, 0.6);
backdrop-filter: blur(4px);
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
transform-style: preserve-3d;
}
.void-door:hover .void-door-frame {
border-color: rgba(160, 100, 255, 0.6);
box-shadow: 0 0 30px rgba(160, 100, 255, 0.15), inset 0 0 20px rgba(160, 100, 255, 0.05);
transform: rotateY(-8deg) scale(1.05);
}
.void-door-handle {
font-size: 1.6em;
z-index: 2;
filter: grayscale(0.3);
transition: filter 0.3s;
}
.void-door:hover .void-door-handle {
filter: grayscale(0);
}
.void-door-label {
margin-top: 8px;
font-size: 0.75em;
color: rgba(176, 128, 255, 0.5);
letter-spacing: 0.1em;
text-transform: uppercase;
transition: color 0.3s;
}
.void-door:hover .void-door-label {
color: rgba(192, 160, 255, 0.8);
}
/* Door inner glow effects */
.void-door-lightning {
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
background: linear-gradient(180deg, rgba(120,60,220,0.15), transparent 40%, rgba(120,60,220,0.1));
}
.void-door-gold {
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
background: linear-gradient(180deg, rgba(200,160,40,0.15), transparent 40%, rgba(200,160,40,0.1));
}
.void-door-crystal {
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
background: linear-gradient(180deg, rgba(60,180,200,0.15), transparent 40%, rgba(60,180,200,0.1));
}
/* Door chosen / faded states */
.void-door-chosen .void-door-frame {
border-color: rgba(160, 100, 255, 0.9) !important;
box-shadow: 0 0 40px rgba(160, 100, 255, 0.3), inset 0 0 30px rgba(160, 100, 255, 0.1) !important;
transform: rotateY(-25deg) scale(1.1) !important;
}
.void-door-chosen .void-door-handle {
filter: none;
}
.void-door-faded {
opacity: 0.15;
transform: scale(0.9);
pointer-events: none;
}
/* ---- Crystal orbs ---- */
#crystal-choices {
display: flex;
justify-content: center;
gap: 32px;
margin: 2em 0 1em;
}
.crystal-orb {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}
.crystal-inner {
width: 70px; height: 70px;
border-radius: 50%;
border: 2px solid rgba(100, 60, 200, 0.3);
background: radial-gradient(circle at 35% 35%, rgba(120, 80, 220, 0.2), rgba(40, 20, 80, 0.4));
box-shadow: 0 0 15px rgba(100, 60, 200, 0.1), inset 0 0 15px rgba(160, 100, 255, 0.05);
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
animation: crystalPulse 3s ease-in-out infinite;
}
.crystal-listen .crystal-inner {
border-color: rgba(120, 60, 220, 0.4);
background: radial-gradient(circle at 35% 35%, rgba(140, 80, 255, 0.25), rgba(30, 10, 60, 0.5));
}
.crystal-sing .crystal-inner {
border-color: rgba(60, 160, 200, 0.4);
background: radial-gradient(circle at 35% 35%, rgba(80, 200, 240, 0.25), rgba(10, 30, 60, 0.5));
animation-delay: 1.5s;
}
@keyframes crystalPulse {
0%, 100% { transform: scale(1); box-shadow: 0 0 15px rgba(100, 60, 200, 0.1); }
50% { transform: scale(1.08); box-shadow: 0 0 30px rgba(160, 100, 255, 0.2); }
}
.crystal-orb:hover .crystal-inner {
transform: scale(1.15);
box-shadow: 0 0 40px rgba(160, 100, 255, 0.3), inset 0 0 20px rgba(160, 100, 255, 0.1);
border-color: rgba(160, 100, 255, 0.7);
}
.crystal-orb span {
margin-top: 10px;
font-size: 0.75em;
color: rgba(176, 128, 255, 0.5);
letter-spacing: 0.1em;
text-transform: uppercase;
transition: color 0.3s;
}
.crystal-orb:hover span {
color: rgba(192, 160, 255, 0.8);
}
.crystal-active .crystal-inner {
transform: scale(1.3) !important;
box-shadow: 0 0 60px rgba(160, 100, 255, 0.5), inset 0 0 30px rgba(160, 100, 255, 0.2) !important;
border-color: rgba(200, 160, 255, 0.9) !important;
}
.crystal-faded {
opacity: 0.15;
transform: scale(0.85);
pointer-events: none;
}
/* ---- 3D animated die ---- */
.dice-container {
display: flex;
justify-content: center;
margin: 2em 0;
perspective: 600px;
}
.void-die-3d {
width: 100px;
height: 100px;
position: relative;
transform-style: preserve-3d;
cursor: pointer;
transition: transform 0.3s ease;
}
.void-die-3d:hover {
filter: drop-shadow(0 0 25px rgba(160, 100, 255, 0.5));
}
.void-die-3d.rolling {
cursor: not-allowed;
animation: dieShake 0.4s ease-in-out infinite;
}
@keyframes dieShake {
0%, 100% { transform: rotateX(0deg) rotateY(0deg); }
25% { transform: rotateX(-30deg) rotateY(20deg); }
75% { transform: rotateX(25deg) rotateY(-15deg); }
}
.void-die-3d.fate-selected {
animation: dieSpinWin 1.5s cubic-bezier(0.23, 1, 0.32, 1) !important;
}
@keyframes dieSpinWin {
0% { transform: rotateX(0deg) rotateY(0deg); }
100% { transform: rotateX(720deg) rotateY(360deg); }
}
/* Die faces - positioned as a cube */
.die-face {
position: absolute;
width: 100px;
height: 100px;
background: linear-gradient(135deg, rgba(80, 40, 160, 0.9), rgba(40, 20, 80, 0.95));
border: 2px solid rgba(160, 100, 255, 0.4);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Cinzel', Georgia, serif;
font-size: 2.5em;
color: rgba(200, 160, 255, 0.9);
text-shadow: 0 0 10px rgba(160, 100, 255, 0.5);
backdrop-filter: blur(8px);
box-shadow: inset 0 0 20px rgba(160, 100, 255, 0.1), 0 0 10px rgba(100, 60, 200, 0.2);
opacity: 0.95;
transform-origin: center;
transition: opacity 0.3s, box-shadow 0.3s;
}
/* Position all six faces of the cube */
.die-face-front { transform: rotateY(0deg) translateZ(50px); }
.die-face-back { transform: rotateY(180deg) translateZ(50px); }
.die-face-top { transform: rotateX(90deg) translateZ(50px); }
.die-face-bottom { transform: rotateX(-90deg) translateZ(50px); }
.die-face-left { transform: rotateY(-90deg) translateZ(50px); }
.die-face-right { transform: rotateY(90deg) translateZ(50px); }
/* Highlight selected face */
.die-selected .die-face {
opacity: 1 !important;
box-shadow: 0 0 40px rgba(160, 100, 255, 0.6), inset 0 0 30px rgba(160, 100, 255, 0.2) !important;
border-color: rgba(200, 160, 255, 0.8) !important;
z-index: 100;
}
/* Small dice variant (for Start passage) */
.dice-container-start {
margin-bottom: 1em;
}
.void-die-small {
width: 80px;
height: 80px;
}
.void-die-small .die-face {
width: 80px;
height: 80px;
font-size: 2em;
}
.void-die-small .die-face span {
filter: drop-shadow(0 0 5px rgba(160, 100, 255, 0.4));
}
/* Mobile tweaks */
@media (max-width: 480px) {
#passages { padding: 60px 16px 100px; }
.trippy-scene { padding: 1em 1.1em; }
a.link-internal { margin: 0.6em 0; }
}