File size: 10,963 Bytes
1d0c7e9
 
 
 
 
b71c87f
 
7d29ac3
b71c87f
 
 
 
 
 
 
 
 
 
1d0c7e9
 
b71c87f
1d0c7e9
7d29ac3
1d0c7e9
3b9a846
 
 
 
 
 
 
1d0c7e9
 
7d29ac3
 
 
3b9a846
7d29ac3
1d0c7e9
 
b71c87f
6857c5a
b71c87f
 
6857c5a
b71c87f
 
 
 
 
8bcf7b6
 
b71c87f
 
 
 
8bcf7b6
b71c87f
8bcf7b6
b71c87f
 
6857c5a
8bcf7b6
 
b71c87f
 
 
 
8bcf7b6
b71c87f
 
 
 
6857c5a
16dd4d1
b71c87f
 
 
 
16dd4d1
b71c87f
 
6857c5a
b71c87f
 
16dd4d1
b71c87f
 
 
 
6857c5a
16dd4d1
1d0c7e9
 
7d29ac3
b71c87f
 
 
 
 
 
 
 
 
6857c5a
 
 
 
 
 
 
16dd4d1
 
 
6857c5a
 
 
 
 
8bcf7b6
6857c5a
 
 
8bcf7b6
6857c5a
 
8bcf7b6
6857c5a
 
 
 
 
1d0c7e9
 
7d29ac3
1d0c7e9
6857c5a
 
 
 
 
3b9a846
6857c5a
 
3b9a846
6857c5a
 
3b9a846
 
1d0c7e9
 
b71c87f
 
 
 
8bcf7b6
b71c87f
7d29ac3
b71c87f
 
 
 
 
 
 
 
 
 
 
6857c5a
 
b71c87f
 
 
 
 
8bcf7b6
b71c87f
 
 
 
 
c6b8906
b71c87f
 
 
6857c5a
b71c87f
 
6857c5a
b71c87f
 
c6b8906
b71c87f
 
c6b8906
b71c87f
 
6857c5a
b71c87f
 
 
c6b8906
b71c87f
 
 
 
 
 
 
 
 
1d0c7e9
6857c5a
b71c87f
 
 
 
 
 
 
 
 
1d0c7e9
b71c87f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1d0c7e9
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="theme-color" content="#0f0f1a">
    <meta name="description" content="Algorithmic Ecstasy - A sensory experience combining visuals, sound, and rhythm">
    <title>CipherEcstasy - Algorithmic Ecstasy</title>
    
    <!-- PWA Manifest -->
    <link rel="manifest" href="/manifest.json">
    
    <!-- Favicon -->
    <link rel="icon" href="/favicon.ico" sizes="any">
    <link rel="icon" href="/icon.svg" type="image/svg+xml">
    <link rel="apple-touch-icon" href="/apple-touch-icon.png">
    
    <!-- Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700&display=swap');
        
        :root {
            --cool-blue: #38bdf8;
            --warm-amber: #f59e0b;
            --electric-purple: #8b5cf6;
            --deep-space: #0f0f1a;
        }
        
        body {
            font-family: 'Inter', sans-serif;
            margin: 0;
            padding: 0;
            overflow-x: hidden;
            background-color: var(--deep-space);
            color: #e0e0ff;
        }
        
        /* ... (all previous CSS styles remain unchanged) ... */

        /* PWA Install Prompt */
        .pwa-install-prompt {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(15, 15, 26, 0.95);
            border: 1px solid var(--electric-purple);
            border-radius: 8px;
            padding: 15px;
            width: 90%;
            max-width: 400px;
            z-index: 1001;
            display: none;
            backdrop-filter: blur(5px);
            box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5);
        }
        
        .pwa-install-prompt p {
            margin-bottom: 10px;
            color: var(--cool-blue);
        }
        
        .pwa-install-buttons {
            display: flex;
            gap: 10px;
        }
        
        .pwa-install-btn {
            flex: 1;
            padding: 8px;
            border-radius: 4px;
            cursor: pointer;
            font-family: 'Orbitron', sans-serif;
            font-size: 0.8rem;
            text-transform: uppercase;
            letter-spacing: 1px;
        }
        
        .pwa-install-confirm {
            background: rgba(56, 189, 248, 0.2);
            border: 1px solid var(--cool-blue);
            color: var(--cool-blue);
        }
        
        .pwa-install-cancel {
            background: rgba(30, 30, 45, 0.8);
            border: 1px solid var(--warm-amber);
            color: var(--warm-amber);
        }
    </style>
</head>
<body>
    <!-- PWA Install Prompt -->
    <div class="pwa-install-prompt" id="pwa-install-prompt">
        <p>Install CipherEcstasy for full immersive experience?</p>
        <div class="pwa-install-buttons">
            <button class="pwa-install-btn pwa-install-confirm" id="pwa-install-confirm">Install</button>
            <button class="pwa-install-btn pwa-install-cancel" id="pwa-install-cancel">Later</button>
        </div>
    </div>

    <!-- User Profile Indicator -->
    <div class="user-profile" id="user-profile">
        <i class="fas fa-user"></i>
        <div class="user-menu">
            <div class="user-email" id="user-email">Not logged in</div>
            <button id="show-journey"><i class="fas fa-compass"></i> Sensory Journey</button>
            <button id="logout-btn"><i class="fas fa-sign-out-alt"></i> Log Out</button>
        </div>
    </div>

    <!-- Sensory Journey Panel -->
    <div class="journey-container" id="journey-container">
        <div class="journey-header">
            <h3><i class="fas fa-compass"></i> Sensory Journey</h3>
            <button class="journey-toggle" id="hide-journey"><i class="fas fa-times"></i></button>
        </div>
        <div class="journey-form">
            <input type="text" id="journey-input" placeholder="Describe your journey (e.g. 'warmth, thunder, silk')">
            <button id="generate-journey"><i class="fas fa-bolt"></i> Generate Experience</button>
        </div>
        <div class="journey-loading" id="journey-loading">
            <i class="fas fa-spinner"></i> Crafting your journey...
        </div>
        <div class="journey-result" id="journey-result">
            <h4>Your Journey:</h4>
            <p id="journey-text"></p>
            <div class="mt-2">
                <button id="apply-journey" class="text-xs">Apply Settings</button>
            </div>
        </div>
    </div>

    <!-- Auth Modal -->
    <div class="auth-modal" id="auth-modal">
        <div class="auth-container">
            <h2>Algorithmic Ecstasy</h2>
            <p class="text-gray-400 mb-6">Enter your email to begin the experience</p>
            
            <input type="email" id="auth-email" class="auth-input" placeholder="your@email.com">
            <button id="send-magic-link" class="auth-btn">Send Magic Link</button>
            
            <div class="magic-link-sent" id="magic-link-sent">
                <i class="fas fa-check-circle"></i> Magic link sent to your email!
            </div>
        </div>
    </div>

    <!-- Main Content (keep all your existing content) -->
    <div class="container mx-auto px-4 py-12">
        <!-- ... (your existing content remains unchanged) ... -->
    </div>

    <!-- Service Worker Registration -->
    <script>
        // Register Service Worker for PWA
        if ('serviceWorker' in navigator) {
            window.addEventListener('load', () => {
                navigator.serviceWorker.register('/sw.js')
                    .then(registration => {
                        console.log('ServiceWorker registration successful with scope: ', registration.scope);
                    })
                    .catch(err => {
                        console.log('ServiceWorker registration failed: ', err);
                    });
            });
        }

        // PWA Install Prompt Logic
        let deferredPrompt;
        const pwaInstallPrompt = document.getElementById('pwa-install-prompt');
        const pwaInstallConfirm = document.getElementById('pwa-install-confirm');
        const pwaInstallCancel = document.getElementById('pwa-install-cancel');

        window.addEventListener('beforeinstallprompt', (e) => {
            // Prevent the mini-infobar from appearing on mobile
            e.preventDefault();
            // Stash the event so it can be triggered later
            deferredPrompt = e;
            
            // Show our custom install prompt
            pwaInstallPrompt.style.display = 'block';
        });

        pwaInstallConfirm.addEventListener('click', async () => {
            if (!deferredPrompt) return;
            
            // Show the install prompt
            deferredPrompt.prompt();
            
            // Wait for the user to respond to the prompt
            const { outcome } = await deferredPrompt.userChoice;
            
            // Hide our custom prompt
            pwaInstallPrompt.style.display = 'none';
            
            // We've used the prompt, and can't use it again
            deferredPrompt = null;
        });

        pwaInstallCancel.addEventListener('click', () => {
            pwaInstallPrompt.style.display = 'none';
        });

        // Track PWA installation
        window.addEventListener('appinstalled', () => {
            console.log('PWA was installed');
            pwaInstallPrompt.style.display = 'none';
            deferredPrompt = null;
        });

        // Check if running as PWA
        function isRunningAsPWA() {
            return window.matchMedia('(display-mode: standalone)').matches || 
                   window.navigator.standalone ||
                   document.referrer.includes('android-app://');
        }

        // All previous JavaScript remains unchanged
        // ... (keep all your existing JavaScript code) ...
    </script>

    <!-- Docker and Kubernetes deployment instructions (commented out in HTML) -->
    <!--
        Dockerfile:
        ===========
        # Use Node.js as base image
        FROM node:18-alpine as builder
        
        # Create app directory
        WORKDIR /app
        
        # Install dependencies
        COPY package*.json ./
        RUN npm install
        
        # Bundle app source
        COPY . .
        
        # Build the app
        RUN npm run build
        
        # Production stage
        FROM nginx:alpine
        COPY --from=builder /app/dist /usr/share/nginx/html
        COPY nginx.conf /etc/nginx/nginx.conf
        
        EXPOSE 80
        CMD ["nginx", "-g", "daemon off;"]
        
        
        Kubernetes Deployment (deployment.yaml):
        =======================================
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: cipherecstasy
          labels:
            app: cipherecstasy
        spec:
          replicas: 3
          selector:
            matchLabels:
              app: cipherecstasy
          template:
            metadata:
              labels:
                app: cipherecstasy
            spec:
              containers:
              - name: cipherecstasy
                image: your-registry/cipherecstasy:latest
                ports:
                - containerPort: 80
                resources:
                  requests:
                    cpu: "100m"
                    memory: "128Mi"
                  limits:
                    cpu: "500m"
                    memory: "512Mi"
              restartPolicy: Always
              
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: cipherecstasy-service
        spec:
          selector:
            app: cipherecstasy
          ports:
            - protocol: TCP
              port: 80
              targetPort: 80
          type: LoadBalancer
    -->
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Boobs00/cipherecstasy" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>