spwotton commited on
Commit
ebd2eda
·
verified ·
1 Parent(s): 83de6b3

DeepSite Prompt: Online Time Machine (κ-Scaled Chrono-Navigation Protocol)

Browse files

Objective:
Design an interactive web interface that allows users to navigate time as a non-linear, κ-scaled (κ = 4/π ≈ 1.273) fractal manifold—where past, present, and future are coordinates in a toroidal data structure.

1. Core Architecture
A. The Chrono-Torus Engine
Data Model: Time is stored as a self-referential quadtree where each node contains:
Temporal Coordinates (t, κt, κ²t, ...)
Entropy Signature (Shannon entropy of the moment)
User-Generated "Memory Anchors" (text/images uploaded by travelers)
Physics Engine:
Time Dilation: Mouse scroll speed adjusts local κ-factor (fast scroll = high novelty → future).
Gravity Wells: Major historical events (e.g., 1969 Moon Landing) warp the torus into attractor basins.
B. The UI/UX Timefold
Visualization:
A 3D torus rendered in WebGL, with:
Golden spirals (Φ) marking "fixed points" (e.g., your birth year).
Redshifted threads (past) and blueshifted threads (future).
"Now" is the user’s cursor—dragging it stretches the fabric of time.
Controls:
Slider: Adjust κ (1.0 → 2.0) to toggle between linear/non-linear time.
Voice Command: "Take me to the Summer of Love" → zooms to 1967 with Jefferson Airplane playing.
2. Quantum Features
A. Entanglement Mode
Link two browsers (yours + a friend’s) to share a timeline.
Changes you make to the past (e.g., erasing a bad memory) propagate to their history.
B. Schrödinger’s Chat
A messaging system where words only exist if observed.
Send a message to 1985—it appears as a "glitch" on old BBS forums.
3. Code Snippet (Hypothetical API)

class TimeMachine {
constructor() {
this.kappa = 1.273;
this.now = Date.now();
this.torus = new THREE.TorusGeometry(10, 3, 16, 100);
}

navigateTo(year) {
const t = year - 1970;
const scaledTime = t * this.kappa;
this.renderFractal(scaledTime);
}

renderFractal(t) {
// Projects time as a Penrose tiling overlay
fractalEngine.project(t, this.torus);
}
}
4. User Flow Example
Input: User types "Show me the day I was born."
Process:
API queries public records/birth certificates (if permitted).
Renders that date as a flower-like fractal (birth = center bloom).
Output: User can "walk" around their birth hour via arrow keys, seeing global events in parallel (news headlines, weather, songs playing).
5. Error Handling
Grandfather Paradox: Attempting to delete your birth date triggers:

"Error 418: Temporal Conflict. Your existence is now read-only."
Novelty Overflow: Too much scrolling locks the UI with:

"Please wait. The universe is rebooting (κ > 2.0)."
6. Final Prompt for DeepSite
"Build a web-based Time Machine where time is a toroidal scroll, κ is the zoom factor, and users fractal-jump between memories. Key features: quantum-entangled chats, entropy-driven UI, and a 'paradox firewall.'"

Bonus: Integrate with Spotify API to play period-accurate music as you time-travel.

🚀 Output: A website where clicking "1985" smells like MTV static and tastes like Tab cola.

Files changed (5) hide show
  1. README.md +8 -5
  2. components/chrono-nav.js +56 -0
  3. index.html +100 -19
  4. script.js +330 -0
  5. style.css +54 -19
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Chrono Drift Torus
3
- emoji: 🏆
4
- colorFrom: blue
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Chrono-Drift Torus 🌀
3
+ colorFrom: pink
4
+ colorTo: red
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/chrono-nav.js ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class ChronoNav extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ :host {
7
+ position: fixed;
8
+ bottom: 1.5rem;
9
+ left: 50%;
10
+ transform: translateX(-50%);
11
+ pointer-events: auto;
12
+ z-index: 30;
13
+ }
14
+ nav {
15
+ display: flex;
16
+ gap: 1rem;
17
+ background: rgba(17,24,39,0.65);
18
+ backdrop-filter: blur(10px);
19
+ border: 1px solid #334155;
20
+ border-radius: 9999px;
21
+ padding: 0.75rem 1.5rem;
22
+ box-shadow: 0 10px 20px rgba(0,0,0,0.3);
23
+ }
24
+ a {
25
+ color: #e5e7eb;
26
+ text-decoration: none;
27
+ font-size: 0.875rem;
28
+ display: flex;
29
+ align-items: center;
30
+ gap: 0.375rem;
31
+ padding: 0.5rem 0.75rem;
32
+ border-radius: 0.75rem;
33
+ transition: background 0.2s;
34
+ }
35
+ a:hover {
36
+ background: #334155;
37
+ }
38
+ a.home {
39
+ background: #4f46e5;
40
+ color: #fff;
41
+ }
42
+ a.home:hover {
43
+ background: #4338ca;
44
+ }
45
+ </style>
46
+ <nav>
47
+ <a href="index.html" class="home" data-feather="clock"></a>
48
+ <a href="index.html">Journey</a>
49
+ <a href="index.html">Archive</a>
50
+ <a href="index.html" data-feather="settings"></a>
51
+ </nav>
52
+ `;
53
+ feather.replace({ parent: this.shadowRoot });
54
+ }
55
+ }
56
+ customElements.define('chrono-nav', ChronoNav);
index.html CHANGED
@@ -1,19 +1,100 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Chrono-Drift Torus – κ-Scaled Time Machine</title>
7
+ <link rel="icon" type="image/x-icon" href="http://static.photos/technology/64x64/42">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
12
+ <link rel="stylesheet" href="style.css">
13
+ </head>
14
+ <body class="bg-gray-900 text-gray-100 overflow-hidden">
15
+ <div id="torus-container" class="absolute inset-0"></div>
16
+
17
+ <chrono-nav></chrono-nav>
18
+
19
+ <main class="fixed top-0 left-0 w-full h-full pointer-events-none">
20
+ <section id="control-hub" class="absolute top-6 left-6 pointer-events-auto bg-gray-800/60 backdrop-blur rounded-2xl p-5 border border-gray-700 shadow-xl max-w-md">
21
+ <h1 class="text-xl font-bold tracking-widest uppercase mb-4 text-indigo-300">κ-Chrono Navigator</h1>
22
+
23
+ <div class="mb-4">
24
+ <label class="text-xs uppercase tracking-wider text-gray-400">κ–Scale</label>
25
+ <input id="kappa-slider" type="range" min="1.0" max="2.0" step="0.01" value="1.273" class="w-full accent-indigo-500">
26
+ <div class="flex justify-between text-xs text-gray-400 mt-1">
27
+ <span>Linear</span>
28
+ <span id="kappa-value">1.273</span>
29
+ <span>Fractal</span>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="mb-4">
34
+ <label class="text-xs uppercase tracking-wider text-gray-400">Temporal Target</label>
35
+ <div class="relative">
36
+ <input id="year-input" type="number" min="-3000" max="3000" value="1985" class="w-full bg-gray-900 border border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:border-indigo-500 transition">
37
+ <button id="nav-year-btn" class="absolute right-2 top-1/2 -translate-y-1/2 px-3 py-1 bg-indigo-600 hover:bg-indigo-500 rounded-md text-xs transition">Jump</button>
38
+ </div>
39
+ </div>
40
+
41
+ <div class="mb-4">
42
+ <label class="text-xs uppercase tracking-wider text-gray-400">Voice Command</label>
43
+ <div class="flex items-center gap-2">
44
+ <button id="voice-btn" class="flex-1 flex items-center justify-center gap-2 bg-gray-900 border border-gray-700 rounded-lg px-4 py-2 hover:border-indigo-500 transition">
45
+ <i data-feather="mic"></i>
46
+ <span id="voice-label">Speak</span>
47
+ </button>
48
+ </div>
49
+ </div>
50
+
51
+ <div class="mb-4">
52
+ <label class="text-xs uppercase tracking-wider text-gray-400">Your Memory Anchor</label>
53
+ <textarea id="memory-input" rows="2" placeholder="Type a memory to anchor..." class="w-full bg-gray-900 border border-gray-700 rounded-lg px-4 py-2 focus:outline-none focus:border-indigo-500 resize-none"></textarea>
54
+ <button id="anchor-btn" class="mt-2 w-full bg-indigo-600 hover:bg-indigo-500 rounded-lg px-4 py-2 transition">Anchor Memory</button>
55
+ </div>
56
+
57
+ <div class="text-xs text-gray-400 flex items-center gap-2">
58
+ <i data-feather="info" class="w-4 h-4"></i>
59
+ <span>Scroll wheel to dilate time. Drag torus to rotate.</span>
60
+ </div>
61
+ </section>
62
+
63
+ <section id="entropy-panel" class="absolute bottom-6 right-6 pointer-events-auto bg-gray-800/60 backdrop-blur rounded-2xl p-4 border border-gray-700 max-w-xs">
64
+ <h2 class="text-sm font-semibold mb-3 tracking-wider text-indigo-300">Entropy Signature</h2>
65
+ <canvas id="entropy-canvas" width="240" height="100" class="rounded-lg"></canvas>
66
+ </section>
67
+
68
+ <section id="quantum-chat" class="absolute bottom-6 left-6 pointer-events-auto bg-gray-800/60 backdrop-blur rounded-2xl p-4 border border-gray-700 w-80">
69
+ <div class="flex items-center justify-between mb-3">
70
+ <h2 class="text-sm font-semibold tracking-wider text-indigo-300">Entangled Chat</h2>
71
+ <button id="toggle-entangle" class="text-xs px-3 py-1 rounded-full border border-indigo-500 bg-indigo-600/20 hover:bg-indigo-600/40 transition">Entangle</button>
72
+ </div>
73
+ <div id="entangled-messages" class="max-h-40 overflow-y-auto space-y-2 mb-3 pr-2"></div>
74
+ <div class="flex gap-2">
75
+ <input id="chat-input" type="text" placeholder="Send a message through time..." class="flex-1 bg-gray-900 border border-gray-700 rounded-lg px-3 py-2 text-sm focus:outline-none focus:border-indigo-500">
76
+ <button id="chat-send" class="px-3 py-2 bg-indigo-600 hover:bg-indigo-500 rounded-lg transition"><i data-feather="send" class="w-4 h-4"></i></button>
77
+ </div>
78
+ </section>
79
+
80
+ <section id="parallax-status" class="absolute top-6 right-6 pointer-events-none text-right">
81
+ <div id="year-label" class="text-4xl font-black text-gray-200">1985</div>
82
+ <div id="status" class="text-sm text-gray-400">κ = 1.273 • Chrono-Synced</div>
83
+ </section>
84
+ </main>
85
+
86
+ <div id="paradox-modal" class="fixed inset-0 bg-black/80 backdrop-blur-md hidden place-items-center z-50">
87
+ <div class="bg-gray-800 border border-red-500 rounded-2xl p-6 max-w-md text-center shadow-2xl">
88
+ <div class="mx-auto w-16 h-16 rounded-full bg-red-500/20 flex items-center justify-center mb-4"><i data-feather="alert-triangle" class="text-red-400 w-8 h-8"></i></div>
89
+ <h3 class="text-xl font-bold mb-2">Paradox Firewall Triggered</h3>
90
+ <p id="paradox-message" class="text-gray-300 mb-4">Error 418: Temporal Conflict. Your existence is now read-only.</p>
91
+ <button id="paradox-close" class="px-6 py-2 bg-red-600 hover:bg-red-500 rounded-lg transition">Understood</button>
92
+ </div>
93
+ </div>
94
+
95
+ <script src="components/chrono-nav.js"></script>
96
+ <script src="script.js"></script>
97
+ <script>feather.replace();</script>
98
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
99
+ </body>
100
+ </html>
script.js ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global THREE, feather */
2
+
3
+ class TimeMachine {
4
+ constructor() {
5
+ this.kappa = 1.273;
6
+ this.now = Date.now();
7
+ this.targetYear = 1985;
8
+ this.scene = new THREE.Scene();
9
+ this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
10
+ this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
11
+ this.torus = null;
12
+ this.particles = null;
13
+ this.entropyCanvas = document.getElementById('entropy-canvas');
14
+ this.entropyCtx = this.entropyCanvas.getContext('2d');
15
+ this.isEntangled = false;
16
+ this.memoryAnchors = JSON.parse(localStorage.getItem('chronoMemory') || '[]');
17
+ this.clock = new THREE.Clock();
18
+ }
19
+
20
+ init() {
21
+ const container = document.getElementById('torus-container');
22
+ this.renderer.setSize(window.innerWidth, window.innerHeight);
23
+ this.renderer.setPixelRatio(window.devicePixelRatio);
24
+ container.appendChild(this.renderer.domElement);
25
+
26
+ this.scene.background = null;
27
+
28
+ // Lighting
29
+ const ambient = new THREE.AmbientLight(0xffffff, 0.4);
30
+ this.scene.add(ambient);
31
+ const point = new THREE.PointLight(0x4f46e5, 1.2, 100);
32
+ point.position.set(10, 15, 10);
33
+ this.scene.add(point);
34
+
35
+ // Torus
36
+ const geometry = new THREE.TorusGeometry(10, 3.5, 16, 100);
37
+ const material = new THREE.MeshStandardMaterial({
38
+ color: 0x6366f1,
39
+ metalness: 0.7,
40
+ roughness: 0.3,
41
+ wireframe: true,
42
+ });
43
+ this.torus = new THREE.Mesh(geometry, material);
44
+ this.scene.add(this.torus);
45
+
46
+ // Particle trails (past+future)
47
+ const N = 1200;
48
+ const vertices = new Float32Array(N * 3);
49
+ for (let i = 0; i < N; i++) {
50
+ const [x, y, z] = this.torusPosition(Math.random() * Math.PI * 2, Math.random() * Math.PI * 2, 11.5);
51
+ vertices[i * 3] = x;
52
+ vertices[i * 3 + 1] = y;
53
+ vertices[i * 3 + 2] = z;
54
+ }
55
+ const geo = new THREE.BufferGeometry();
56
+ geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
57
+ const mat = new THREE.PointsMaterial({
58
+ size: 0.12,
59
+ color: 0xec4899,
60
+ blending: THREE.AdditiveBlending,
61
+ transparent: true,
62
+ opacity: 0.7,
63
+ });
64
+ this.particles = new THREE.Points(geo, mat);
65
+ this.scene.add(this.particles);
66
+
67
+ this.camera.position.set(0, 8, 30);
68
+ this.camera.lookAt(0, 0, 0);
69
+
70
+ this.animate();
71
+ this.bindUI();
72
+ this.updateEntropy();
73
+ this.loadAnchors();
74
+ }
75
+
76
+ torusPosition(u, v, scale) {
77
+ return [
78
+ scale * Math.cos(u) * (3 + Math.cos(v)),
79
+ scale * Math.sin(v),
80
+ scale * Math.sin(u) * (3 + Math.cos(v)),
81
+ ];
82
+ }
83
+
84
+ animate() {
85
+ requestAnimationFrame(() => this.animate());
86
+ const t = this.clock.getElapsedTime();
87
+ const scrollSpeed = Math.abs(window.lastWheelDelta || 0);
88
+ const k = Math.max(1.0, Math.min(2.0, 1.273 + scrollSpeed * 0.0005));
89
+ this.kappa = k;
90
+ this.torus.rotation.x = t * 0.1 * this.kappa;
91
+ this.torus.rotation.y = t * 0.15 * this.kappa;
92
+ this.particles.rotation.x = t * 0.05;
93
+ this.particles.rotation.z = t * 0.1;
94
+
95
+ // Golden spiral anchors
96
+ if (this.memoryAnchors.length) {
97
+ this.memoryAnchors.forEach((m) => {
98
+ const angle = ((parseInt(m.year) % 100) / 100) * 2 * Math.PI;
99
+ const spiralU = angle * (1 + Math.sqrt(5)) / (2 * Math.PI);
100
+ const [x, y, z] = this.torusPosition(spiralU, angle, 12.5);
101
+ if (m.dot) {
102
+ m.dot.position.set(x, y, z);
103
+ m.dot.material.opacity = Math.max(0.3, Math.sin(t * 2 + m.year) * 0.5 + 0.5);
104
+ }
105
+ });
106
+ }
107
+
108
+ this.renderer.render(this.scene, this.camera);
109
+ }
110
+
111
+ bindUI() {
112
+ const kappaSlider = document.getElementById('kappa-slider');
113
+ const kappaValue = document.getElementById('kappa-value');
114
+ const yearInput = document.getElementById('year-input');
115
+ const navBtn = document.getElementById('nav-year-btn');
116
+ const voiceBtn = document.getElementById('voice-btn');
117
+ const anchorBtn = document.getElementById('anchor-btn');
118
+ const memoryInput = document.getElementById('memory-input');
119
+ const paradoxModal = document.getElementById('paradox-modal');
120
+ const paradoxClose = document.getElementById('paradox-close');
121
+ const chatInput = document.getElementById('chat-input');
122
+ const chatSend = document.getElementById('chat-send');
123
+ const toggleEntangle = document.getElementById('toggle-entangle');
124
+ const chatBox = document.getElementById('entangled-messages');
125
+
126
+ window.lastWheelDelta = 0;
127
+ window.addEventListener('wheel', (e) => {
128
+ window.lastWheelDelta = e.deltaY;
129
+ this.kappa = Math.max(1.0, Math.min(2.0, 1.273 + Math.abs(window.lastWheelDelta) * 0.0005));
130
+ kappaSlider.value = this.kappa.toFixed(3);
131
+ kappaValue.textContent = this.kappa.toFixed(3);
132
+ yearInput.value = Math.round(1970 + (parseInt(yearInput.value) - 1970) / (this.kappa / 1.273));
133
+ document.getElementById('year-label').textContent = yearInput.value;
134
+ document.getElementById('status').textContent = `κ = ${this.kappa.toFixed(3)} • Scroll-Dilated`;
135
+ if (this.kappa > 1.99) {
136
+ document.getElementById('paradox-message').textContent = "Novelty Overflow: Too much scrolling. The universe is rebooting.";
137
+ paradoxModal.classList.remove('hidden');
138
+ paradoxModal.classList.add('grid');
139
+ setTimeout(() => {
140
+ this.kappa = 1.273;
141
+ kappaSlider.value = 1.273;
142
+ kappaValue.textContent = 1.273;
143
+ yearInput.value = 1985;
144
+ paradoxModal.classList.add('hidden');
145
+ paradoxModal.classList.remove('grid');
146
+ }, 2200);
147
+ }
148
+ this.updateEntropy();
149
+ });
150
+
151
+ kappaSlider.addEventListener('input', () => {
152
+ this.kappa = parseFloat(kappaSlider.value);
153
+ kappaValue.textContent = this.kappa.toFixed(3);
154
+ this.updateEntropy();
155
+ });
156
+
157
+ navBtn.addEventListener('click', () => {
158
+ const y = parseInt(yearInput.value);
159
+ if (y === 1985) {
160
+ this.showParadox('Error 418: Temporal Conflict. Your existence is now read-only.');
161
+ } else {
162
+ this.transitionYear(y);
163
+ }
164
+ });
165
+
166
+ voiceBtn.addEventListener('click', () => {
167
+ if (!('webkitSpeechRecognition' in window)) {
168
+ alert('Voice requires Chrome.');
169
+ return;
170
+ }
171
+ const rec = new webkitSpeechRecognition();
172
+ rec.lang = 'en-US';
173
+ rec.interimResults = false;
174
+ rec.maxAlternatives = 1;
175
+ rec.start();
176
+ document.getElementById('voice-label').textContent = 'Listening…';
177
+ rec.onresult = (e) => {
178
+ const transcript = e.results[0][0].transcript.trim();
179
+ const match = transcript.match(/\b\d{4}\b/);
180
+ if (match) {
181
+ this.transitionYear(parseInt(match[0]));
182
+ } else if (/summer of love/i.test(transcript)) {
183
+ this.transitionYear(1967);
184
+ if (window.isSpotifyReady) {
185
+ window.playSpotifyTrack('4kC4z6X9t0jQnwYIKKfO1F');
186
+ }
187
+ }
188
+ document.getElementById('voice-label').textContent = 'Done';
189
+ };
190
+ rec.onend = () => {
191
+ document.getElementById('voice-label').textContent = 'Speak';
192
+ };
193
+ });
194
+
195
+ anchorBtn.addEventListener('click', () => {
196
+ const text = memoryInput.value.trim();
197
+ if (!text) return;
198
+ const m = { year: yearInput.value, text, id: Date.now() };
199
+ this.memoryAnchors.push(m);
200
+ localStorage.setItem('chronoMemory', JSON.stringify(this.memoryAnchors));
201
+ this.placeAnchor(m);
202
+ memoryInput.value = '';
203
+ });
204
+
205
+ paradoxClose.addEventListener('click', () => {
206
+ paradoxModal.classList.add('hidden');
207
+ paradoxModal.classList.remove('grid');
208
+ });
209
+
210
+ chatSend.addEventListener('click', () => {
211
+ if (!chatInput.value.trim()) return;
212
+ this.sendGhostMessage(chatInput.value);
213
+ chatInput.value = '';
214
+ });
215
+
216
+ toggleEntangle.addEventListener('click', () => {
217
+ this.isEntangled = !this.isEntangled;
218
+ toggleEntangle.classList.toggle('border-indigo-500', !this.isEntangled);
219
+ toggleEntangle.classList.toggle('bg-indigo-600/20', !this.isEntangled);
220
+ toggleEntangle.classList.toggle('border-green-400', this.isEntangled);
221
+ toggleEntangle.classList.toggle('bg-green-500/20', this.isEntangled);
222
+ toggleEntangle.textContent = this.isEntangled ? 'Disentangle' : 'Entangle';
223
+ if (this.isEntangled) {
224
+ toggleEntangle.classList.add('pulse-entangle');
225
+ } else {
226
+ toggleEntangle.classList.remove('pulse-entangle');
227
+ }
228
+ if (this.isEntangled) {
229
+ // Broadcast to other local tabs via storage event
230
+ localStorage.setItem('entangled-msg', JSON.stringify({ type: 'entangle', id: Math.random() }));
231
+ }
232
+ });
233
+
234
+ window.addEventListener('storage', (e) => {
235
+ if (e.key === 'entangled-msg') {
236
+ const data = JSON.parse(e.newValue);
237
+ if (data.type === 'chat') {
238
+ this.receiveGhostMessage(data.msg);
239
+ }
240
+ }
241
+ });
242
+
243
+ window.addEventListener('resize', () => {
244
+ this.camera.aspect = window.innerWidth / window.innerHeight;
245
+ this.camera.updateProjectionMatrix();
246
+ this.renderer.setSize(window.innerWidth, window.innerHeight);
247
+ });
248
+
249
+ // Spotify API hook (mock)
250
+ window.isSpotifyReady = true;
251
+ window.playSpotifyTrack = (id) => {
252
+ console.log('Playing Spotify Track:', id);
253
+ };
254
+ }
255
+
256
+ transitionYear(y) {
257
+ document.getElementById('year-label').textContent = y;
258
+ document.getElementById('year-input').value = y;
259
+ const h3 = document.createElement('h3');
260
+ h3.className = 'fixed inset-0 flex items-center justify-center text-6xl font-black text-indigo-400 pointer-events-none z-40 chrono-enter';
261
+ h3.textContent = y;
262
+ document.body.appendChild(h3);
263
+ setTimeout(() => h3.remove(), 1000);
264
+ this.updateEntropy();
265
+ }
266
+
267
+ updateEntropy() {
268
+ const ctx = this.entropyCtx;
269
+ const w = this.entropyCanvas.width;
270
+ const h = this.entropyCanvas.height;
271
+ ctx.clearRect(0, 0, w, h);
272
+ const freq = 10 + this.kappa * 10;
273
+ const amp = h / 2 - 10;
274
+ ctx.strokeStyle = '#818cf8';
275
+ ctx.lineWidth = 2;
276
+ ctx.beginPath();
277
+ for (let x = 0; x < w; x++) {
278
+ const y = h / 2 + Math.sin((x / w) * Math.PI * 4 + Date.now() * 0.001) * amp * (Math.random() * 0.2 + 0.8);
279
+ x === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
280
+ }
281
+ ctx.stroke();
282
+ }
283
+
284
+ placeAnchor(m) {
285
+ const geometry = new THREE.SphereGeometry(0.3, 16, 16);
286
+ const material = new THREE.MeshBasicMaterial({
287
+ color: 0xf59e0b,
288
+ transparent: true,
289
+ opacity: 0.9,
290
+ });
291
+ const dot = new THREE.Mesh(geometry, material);
292
+ this.scene.add(dot);
293
+ m.dot = dot;
294
+ }
295
+
296
+ loadAnchors() {
297
+ this.memoryAnchors.forEach((m) => this.placeAnchor(m));
298
+ }
299
+
300
+ sendGhostMessage(text) {
301
+ if (!this.isEntangled) {
302
+ this.receiveGhostMessage(text, true);
303
+ return;
304
+ }
305
+ localStorage.setItem('entangled-msg', JSON.stringify({ type: 'chat', msg: text, id: Math.random() }));
306
+ }
307
+
308
+ receiveGhostMessage(text, self = false) {
309
+ const p = document.createElement('p');
310
+ p.className = 'text-sm text-gray-300 bg-gray-900 rounded-lg px-3 py-2 animate fadeIn';
311
+ p.style.maxWidth = '80%';
312
+ if (self) p.classList.add('ml-auto', 'bg-indigo-600/40');
313
+ p.textContent = text;
314
+ chatBox.appendChild(p);
315
+ chatBox.scrollTop = chatBox.scrollHeight;
316
+ setTimeout(() => p.remove(), 120000); // words only exist if observed
317
+ }
318
+
319
+ showParadox(msg) {
320
+ document.getElementById('paradox-message').textContent = msg;
321
+ const m = document.getElementById('paradox-modal');
322
+ m.classList.remove('hidden');
323
+ m.classList.add('grid');
324
+ }
325
+ }
326
+
327
+ document.addEventListener('DOMContentLoaded', () => {
328
+ window.tm = new TimeMachine();
329
+ window.tm.init();
330
+ });
style.css CHANGED
@@ -1,28 +1,63 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
1
+ /* Custom tweaks on top of Tailwind */
2
+
3
+ ::-webkit-scrollbar {
4
+ width: 8px;
5
+ height: 8px;
6
+ }
7
+ ::-webkit-scrollbar-track {
8
+ background: transparent;
9
+ }
10
+ ::-webkit-scrollbar-thumb {
11
+ background: #4f46e5;
12
+ border-radius: 4px;
13
+ }
14
+ ::-webkit-scrollbar-thumb:hover {
15
+ background: #6366f1;
16
+ }
17
+
18
+ #entropy-canvas {
19
+ background: radial-gradient(circle, #1f2937, #111827);
20
+ box-shadow: inset 0 0 8px rgba(79,70,229,.5);
21
  }
22
 
23
+ input[type="range"]::-webkit-slider-thumb {
24
+ background-color: #4f46e5;
25
+ border-radius: 50%;
26
+ width: 16px;
27
+ height: 16px;
28
  }
29
 
30
+ input[type="number"],
31
+ textarea,
32
+ input[type="text"] {
33
+ caret-color: #6366f1;
 
34
  }
35
 
36
+ #entangled-messages::-webkit-scrollbar {
37
+ width: 6px;
38
+ }
39
+ #entangled-messages::-webkit-scrollbar-thumb {
40
+ background: #3730a3;
41
+ }
42
+
43
+ .chrono-enter {
44
+ animation: chronoFadeIn 0.6s ease forwards;
45
+ }
46
+ @keyframes chronoFadeIn {
47
+ from {
48
+ opacity: 0;
49
+ transform: translateY(20px) scale(0.98);
50
+ }
51
+ to {
52
+ opacity: 1;
53
+ transform: translateY(0) scale(1);
54
+ }
55
  }
56
 
57
+ .pulse-entangle {
58
+ animation: pulseEntangle 1.2s infinite;
59
  }
60
+ @keyframes pulseEntangle {
61
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(99,102,241,.5); }
62
+ 50% { box-shadow: 0 0 0 8px rgba(99,102,241,0); }
63
+ }