MatteoScript commited on
Commit
3729df2
·
verified ·
1 Parent(s): b9788b9

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +867 -19
index.html CHANGED
@@ -1,19 +1,867 @@
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="it">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
6
+ <title>Matteo Bergamelli | Innovation Lab Candidate</title>
7
+
8
+ <!-- Tailwind CSS -->
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+
11
+ <!-- Fonts (Manteniamo i tuoi font originali) -->
12
+ <link rel="preconnect" href="https://fonts.googleapis.com">
13
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
+ <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Fira+Code:wght@300;400;500;700&display=swap" rel="stylesheet">
15
+
16
+ <!-- Three.js -->
17
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
18
+
19
+ <!-- A-Frame & MindAR -->
20
+ <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
21
+ <script src="https://cdn.jsdelivr.net/gh/hiukim/mind-ar-js@1.1.5/dist/mindar-image.prod.js"></script>
22
+ <script src="https://cdn.jsdelivr.net/gh/hiukim/mind-ar-js@1.1.5/dist/mindar-image-aframe.prod.js"></script>
23
+
24
+ <style>
25
+ /* --- STILE ORIGINALE --- */
26
+ :root {
27
+ --neon-green: #00ff41;
28
+ --dark-bg: #050505;
29
+ --glass: rgba(10, 10, 10, 0.8);
30
+ }
31
+
32
+ body {
33
+ margin: 0;
34
+ background-color: var(--dark-bg);
35
+ color: #f5f5f5;
36
+ font-family: 'Fira Code', monospace;
37
+ overflow-x: hidden;
38
+ -webkit-font-smoothing: antialiased;
39
+ cursor: default;
40
+ }
41
+
42
+ /* Typography */
43
+ .font-serif { font-family: 'Playfair Display', serif; }
44
+ .font-mono { font-family: 'Fira Code', monospace; }
45
+
46
+ /* Selection Style (Nerd touch) */
47
+ ::selection {
48
+ background: var(--neon-green);
49
+ color: #000;
50
+ }
51
+
52
+ /* Scrollbar */
53
+ ::-webkit-scrollbar { width: 8px; }
54
+ ::-webkit-scrollbar-track { background: #0a0a0a; }
55
+ ::-webkit-scrollbar-thumb { background: #333; border-radius: 4px; }
56
+ ::-webkit-scrollbar-thumb:hover { background: var(--neon-green); }
57
+
58
+ /* --- FX: SCANLINES & CRT --- */
59
+ .scanlines {
60
+ background: linear-gradient(
61
+ to bottom,
62
+ rgba(255,255,255,0),
63
+ rgba(255,255,255,0) 50%,
64
+ rgba(0,0,0,0.2) 50%,
65
+ rgba(0,0,0,0.2)
66
+ );
67
+ background-size: 100% 4px;
68
+ position: fixed; pointer-events: none; top: 0; left: 0; right: 0; bottom: 0; z-index: 50;
69
+ }
70
+
71
+ /* --- FX: GLITCH TEXT --- */
72
+ .glitch-wrapper { position: relative; display: inline-block; }
73
+ .glitch { position: relative; color: inherit; }
74
+ .glitch::before, .glitch::after {
75
+ content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--dark-bg);
76
+ }
77
+ .glitch::before {
78
+ left: 2px; text-shadow: -1px 0 var(--neon-green); clip: rect(24px, 550px, 90px, 0);
79
+ animation: glitch-anim 3s infinite linear alternate-reverse;
80
+ }
81
+ .glitch::after {
82
+ left: -2px; text-shadow: -1px 0 #ff00ff; clip: rect(85px, 550px, 140px, 0);
83
+ animation: glitch-anim 2.5s infinite linear alternate-reverse;
84
+ }
85
+ @keyframes glitch-anim {
86
+ 0% { clip: rect(10px, 9999px, 30px, 0); }
87
+ 20% { clip: rect(80px, 9999px, 100px, 0); }
88
+ 40% { clip: rect(40px, 9999px, 60px, 0); }
89
+ 60% { clip: rect(20px, 9999px, 100px, 0); }
90
+ 80% { clip: rect(90px, 9999px, 5px, 0); }
91
+ 100% { clip: rect(10px, 9999px, 60px, 0); }
92
+ }
93
+
94
+ /* --- FX: RIPPLE CLICK --- */
95
+ .ripple {
96
+ position: absolute;
97
+ border-radius: 50%;
98
+ border: 1px solid var(--neon-green);
99
+ transform: scale(0);
100
+ animation: ripple-anim 0.6s linear;
101
+ pointer-events: none;
102
+ z-index: 999;
103
+ }
104
+ @keyframes ripple-anim {
105
+ to { transform: scale(4); opacity: 0; }
106
+ }
107
+
108
+ /* --- FX: MATRIX RAIN (Easter Egg) --- */
109
+ #matrix-canvas {
110
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 40;
111
+ opacity: 0; pointer-events: none; transition: opacity 1s;
112
+ }
113
+ .matrix-active #matrix-canvas { opacity: 0.3; }
114
+
115
+ /* --- ANIMATIONS --- */
116
+ .reveal-on-scroll {
117
+ opacity: 0; transform: translateY(30px); transition: opacity 0.8s ease-out, transform 0.8s ease-out;
118
+ }
119
+ .reveal-on-scroll.visible { opacity: 1; transform: translateY(0); }
120
+
121
+ .blink { animation: blink-anim 1s step-end infinite; }
122
+ @keyframes blink-anim { 50% { opacity: 0; } }
123
+
124
+ /* AR UI */
125
+ #ar-container { display: none; }
126
+ .mindar-ui-overlay { z-index: 1000 !important; }
127
+ </style>
128
+ </head>
129
+ <body>
130
+
131
+ <!-- EASTER EGG: MATRIX RAIN CANVAS -->
132
+ <canvas id="matrix-canvas"></canvas>
133
+
134
+ <!-- 1. TERMINAL LOADER -->
135
+ <div id="terminal-loader" class="fixed inset-0 z-[100] flex items-center justify-center bg-black transition-opacity duration-500">
136
+ <div class="w-full max-w-md p-6 font-mono text-sm md:text-base">
137
+ <div id="terminal-lines"></div>
138
+ <div class="mt-2">
139
+ <span class="text-[#00ff41]">></span> <span class="inline-block w-3 h-5 bg-[#00ff41] align-middle blink"></span>
140
+ </div>
141
+ </div>
142
+ </div>
143
+
144
+ <!-- 2. 3D BACKGROUND (Digital Fabric) -->
145
+ <div id="canvas-container" class="fixed inset-0 z-0 opacity-0 transition-opacity duration-1000"></div>
146
+
147
+ <!-- 3. SCANLINES -->
148
+ <div class="scanlines"></div>
149
+
150
+ <!-- STATUS BAR (Fixed Top) -->
151
+ <div id="status-bar" class="fixed top-0 w-full p-4 z-40 flex justify-between items-center pointer-events-none opacity-0 transition-opacity duration-1000 mix-blend-screen">
152
+ <div class="text-[10px] text-[#00ff41] font-mono">SYS.STATUS: ONLINE</div>
153
+ <div class="text-[10px] text-[#00ff41] font-mono">JOB_ID: <span id="job-id-scramble">XXXXXXXXX</span></div>
154
+ </div>
155
+
156
+ <!-- 4. MAIN CONTENT -->
157
+ <div id="main-content" class="relative z-10 w-full h-full opacity-0 transition-opacity duration-1000">
158
+
159
+ <!-- HERO SECTION -->
160
+ <section class="min-h-screen flex flex-col items-center justify-center px-6 py-20 relative">
161
+ <div class="max-w-4xl mx-auto text-center z-10">
162
+ <div class="mb-8 hover:scale-105 transition-transform duration-500 cursor-default">
163
+ <div class="glitch-wrapper font-serif text-5xl md:text-7xl font-bold mb-2 text-white">
164
+ <span class="glitch" data-text="Physical Touch,">Physical Touch,</span>
165
+ </div>
166
+ <br>
167
+ <div class="glitch-wrapper font-serif text-5xl md:text-7xl font-bold text-[#00ff41]">
168
+ <span class="glitch" data-text="Digital Mind.">Digital Mind.</span>
169
+ </div>
170
+ </div>
171
+
172
+ <p class="text-base md:text-xl leading-relaxed mb-12 max-w-2xl mx-auto font-mono opacity-80 reveal-on-scroll border-l-2 border-[#00ff41] pl-4 text-left md:text-center md:border-l-0 md:pl-0">
173
+ Ciao Innovation Lab. Hai appena trasformato un pezzo di stoffa in un flusso dati.
174
+ Questo è il mio concetto di <span class="text-[#00ff41] font-bold relative group cursor-help">
175
+ Omnichannel
176
+ <span class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-48 bg-black border border-[#00ff41] text-[#00ff41] text-[10px] p-2 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none">
177
+ (Spoiler: È la mia specialità)
178
+ </span>
179
+ </span>.
180
+ </p>
181
+
182
+ <div class="flex flex-col items-center reveal-on-scroll group" style="transition-delay: 0.2s;">
183
+ <!-- Initials with hidden click interaction -->
184
+ <div id="profile-pic" class="w-24 h-24 md:w-32 md:h-32 rounded-full border-2 border-[#00ff41] flex items-center justify-center bg-black/50 backdrop-blur-sm mb-4 shadow-[0_0_20px_rgba(0,255,65,0.3)] cursor-pointer transition-all hover:shadow-[0_0_40px_rgba(0,255,65,0.6)] active:scale-95">
185
+ <span class="text-3xl font-bold text-[#00ff41] group-hover:animate-pulse">MB</span>
186
+ </div>
187
+ <h2 class="font-serif text-2xl md:text-3xl font-bold mb-1">Matteo Bergamelli</h2>
188
+ <p class="text-[#00ff41] text-xs md:text-sm font-mono tracking-wider mb-2">INNOVATION / AI DEVELOPER</p>
189
+ <span class="px-3 py-1 border border-[#00ff41]/50 rounded-full text-[10px] text-[#00ff41] bg-[#00ff41]/10">
190
+ 📍 Km0 - Padenghe s/G
191
+ </span>
192
+ </div>
193
+ </div>
194
+
195
+ <!-- Scroll Indicator -->
196
+ <div class="absolute bottom-10 left-1/2 -translate-x-1/2 flex flex-col items-center gap-2 opacity-50 animate-bounce">
197
+ <span class="text-[10px] font-mono tracking-[0.2em] text-[#00ff41]">SCROLL TO DECODE</span>
198
+ <div class="w-[1px] h-12 bg-gradient-to-b from-[#00ff41] to-transparent"></div>
199
+ </div>
200
+ </section>
201
+
202
+ <!-- FABRIC DECODER SECTION -->
203
+ <section class="px-6 py-24 relative z-10">
204
+ <div class="max-w-5xl mx-auto">
205
+ <div class="mb-16 text-center reveal-on-scroll">
206
+ <h2 class="font-serif text-4xl md:text-5xl font-bold mb-4">
207
+ The Fabric <span class="text-[#00ff41]">Decoder</span>
208
+ </h2>
209
+ <p class="font-mono text-sm opacity-60">
210
+ // Tre tessuti. Tre layer tecnologici. Una sola persona.
211
+ </p>
212
+ </div>
213
+
214
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
215
+ <!-- CARD 1 -->
216
+ <div class="fabric-card relative p-8 rounded-xl overflow-hidden group transition-all duration-300 backdrop-blur-md bg-[#0f0f0f]/80 border border-[#333] hover:border-[#00ff41]/50 hover:-translate-y-2 reveal-on-scroll">
217
+ <div class="absolute inset-0 bg-gradient-to-r from-transparent via-[#00ff41]/5 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000 ease-in-out pointer-events-none"></div>
218
+ <div class="mb-6 pt-1">
219
+ <div class="p-3 bg-black/50 rounded-lg border border-[#333] group-hover:border-[#00ff41] transition-colors w-min">
220
+ <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#00ff41" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect><rect x="9" y="9" width="6" height="6"></rect><line x1="9" y1="1" x2="9" y2="4"></line><line x1="15" y1="1" x2="15" y2="4"></line><line x1="9" y1="20" x2="9" y2="23"></line><line x1="15" y1="20" x2="15" y2="23"></line></svg>
221
+ </div>
222
+ </div>
223
+ <h3 class="font-serif text-2xl font-bold mb-2 text-white">LEGACY STRUCTURE</h3>
224
+ <p class="text-xs text-[#00ff41] mb-4 font-mono tracking-widest">JEANS / RAW</p>
225
+ <p class="text-sm italic opacity-80 mb-6 font-serif border-l-2 border-[#333] pl-4 group-hover:border-[#00ff41] transition-colors">
226
+ "Solido. Resistente. Il ferro del Retail."
227
+ </p>
228
+ <ul class="space-y-3 mb-6 text-sm font-mono opacity-90">
229
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span><span class="text-[#00ff41] font-bold">13</span> anni di esperienza</span></li>
230
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span>ERP <span class="text-[#00ff41] font-bold">Zucchetti</span> & <span class="text-[#00ff41] font-bold">SAP</span></span></li>
231
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span>Hardware & PLC</span></li>
232
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span><span class="text-[#00ff41] font-bold">SQL</span> Server Expert</span></li>
233
+ </ul>
234
+ </div>
235
+
236
+ <!-- CARD 2 -->
237
+ <div class="fabric-card relative p-8 rounded-xl overflow-hidden group transition-all duration-300 backdrop-blur-md bg-[#0f0f0f]/80 border border-[#333] hover:border-[#00ff41]/50 hover:-translate-y-2 reveal-on-scroll" style="transition-delay: 0.2s;">
238
+ <div class="absolute inset-0 bg-gradient-to-r from-transparent via-[#00ff41]/5 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000 ease-in-out pointer-events-none"></div>
239
+ <div class="mb-6 pt-1">
240
+ <div class="p-3 bg-black/50 rounded-lg border border-[#333] group-hover:border-[#00ff41] transition-colors w-min">
241
+ <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#00ff41" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2Z"></path><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2Z"></path></svg>
242
+ </div>
243
+ </div>
244
+ <h3 class="font-serif text-2xl font-bold mb-2 text-white">GENERATIVE MESH</h3>
245
+ <p class="text-xs text-[#00ff41] mb-4 font-mono tracking-widest">NYLON / TECH</p>
246
+ <p class="text-sm italic opacity-80 mb-6 font-serif border-l-2 border-[#333] pl-4 group-hover:border-[#00ff41] transition-colors">
247
+ "Flessibile. Sintetico. Il futuro."
248
+ </p>
249
+ <ul class="space-y-3 mb-6 text-sm font-mono opacity-90">
250
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span><span class="text-[#00ff41] font-bold">Python</span> per AI & Auto</span></li>
251
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span>Agents: <span class="text-[#00ff41] font-bold">OpenAI</span>, <span class="text-[#00ff41] font-bold">Gemini</span></span></li>
252
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span><span class="text-[#00ff41] font-bold">RAG</span> su documenti</span></li>
253
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span><span class="text-[#00ff41] font-bold">PDF-to-JSON</span></span></li>
254
+ </ul>
255
+ </div>
256
+
257
+ <!-- CARD 3 (Highlighted) -->
258
+ <div class="fabric-card relative p-8 rounded-xl overflow-hidden group transition-all duration-300 backdrop-blur-md bg-gradient-to-br from-[#1a1a1a]/90 to-[#0a0a0a]/90 border border-[#00ff41] hover:-translate-y-2 reveal-on-scroll" style="transition-delay: 0.4s;">
259
+ <div class="absolute inset-0 bg-gradient-to-r from-transparent via-[#00ff41]/10 to-transparent -translate-x-full group-hover:translate-x-full transition-transform duration-1000 ease-in-out pointer-events-none"></div>
260
+ <div class="mb-6 pt-1">
261
+ <div class="p-3 bg-black/50 rounded-lg border border-[#00ff41] transition-colors w-min">
262
+ <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#00ff41" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line></svg>
263
+ </div>
264
+ </div>
265
+ <h3 class="font-serif text-2xl font-bold mb-2 text-[#00ff41]">THE OMNICHANNEL</h3>
266
+ <p class="text-xs text-[#00ff41] mb-4 font-mono tracking-widest">VELLUTO / NFC</p>
267
+ <p class="text-sm italic opacity-80 mb-6 font-serif border-l-2 border-[#333] pl-4 group-hover:border-[#00ff41] transition-colors">
268
+ "L'integrazione perfetta."
269
+ </p>
270
+ <ul class="space-y-3 mb-6 text-sm font-mono opacity-90">
271
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span>Middleware <span class="text-[#00ff41] font-bold">SAP-AI</span></span></li>
272
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span>Graphic & <span class="text-[#00ff41] font-bold">Meta</span> AR</span></li>
273
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span><span class="text-[#00ff41] font-bold">Magazziniere</span> to <span class="text-[#00ff41] font-bold">CTO</span></span></li>
274
+ <li class="flex gap-2"><span class="text-[#00ff41]">→</span> <span><span class="text-[#00ff41] font-bold">Physical</span> & <span class="text-[#00ff41] font-bold">Digital</span></span></li>
275
+ </ul>
276
+ <p class="text-xs mt-4 italic text-[#00ff41] font-bold">"Questo NFC che stai toccando? È solo l'inizio."</p>
277
+ </div>
278
+ </div>
279
+ </div>
280
+ </section>
281
+
282
+ <!-- UNLOCK AR LAYER -->
283
+ <section class="px-6 py-24 relative z-20 overflow-hidden">
284
+ <div class="absolute inset-0 bg-gradient-to-b from-black via-[#0d0d0d] to-black opacity-90"></div>
285
+ <div class="absolute inset-0 opacity-20" style="background-image: url('data:image/svg+xml,%3Csvg viewBox=%220 0 200 200%22 xmlns=%22http://www.w3.org/2000/svg%22%3E%3Cfilter id=%22noiseFilter%22%3E%3CfeTurbulence type=%22fractalNoise%22 baseFrequency=%220.65%22 numOctaves=%223%22 stitchTiles=%22stitch%22/%3E%3C/filter%3E%3Crect width=%22100%25%22 height=%22100%25%22 filter=%22url(%23noiseFilter)%22 opacity=%221%22/%3E%3C/svg%3E');"></div>
286
+
287
+ <div class="max-w-3xl mx-auto relative text-center reveal-on-scroll">
288
+ <div class="mb-8">
289
+ <h2 class="font-serif text-3xl md:text-4xl font-bold mb-4 text-white">
290
+ The Hidden <span class="text-[#00ff41] animate-pulse">Layer</span>
291
+ </h2>
292
+ <p class="font-mono text-xs md:text-sm opacity-70 max-w-lg mx-auto">
293
+ C'è un quarto livello di realtà nascosto in questo tessuto.
294
+ Sblocca il protocollo AR per visualizzare i dati nascosti.
295
+ </p>
296
+ </div>
297
+
298
+ <div class="py-8 flex justify-center">
299
+ <!-- Slider Component -->
300
+ <div id="slider-container" class="relative w-full max-w-xs h-14 bg-black border border-[#333] rounded-full overflow-hidden backdrop-blur-sm shadow-[0_0_15px_rgba(0,0,0,0.5)] select-none touch-none">
301
+ <div class="absolute -top-8 left-0 right-0 text-center">
302
+ <div class="text-[10px] text-[#00ff41] font-mono tracking-widest uppercase animate-pulse">Secure Connection Available</div>
303
+ </div>
304
+ <!-- Background Fill -->
305
+ <div id="slider-fill" class="absolute inset-0 bg-[#00ff41] opacity-10 transition-opacity" style="width: 0%"></div>
306
+ <div class="absolute inset-0 opacity-20 bg-[linear-gradient(90deg,transparent_0%,rgba(0,255,65,0.2)_50%,transparent_100%)] bg-[length:200%_100%] animate-[shimmer_2s_infinite] pointer-events-none"></div>
307
+
308
+ <!-- Text -->
309
+ <div id="slider-text" class="absolute inset-0 flex items-center justify-center pointer-events-none transition-opacity duration-300">
310
+ <span class="font-mono text-xs font-bold text-white tracking-[0.2em] uppercase flex items-center gap-2">
311
+ Slide to Decode <span class="animate-bounce">→</span>
312
+ </span>
313
+ </div>
314
+
315
+ <!-- Handle -->
316
+ <div id="slider-handle" class="absolute top-1 left-1 bottom-1 w-12 bg-[#0d0d0d] rounded-full border border-[#00ff41] flex items-center justify-center cursor-grab z-20 shadow-[0_0_10px_rgba(0,255,65,0.3)] active:cursor-grabbing hover:scale-105 transition-transform">
317
+ <svg id="icon-arrow" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="animate-pulse"><polyline points="9 18 15 12 9 6"></polyline></svg>
318
+ <svg id="icon-lock" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#00ff41" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="hidden"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>
319
+ </div>
320
+ </div>
321
+ </div>
322
+
323
+ <p class="mt-8 text-[10px] text-[#00ff41]/60 font-mono">
324
+ // REQUIRES CAMERA PERMISSION
325
+ </p>
326
+ </div>
327
+ </section>
328
+
329
+ <!-- MISSING LINK SECTION & CODE BLOCK -->
330
+ <section class="px-6 py-24 relative z-10 bg-black/60 backdrop-blur-md border-y border-[#333]">
331
+ <div class="max-w-3xl mx-auto reveal-on-scroll">
332
+ <h2 class="font-serif text-3xl md:text-4xl font-bold text-center mb-12">
333
+ The <span class="text-[#00ff41]">"Missing Link"</span>
334
+ </h2>
335
+
336
+ <!-- Code Block Component -->
337
+ <div class="relative rounded-lg overflow-hidden bg-[#0d0d0d] border border-[#00ff41] shadow-[0_0_15px_rgba(0,255,65,0.15)] max-w-xl mx-auto transition-transform hover:scale-[1.02] duration-500 group">
338
+ <div class="flex items-center justify-between px-4 py-2 bg-[#1a1a1a] border-b border-[#333]">
339
+ <div class="flex gap-2">
340
+ <div class="w-3 h-3 rounded-full bg-red-500/50"></div>
341
+ <div class="w-3 h-3 rounded-full bg-yellow-500/50"></div>
342
+ <div class="w-3 h-3 rounded-full bg-green-500/50"></div>
343
+ </div>
344
+ <span class="text-[10px] text-[#00ff41] font-mono opacity-70">// middleware.js</span>
345
+ </div>
346
+
347
+ <div class="p-6 font-mono text-xs md:text-sm leading-relaxed overflow-x-auto text-left">
348
+ <div class="text-gray-400">
349
+ <span class="text-[#c678dd]">const</span> <span class="text-[#61afef]">checkCompatibility</span> = (<span class="text-[#d19a66]">system</span>) ={'>'} {'{'}
350
+ </div>
351
+ <div class="pl-4">
352
+ <span class="text-[#c678dd]">if</span> (
353
+ <span class="text-[#e06c75]">Legacy_Systems</span> &&
354
+ <span class="text-[#e06c75]">Future_AI</span>
355
+ ) {'{'}
356
+ </div>
357
+ <div class="pl-8 text-[#98c379]">
358
+ return <span class="text-[#e06c75]">"Matteo Bergamelli"</span>;
359
+ </div>
360
+ <div class="pl-4">
361
+ {'}'} <span class="text-[#c678dd]">else</span> {'{'}
362
+ </div>
363
+ <div class="pl-8 text-[#98c379]">
364
+ return <span class="text-red-400">"Gap Tecnologico"</span>;
365
+ </div>
366
+ <div class="pl-4">{'}'}</div>
367
+ <div>{'}'};</div>
368
+ </div>
369
+
370
+ <!-- Blink Cursor -->
371
+ <div class="absolute bottom-6 right-6 w-2 h-4 bg-[#00ff41] animate-pulse"></div>
372
+
373
+ <!-- Easter Egg Copy -->
374
+ <button onclick="copyCodeEasterEgg()" class="absolute top-14 right-4 text-[10px] text-[#00ff41] bg-black/80 px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity border border-[#00ff41]">COPY</button>
375
+ </div>
376
+
377
+ <p class="text-center text-sm md:text-base leading-relaxed opacity-90 mt-8 font-mono">
378
+ La vostra Job Description <span class="text-[#00ff41] font-bold">(ID 247442889)</span> cerca qualcuno che unisca questi mondi.
379
+ <br />
380
+ <span class="font-serif text-xl md:text-2xl font-bold mt-6 block text-white">
381
+ Io sono quel connettore.
382
+ </span>
383
+ </p>
384
+
385
+ <div class="mt-12 p-6 bg-[#0a0a0a]/80 rounded-lg border border-[#333] backdrop-blur-sm text-center">
386
+ <p class="text-xs font-mono opacity-60 mb-4 text-[#00ff41]">// CURRENT STACK</p>
387
+ <div class="flex flex-wrap justify-center gap-2">
388
+ <span class="px-3 py-1 bg-[#151515] border border-[#00ff41]/40 rounded text-xs font-mono text-[#00ff41] hover:bg-[#00ff41] hover:text-black transition-colors cursor-default">Python</span>
389
+ <span class="px-3 py-1 bg-[#151515] border border-[#00ff41]/40 rounded text-xs font-mono text-[#00ff41] hover:bg-[#00ff41] hover:text-black transition-colors cursor-default">SAP B1</span>
390
+ <span class="px-3 py-1 bg-[#151515] border border-[#00ff41]/40 rounded text-xs font-mono text-[#00ff41] hover:bg-[#00ff41] hover:text-black transition-colors cursor-default">SQL Server</span>
391
+ <span class="px-3 py-1 bg-[#151515] border border-[#00ff41]/40 rounded text-xs font-mono text-[#00ff41] hover:bg-[#00ff41] hover:text-black transition-colors cursor-default">LLM Agents</span>
392
+ <span class="px-3 py-1 bg-[#151515] border border-[#00ff41]/40 rounded text-xs font-mono text-[#00ff41] hover:bg-[#00ff41] hover:text-black transition-colors cursor-default">Spark AR</span>
393
+ <span class="px-3 py-1 bg-[#151515] border border-[#00ff41]/40 rounded text-xs font-mono text-[#00ff41] hover:bg-[#00ff41] hover:text-black transition-colors cursor-default">React</span>
394
+ </div>
395
+ </div>
396
+ </div>
397
+ </section>
398
+
399
+ <!-- FOOTER -->
400
+ <section class="px-6 py-20 bg-black relative z-10">
401
+ <div class="max-w-2xl mx-auto text-center reveal-on-scroll">
402
+ <h2 class="font-serif text-3xl md:text-4xl font-bold mb-12">
403
+ Iniziamo a <span class="text-[#00ff41]">connettere</span>?
404
+ </h2>
405
+
406
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-16">
407
+ <a href="./CV.pdf" class="group flex items-center justify-center gap-2 px-6 py-4 bg-[#00ff41] text-black font-mono text-sm font-bold rounded hover:bg-transparent hover:text-[#00ff41] border border-[#00ff41] transition-all">
408
+ <span class="group-hover:translate-x-1 transition-transform">📄 SCARICA CV TECNICO</span>
409
+ </a>
410
+ <a href="tel:+393428194066" class="flex items-center justify-center gap-2 px-6 py-4 bg-transparent text-[#f5f5f5] font-mono text-sm border border-[#333] rounded hover:border-[#00ff41] hover:text-[#00ff41] transition-all">
411
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg>
412
+ Chiama Matteo
413
+ </a>
414
+ <a href="mailto:matteo.bergamelli1989@gmail.com" class="flex items-center justify-center gap-2 px-6 py-4 bg-transparent text-[#f5f5f5] font-mono text-sm border border-[#333] rounded hover:border-[#00ff41] hover:text-[#00ff41] transition-all">
415
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg>
416
+ Email
417
+ </a>
418
+ </div>
419
+
420
+ <div class="pt-8 border-t border-[#333] text-left md:text-center">
421
+ <p class="font-mono text-[10px] md:text-xs opacity-40 leading-relaxed uppercase tracking-widest">
422
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br/>
423
+ ONIVERSE PHYGITAL EXPERIENCE<br/>
424
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br/><br/>
425
+ Printed at: Padenghe s/G<br/>
426
+ Cost: 0€<br/>
427
+ Value: <span class="text-[#00ff41]">Infinite</span><br/><br/>
428
+ Promotica S.p.A | Freelance AI Dev<br/>
429
+ Made with ❤️ and <span class="text-[#00ff41]">Code</span><br/><br/>
430
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
431
+ </p>
432
+ </div>
433
+ </div>
434
+ </section>
435
+ </div>
436
+ <script>
437
+ /* ==========================================
438
+ 0. EASTER EGGS & NERD STUFF
439
+ ========================================== */
440
+
441
+ // A) Console ASCII Art (First place devs look)
442
+ console.log(`%c
443
+ ███╗ ███╗██████╗
444
+ ████╗ ████║██╔══██╗
445
+ ██╔████╔██║██████╔╝
446
+ ██║╚██╔╝██║██╔══██╗
447
+ ██║ ╚═╝ ██║██████╔╝
448
+ ╚═╝ ╚═╝╚═════╝
449
+ %c> Ciao Dev di Oniverse.
450
+ > Se stai leggendo questo, stiamo parlando la stessa lingua.
451
+ > Stack: React, Python, AI, AR.
452
+ > Status: Ready to deploy.
453
+ `, "color: #00ff41; font-weight: bold; font-family: monospace;", "color: #f5f5f5; font-family: monospace;");
454
+
455
+ // B) Konami Code (The classic) -> Triggers Matrix Rain
456
+ let konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
457
+ let konamiIndex = 0;
458
+
459
+ document.addEventListener('keydown', (e) => {
460
+ if (e.key.toLowerCase() === konamiCode[konamiIndex].toLowerCase() || e.key === konamiCode[konamiIndex]) {
461
+ konamiIndex++;
462
+ if (konamiIndex === konamiCode.length) {
463
+ activateMatrixMode();
464
+ konamiIndex = 0;
465
+ }
466
+ } else {
467
+ konamiIndex = 0;
468
+ }
469
+ });
470
+
471
+ function activateMatrixMode() {
472
+ alert("🔓 GOD MODE ACTIVATED: You found the secret!");
473
+ startMatrixRain();
474
+ }
475
+
476
+ // C) Matrix Rain Canvas Logic
477
+ function startMatrixRain() {
478
+ const canvas = document.getElementById('matrix-canvas');
479
+ const ctx = canvas.getContext('2d');
480
+ canvas.width = window.innerWidth;
481
+ canvas.height = window.innerHeight;
482
+
483
+ canvas.classList.add('matrix-active');
484
+
485
+ const chars = "01010101MATTEOBERGAMELLIONIVERSEINNOVATIONLAB";
486
+ const fontSize = 14;
487
+ const columns = canvas.width / fontSize;
488
+ const drops = [];
489
+ for(let x = 0; x < columns; x++) drops[x] = 1;
490
+
491
+ function draw() {
492
+ ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
493
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
494
+ ctx.fillStyle = "#00ff41";
495
+ ctx.font = fontSize + "px monospace";
496
+
497
+ for(let i = 0; i < drops.length; i++) {
498
+ const text = chars.charAt(Math.floor(Math.random() * chars.length));
499
+ ctx.fillText(text, i * fontSize, drops[i] * fontSize);
500
+ if(drops[i] * fontSize > canvas.height && Math.random() > 0.975) drops[i] = 0;
501
+ drops[i]++;
502
+ }
503
+ requestAnimationFrame(draw);
504
+ }
505
+ draw();
506
+ }
507
+
508
+ // D) Ripple Effect on Click (Physical Touch visual feedback)
509
+ document.addEventListener('click', (e) => {
510
+ // Don't trigger on interactive elements to avoid confusion
511
+ if(e.target.closest('button') || e.target.closest('a') || e.target.closest('#slider-container')) return;
512
+
513
+ const ripple = document.createElement('div');
514
+ ripple.className = 'ripple';
515
+ ripple.style.left = e.clientX + 'px';
516
+ ripple.style.top = e.clientY + 'px';
517
+ // Size based on viewport
518
+ const size = Math.max(window.innerWidth, window.innerHeight) / 10;
519
+ ripple.style.width = ripple.style.height = size + 'px';
520
+ ripple.style.marginTop = ripple.style.marginLeft = -(size/2) + 'px';
521
+ document.body.appendChild(ripple);
522
+
523
+ setTimeout(() => ripple.remove(), 600);
524
+ });
525
+
526
+ // E) Copy Code Easter Egg
527
+ window.copyCodeEasterEgg = function() {
528
+ navigator.clipboard.writeText("function bridgeLegacyAndAI() { return 'Matteo Bergamelli'; }");
529
+ alert("📋 Copied to clipboard: A secret function just for you.");
530
+ }
531
+
532
+ /* ==========================================
533
+ 1. TERMINAL LOADER LOGIC
534
+ ========================================== */
535
+ const terminalLines = [
536
+ "> CONNECTING TO INNOVATION LAB...",
537
+ "> ANALYZING STACK: PYTHON, SAP, AI...",
538
+ "> DETECTING PHYSICAL & DIGITAL ASSETS...",
539
+ "> SYNCING NEURAL MESH...",
540
+ "> ACCESS GRANTED."
541
+ ];
542
+
543
+ const terminalEl = document.getElementById('terminal-lines');
544
+ let lineIndex = 0;
545
+
546
+ function typeWriter() {
547
+ if (lineIndex < terminalLines.length) {
548
+ const div = document.createElement('div');
549
+ div.className = "mb-2 text-[#00ff41] drop-shadow-[0_0_5px_rgba(0,255,65,0.8)] opacity-0 transition-opacity duration-300";
550
+ div.textContent = terminalLines[lineIndex];
551
+ terminalEl.appendChild(div);
552
+
553
+ void div.offsetWidth; // Reflow
554
+ div.style.opacity = "1";
555
+
556
+ lineIndex++;
557
+ setTimeout(typeWriter, 600);
558
+ } else {
559
+ // Finished
560
+ setTimeout(() => {
561
+ document.getElementById('terminal-loader').style.opacity = '0';
562
+ document.getElementById('main-content').style.opacity = '1';
563
+ document.getElementById('canvas-container').style.opacity = '1';
564
+ document.getElementById('status-bar').style.opacity = '1';
565
+
566
+ // Decrypt Job ID
567
+ scrambleText(document.getElementById('job-id-scramble'), "247442889");
568
+
569
+ setTimeout(() => {
570
+ document.getElementById('terminal-loader').style.display = 'none';
571
+ }, 500);
572
+ }, 800);
573
+ }
574
+ }
575
+
576
+ // Text Scrambler Function
577
+ function scrambleText(element, finalString) {
578
+ let iterations = 0;
579
+ const possible = "0123456789XYK@#%";
580
+ const interval = setInterval(() => {
581
+ element.innerText = finalString
582
+ .split("")
583
+ .map((letter, index) => {
584
+ if (index < iterations) return finalString[index];
585
+ return possible[Math.floor(Math.random() * possible.length)];
586
+ })
587
+ .join("");
588
+
589
+ if (iterations >= finalString.length) clearInterval(interval);
590
+ iterations += 1/3;
591
+ }, 30);
592
+ }
593
+
594
+ window.addEventListener('load', typeWriter);
595
+
596
+
597
+ /* ==========================================
598
+ 2. THREE.JS BACKGROUND (Digital Fabric)
599
+ ========================================== */
600
+ function initThreeJS() {
601
+ const container = document.getElementById('canvas-container');
602
+ const scene = new THREE.Scene();
603
+ const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
604
+ camera.position.set(0, 5, 10);
605
+ camera.lookAt(0, 0, 0);
606
+
607
+ const renderer = new THREE.WebGLRenderer({ antialias: false, alpha: true });
608
+ renderer.setSize(window.innerWidth, window.innerHeight);
609
+ renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
610
+ container.appendChild(renderer.domElement);
611
+
612
+ // Create Particles
613
+ const particleCount = 12000;
614
+ const geometry = new THREE.BufferGeometry();
615
+ const positions = new Float32Array(particleCount * 3);
616
+
617
+ const size = 20;
618
+ const gap = 0.2;
619
+ const rows = Math.sqrt(particleCount);
620
+
621
+ for (let i = 0; i < particleCount; i++) {
622
+ const row = Math.floor(i / rows);
623
+ const col = i % rows;
624
+
625
+ const x = (col * gap) - (rows * gap) / 2;
626
+ const z = (row * gap) - (rows * gap) / 2;
627
+
628
+ positions[i * 3] = x;
629
+ positions[i * 3 + 1] = 0;
630
+ positions[i * 3 + 2] = z;
631
+ }
632
+
633
+ geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
634
+
635
+ const material = new THREE.PointsMaterial({
636
+ size: 0.05,
637
+ color: 0x00ff41,
638
+ transparent: true,
639
+ opacity: 0.5,
640
+ sizeAttenuation: true,
641
+ blending: THREE.AdditiveBlending
642
+ });
643
+
644
+ const points = new THREE.Points(geometry, material);
645
+ scene.add(points);
646
+
647
+ // Interaction
648
+ let mouseX = 0;
649
+ let mouseY = 0;
650
+
651
+ document.addEventListener('mousemove', (event) => {
652
+ mouseX = (event.clientX / window.innerWidth) * 2 - 1;
653
+ mouseY = -(event.clientY / window.innerHeight) * 2 + 1;
654
+ });
655
+
656
+ // Animation Loop
657
+ const clock = new THREE.Clock();
658
+
659
+ function animate() {
660
+ requestAnimationFrame(animate);
661
+
662
+ const time = clock.getElapsedTime();
663
+ const positions = points.geometry.attributes.position.array;
664
+
665
+ for (let i = 0; i < particleCount; i++) {
666
+ const x = positions[i * 3];
667
+ const z = positions[i * 3 + 2];
668
+
669
+ // Wave equation + Mouse Interaction influence
670
+ // (Subtle distortion based on mouse position)
671
+ const mouseDist = Math.sqrt((x - mouseX * 5)**2 + (z - mouseY * 5)**2);
672
+ const interaction = Math.max(0, 3 - mouseDist) * 0.2;
673
+
674
+ const y =
675
+ Math.sin(x * 0.5 + time * 0.5) * 1.5 +
676
+ Math.sin(z * 0.3 + time * 0.3) * 1.5 +
677
+ Math.sin((x + z) * 0.2 + time) * 0.5 +
678
+ Math.sin(time * 2 + mouseDist) * interaction; // Interactive ripple
679
+
680
+ positions[i * 3 + 1] = y;
681
+ }
682
+
683
+ points.geometry.attributes.position.needsUpdate = true;
684
+ points.rotation.y = time * 0.05;
685
+
686
+ renderer.render(scene, camera);
687
+ }
688
+
689
+ animate();
690
+
691
+ window.addEventListener('resize', () => {
692
+ camera.aspect = window.innerWidth / window.innerHeight;
693
+ camera.updateProjectionMatrix();
694
+ renderer.setSize(window.innerWidth, window.innerHeight);
695
+ });
696
+ }
697
+
698
+ initThreeJS();
699
+
700
+
701
+ /* ==========================================
702
+ 3. SCROLL REVEAL ANIMATIONS
703
+ ========================================== */
704
+ const observer = new IntersectionObserver((entries) => {
705
+ entries.forEach(entry => {
706
+ if (entry.isIntersecting) {
707
+ entry.target.classList.add('visible');
708
+ }
709
+ });
710
+ }, { threshold: 0.1 });
711
+
712
+ document.querySelectorAll('.reveal-on-scroll').forEach(el => observer.observe(el));
713
+
714
+
715
+ /* ==========================================
716
+ 4. UNLOCK SLIDER LOGIC
717
+ ========================================== */
718
+ const sliderHandle = document.getElementById('slider-handle');
719
+ const sliderFill = document.getElementById('slider-fill');
720
+ const sliderText = document.getElementById('slider-text');
721
+ const iconArrow = document.getElementById('icon-arrow');
722
+ const iconLock = document.getElementById('icon-lock');
723
+
724
+ let isDragging = false;
725
+ let startX = 0;
726
+ let currentX = 0;
727
+ const maxDrag = 260;
728
+
729
+ function playClickSound() {
730
+ // Very short oscillator beep using Web Audio API (no external file needed)
731
+ const AudioContext = window.AudioContext || window.webkitAudioContext;
732
+ if (AudioContext) {
733
+ const audioCtx = new AudioContext();
734
+ const oscillator = audioCtx.createOscillator();
735
+ const gainNode = audioCtx.createGain();
736
+ oscillator.connect(gainNode);
737
+ gainNode.connect(audioCtx.destination);
738
+ oscillator.type = 'sine';
739
+ oscillator.frequency.value = 800;
740
+ gainNode.gain.setValueAtTime(0.05, audioCtx.currentTime);
741
+ gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.1);
742
+ oscillator.start();
743
+ oscillator.stop(audioCtx.currentTime + 0.1);
744
+ }
745
+ }
746
+
747
+ sliderHandle.addEventListener('mousedown', startDrag);
748
+ window.addEventListener('mousemove', drag);
749
+ window.addEventListener('mouseup', endDrag);
750
+ sliderHandle.addEventListener('touchstart', (e) => startDrag(e.touches[0]));
751
+ window.addEventListener('touchmove', (e) => drag(e.touches[0]));
752
+ window.addEventListener('touchend', endDrag);
753
+
754
+ function startDrag(e) {
755
+ isDragging = true;
756
+ startX = e.clientX;
757
+ sliderHandle.style.transition = 'none';
758
+ sliderFill.style.transition = 'none';
759
+ playClickSound();
760
+ }
761
+
762
+ function drag(e) {
763
+ if (!isDragging) return;
764
+ let x = e.clientX - startX;
765
+ if (x < 0) x = 0;
766
+ if (x > maxDrag) x = maxDrag;
767
+ currentX = x;
768
+ updateSliderUI(x);
769
+ }
770
+
771
+ function endDrag() {
772
+ if (!isDragging) return;
773
+ isDragging = false;
774
+ if (currentX > maxDrag * 0.85) {
775
+ updateSliderUI(maxDrag);
776
+ unlockSuccess();
777
+ } else {
778
+ sliderHandle.style.transition = 'left 0.3s ease';
779
+ sliderFill.style.transition = 'width 0.3s ease, opacity 0.3s ease';
780
+ updateSliderUI(0);
781
+ }
782
+ }
783
+
784
+ function updateSliderUI(x) {
785
+ sliderHandle.style.left = `${x}px`;
786
+ const percentage = (x / maxDrag);
787
+ sliderFill.style.width = `${x + 40}px`;
788
+ sliderFill.style.opacity = 0.1 + (percentage * 0.3);
789
+ sliderText.style.opacity = 1 - (percentage * 1.5);
790
+ }
791
+
792
+ function unlockSuccess() {
793
+ playClickSound();
794
+ iconArrow.classList.add('hidden');
795
+ iconLock.classList.remove('hidden');
796
+ sliderHandle.style.borderColor = '#00ff41';
797
+ sliderHandle.style.backgroundColor = '#00ff41';
798
+ iconLock.style.stroke = 'black';
799
+ // CHANGE: Redirect instead of starting AR
800
+ setTimeout(() => window.location.href = './index_old.html', 500);
801
+ }
802
+
803
+
804
+ /* ==========================================
805
+ 5. AR EXPERIENCE LOGIC
806
+ ========================================== */
807
+ const arContainer = document.getElementById('ar-container');
808
+ const closeArBtn = document.getElementById('close-ar-btn');
809
+ const arStatusBox = document.getElementById('ar-status-box');
810
+
811
+ function startAR() {
812
+ arContainer.style.display = 'block';
813
+ const arScene = document.querySelector('a-scene');
814
+ if (arScene && arScene.systems['mindar-image-system']) {
815
+ arScene.systems['mindar-image-system'].start();
816
+ }
817
+
818
+ const targetEl = document.getElementById('target-entity');
819
+ const arVideo = document.getElementById('ar-video');
820
+
821
+ if (targetEl) {
822
+ targetEl.addEventListener('targetFound', () => {
823
+ arStatusBox.innerHTML = `
824
+ <span class="relative flex h-3 w-3"><span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-[#00ff41] opacity-75"></span><span class="relative inline-flex rounded-full h-3 w-3 bg-[#00ff41]"></span></span>
825
+ <span class="text-sm font-mono font-bold tracking-widest text-[#00ff41]">SIGNAL LOCKED</span>
826
+ `;
827
+ arStatusBox.classList.add('bg-[#00ff41]/10', 'border-[#00ff41]');
828
+ arStatusBox.classList.remove('bg-black/60', 'text-white/60');
829
+ if(arVideo) arVideo.play();
830
+ });
831
+
832
+ targetEl.addEventListener('targetLost', () => {
833
+ arStatusBox.innerHTML = `
834
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="animate-pulse"><path d="M3 7V5a2 2 0 0 1 2-2h2"></path><path d="M17 3h2a2 2 0 0 1 2 2v2"></path><path d="M21 17v2a2 2 0 0 1-2 2h-2"></path><path d="M7 21H5a2 2 0 0 1-2-2v-2"></path></svg>
835
+ <span class="text-sm font-mono tracking-widest">SCANNING TARGET...</span>
836
+ `;
837
+ arStatusBox.classList.remove('bg-[#00ff41]/10', 'border-[#00ff41]');
838
+ arStatusBox.classList.add('bg-black/60', 'text-white/60');
839
+ if(arVideo) arVideo.pause();
840
+ });
841
+ }
842
+ }
843
+
844
+ closeArBtn.addEventListener('click', () => {
845
+ arContainer.style.display = 'none';
846
+ const arScene = document.querySelector('a-scene');
847
+ if (arScene && arScene.systems['mindar-image-system']) {
848
+ arScene.systems['mindar-image-system'].stop();
849
+ }
850
+ const videoFeed = document.querySelector('.mindar-ui-overlay');
851
+ if (videoFeed) videoFeed.remove();
852
+
853
+ // Reset slider
854
+ isDragging = false;
855
+ currentX = 0;
856
+ iconArrow.classList.remove('hidden');
857
+ iconLock.classList.add('hidden');
858
+ sliderHandle.style.backgroundColor = '#0d0d0d';
859
+ sliderHandle.style.left = '0px';
860
+ sliderFill.style.width = '0px';
861
+ sliderFill.style.opacity = '0.1';
862
+ sliderText.style.opacity = '1';
863
+ });
864
+
865
+ </script>
866
+ </body>
867
+ </html>