openfree commited on
Commit
35f212d
Β·
verified Β·
1 Parent(s): aa7324d

Update dna-slot-machine.html

Browse files
Files changed (1) hide show
  1. dna-slot-machine.html +597 -307
dna-slot-machine.html CHANGED
@@ -3,8 +3,10 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>DNA Slot Machine</title>
7
  <style>
 
 
8
  * {
9
  margin: 0;
10
  padding: 0;
@@ -12,9 +14,9 @@
12
  }
13
 
14
  body {
15
- background: #0a0a0a;
16
  color: #fff;
17
- font-family: 'Courier New', monospace;
18
  overflow-x: hidden;
19
  display: flex;
20
  flex-direction: column;
@@ -25,7 +27,32 @@
25
  padding-top: 10px;
26
  }
27
 
 
28
  body::before {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  content: '';
30
  position: fixed;
31
  top: 0;
@@ -46,164 +73,253 @@
46
  rgba(0,0,0,0.05) 1px,
47
  transparent 1px,
48
  transparent 2px
49
- ),
50
- repeating-linear-gradient(
51
- 45deg,
52
- transparent 0px,
53
- rgba(255,255,255,0.03) 1px,
54
- transparent 2px,
55
- transparent 3px
56
- ),
57
- repeating-linear-gradient(
58
- -45deg,
59
- transparent 0px,
60
- rgba(0,0,0,0.03) 1px,
61
- transparent 2px,
62
- transparent 3px
63
  );
64
- background-size: 2px 2px, 2px 2px, 3px 3px, 3px 3px;
65
  pointer-events: none;
66
  z-index: 1;
67
  opacity: 0.8;
68
  animation: staticNoise 0.1s steps(8) infinite;
69
  }
70
 
71
- body::after {
72
- content: '';
73
- position: fixed;
74
- top: 0;
75
- left: 0;
76
- width: 100%;
77
- height: 100%;
78
- background:
79
- radial-gradient(circle at 17% 23%, rgba(255,255,255,0.1) 0px, transparent 1px),
80
- radial-gradient(circle at 67% 71%, rgba(0,0,0,0.08) 0px, transparent 1px),
81
- radial-gradient(circle at 41% 57%, rgba(255,255,255,0.06) 0px, transparent 1px),
82
- radial-gradient(circle at 89% 13%, rgba(0,0,0,0.07) 0px, transparent 1px),
83
- radial-gradient(circle at 23% 89%, rgba(255,255,255,0.05) 0px, transparent 1px);
84
- background-size: 3px 3px, 2px 2px, 4px 4px, 2px 2px, 3px 3px;
85
- pointer-events: none;
86
- z-index: 1;
87
- animation: staticNoise 0.15s steps(10) infinite reverse;
88
- }
89
-
90
  @keyframes staticNoise {
91
  0%, 100% { transform: translate(0, 0); }
92
- 10% { transform: translate(-1px, -1px); }
93
- 20% { transform: translate(1px, 0px); }
94
- 30% { transform: translate(0px, 1px); }
95
- 40% { transform: translate(-1px, 1px); }
96
- 50% { transform: translate(1px, -1px); }
97
- 60% { transform: translate(-1px, 0px); }
98
- 70% { transform: translate(0px, -1px); }
99
- 80% { transform: translate(1px, 1px); }
100
- 90% { transform: translate(-1px, -1px); }
101
  }
102
 
 
103
  .machine-container {
104
- background: linear-gradient(145deg, #1a1a1a, #2d2d2d);
105
- border-radius: 20px;
106
- padding: 15px;
107
- padding-right: 100px;
108
- box-shadow: 0 20px 40px rgba(0,0,0,0.5),
109
- inset 0 2px 10px rgba(255,255,255,0.1);
 
 
 
110
  width: 95vw;
111
  max-width: 1400px;
112
  position: relative;
113
  z-index: 2;
114
  }
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  .title {
117
  text-align: center;
118
- font-size: 2rem;
119
- margin-bottom: 15px;
120
- font-weight: bold;
121
- letter-spacing: 0.1em;
 
 
122
  }
123
 
124
  .title a {
125
  text-decoration: none;
126
- background: linear-gradient(45deg, #00ff88, #00ffff, #ff00ff);
127
- -webkit-background-clip: text;
128
- -webkit-text-fill-color: transparent;
129
- text-shadow: 0 0 30px rgba(0,255,136,0.5);
130
- transition: all 0.3s ease;
 
 
 
 
 
 
131
  }
132
 
133
- .title a:hover {
134
- text-shadow: 0 0 40px rgba(0,255,136,0.7), 0 0 60px rgba(0,255,255,0.5);
 
 
135
  }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  .cell-type-selector {
138
  display: flex;
139
  align-items: center;
140
  justify-content: center;
141
  gap: 20px;
142
- margin-bottom: 15px;
143
- }
144
-
145
- .cell-type-label {
146
- font-size: 1.2rem;
147
- color: #ccc;
148
  }
149
 
150
  .radio-group {
151
  display: flex;
152
- gap: 20px;
153
  }
154
 
155
- .radio-label {
 
156
  display: flex;
157
  align-items: center;
158
- gap: 8px;
 
 
159
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  font-size: 1.1rem;
161
  color: #fff;
162
- transition: color 0.3s ease;
 
 
163
  }
164
 
165
- .radio-label:hover {
166
- color: #00ff88;
 
167
  }
168
 
169
- .radio-label input[type="radio"] {
170
- width: 18px;
171
- height: 18px;
172
- accent-color: #00ff88;
173
- cursor: pointer;
 
 
 
 
 
 
 
 
174
  }
175
 
 
 
 
 
 
 
176
  .reels-container {
177
  background: #000;
178
- border: 3px solid #333;
179
- border-radius: 10px;
180
- padding: 15px;
181
  max-width: 100%;
182
  position: relative;
183
- box-shadow: inset 0 0 20px rgba(0,0,0,0.5);
 
 
184
  overflow: visible;
 
185
  }
186
 
187
  .reels-wrapper {
188
  display: flex;
189
- gap: 1px;
190
  min-width: fit-content;
191
- padding: 3px 0;
192
  justify-content: center;
193
  flex-wrap: wrap;
194
  max-width: 1200px;
195
  margin: 0 auto;
 
 
 
 
196
  }
197
 
198
  .reel {
199
- width: 18px;
200
- height: 40px;
201
  background: #ffffff;
202
- border: 1px solid #ddd;
203
- border-radius: 2px;
204
  overflow: hidden;
205
  position: relative;
206
- box-shadow: inset 0 0 3px rgba(0,0,0,0.1);
 
 
207
  }
208
 
209
  .reel-strip {
@@ -213,305 +329,385 @@
213
  }
214
 
215
  .nucleotide {
216
- height: 40px;
217
  display: flex;
218
  align-items: center;
219
  justify-content: center;
220
- font-size: 0.9rem;
221
  font-weight: bold;
222
  background: #ffffff;
 
223
  }
224
 
225
- .nucleotide.A { color: #00ff00; }
226
- .nucleotide.T { color: #ff0000; }
227
- .nucleotide.C { color: #0000ff; }
228
- .nucleotide.G { color: #ffa500; }
229
 
230
- .controls {
231
- display: flex;
232
- flex-direction: column;
233
- align-items: center;
234
- gap: 15px;
235
- margin-top: 20px;
 
 
 
236
  }
237
 
238
- .spin-button {
239
- background: #4a4a4a;
240
- border: none;
241
- padding: 20px 60px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  font-size: 1.5rem;
243
  font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  border-radius: 50px;
245
  cursor: pointer;
246
  text-transform: uppercase;
247
- letter-spacing: 2px;
248
- box-shadow: 0 10px 20px rgba(0,0,0,0.5);
 
 
 
249
  transition: all 0.3s ease;
250
  color: #fff;
251
- text-shadow: 0 2px 4px rgba(0,0,0,0.3);
252
  position: relative;
253
  overflow: hidden;
 
254
  }
255
 
256
  .spin-button::before {
257
  content: '';
258
  position: absolute;
259
- top: 0;
260
- left: 0;
261
- width: 100%;
262
- height: 100%;
263
- background-image:
264
- radial-gradient(circle at 20% 30%, #00ff00 0px, transparent 2px),
265
- radial-gradient(circle at 80% 70%, #ff0000 0px, transparent 2px),
266
- radial-gradient(circle at 50% 50%, #0000ff 0px, transparent 2px),
267
- radial-gradient(circle at 30% 80%, #ffa500 0px, transparent 2px),
268
- radial-gradient(circle at 70% 20%, #00ff00 0px, transparent 2px),
269
- radial-gradient(circle at 10% 60%, #ff0000 0px, transparent 2px),
270
- radial-gradient(circle at 90% 40%, #0000ff 0px, transparent 2px),
271
- radial-gradient(circle at 40% 10%, #ffa500 0px, transparent 2px);
272
- background-size: 20px 20px, 25px 25px, 30px 30px, 15px 15px,
273
- 18px 18px, 22px 22px, 28px 28px, 24px 24px;
274
- opacity: 0.25;
275
- animation: nucleotideNoise 0.8s steps(6) infinite;
276
- }
277
-
278
- .spin-button::after {
279
- content: '';
280
- position: absolute;
281
- top: 0;
282
- left: 0;
283
- width: 100%;
284
- height: 100%;
285
- background-image:
286
- radial-gradient(circle at 60% 40%, #00ff00 0px, transparent 1px),
287
- radial-gradient(circle at 25% 75%, #ff0000 0px, transparent 1px),
288
- radial-gradient(circle at 85% 15%, #0000ff 0px, transparent 1px),
289
- radial-gradient(circle at 15% 25%, #ffa500 0px, transparent 1px);
290
- background-size: 10px 10px, 12px 12px, 14px 14px, 16px 16px;
291
- opacity: 0.2;
292
- animation: nucleotideNoise 1.2s steps(8) infinite reverse;
293
- }
294
-
295
- @keyframes nucleotideNoise {
296
- 0% { transform: translate(0, 0) scale(1); }
297
- 16% { transform: translate(-2px, 1px) scale(1.02); }
298
- 33% { transform: translate(1px, -2px) scale(0.98); }
299
- 50% { transform: translate(-1px, 2px) scale(1.01); }
300
- 66% { transform: translate(2px, -1px) scale(0.99); }
301
- 83% { transform: translate(-2px, -2px) scale(1.02); }
302
- 100% { transform: translate(1px, 1px) scale(1); }
303
- }
304
-
305
- .spin-button span {
306
- position: relative;
307
- z-index: 2;
308
  }
309
 
310
- .spin-button:hover {
311
- transform: translateY(-2px);
312
- box-shadow: 0 15px 30px rgba(0,0,0,0.6);
313
- background: #5a5a5a;
314
  }
315
 
316
- .spin-button:hover::before {
317
- opacity: 0.35;
318
- animation-duration: 0.4s;
 
 
319
  }
320
 
321
  .spin-button:active {
322
- transform: translateY(0);
323
  }
324
 
325
  .spin-button:disabled {
326
- background: #444;
327
  cursor: not-allowed;
328
  box-shadow: none;
 
329
  }
330
 
 
331
  .sequence-display {
332
- background: #0a0a0a;
333
- border: 2px solid #333;
334
- border-radius: 10px;
335
- padding: 20px 25px 12px 25px;
336
- font-family: 'Courier New', monospace;
337
  font-size: 0.9rem;
338
- letter-spacing: 1px;
339
  width: 100%;
340
  max-width: 1200px;
341
- text-align: left;
342
- word-wrap: break-word;
343
- line-height: 1.4;
 
344
  position: relative;
345
- margin: 0 auto;
346
  }
347
 
348
  .sequence-display::before {
349
- content: 'SYNTHETIC REGULATORY ELEMENT';
350
  position: absolute;
351
- top: -10px;
352
  left: 50%;
353
  transform: translateX(-50%);
354
- background: #0a0a0a;
355
- padding: 0 15px;
356
- font-size: 0.7rem;
357
- color: #00ff88;
358
- letter-spacing: 2px;
359
- white-space: nowrap;
360
  }
361
 
362
- .info {
363
- text-align: center;
364
- margin-top: 15px;
365
- color: #888;
366
- font-size: 0.9rem;
 
 
 
 
 
 
 
 
367
  }
368
 
369
- .lab-credit {
 
 
 
 
 
 
 
 
 
 
 
 
370
  text-align: center;
371
- margin-top: 10px;
372
- font-size: 1.1rem;
 
373
  }
374
 
375
- .lab-credit a {
376
- color: #00ff88;
377
- text-decoration: none;
378
- font-weight: bold;
379
- letter-spacing: 1px;
380
- transition: all 0.3s ease;
381
- padding: 5px 15px;
382
- border: 1px solid transparent;
383
- border-radius: 20px;
 
 
 
384
  }
385
 
386
- .lab-credit a:hover {
 
 
 
 
387
  color: #fff;
388
- border-color: #00ff88;
389
- box-shadow: 0 0 10px rgba(0,255,136,0.5);
390
- text-shadow: 0 0 5px rgba(0,255,136,0.5);
391
  }
392
 
393
- @keyframes pulse {
394
- 0% { opacity: 0.5; }
395
- 50% { opacity: 1; }
396
- 100% { opacity: 0.5; }
397
  }
398
 
399
- .spinning {
400
- animation: pulse 0.5s infinite;
 
 
 
401
  }
402
 
403
- .winning-flash {
404
- animation: winFlash 1s ease-out;
 
 
 
 
405
  }
406
 
407
- @keyframes winFlash {
408
- 0%, 100% { background-color: transparent; }
409
- 50% { background-color: rgba(0,255,136,0.2); }
 
 
410
  }
411
 
412
- .lever-container {
413
- position: absolute;
414
- right: -70px;
415
- top: 50%;
416
- transform: translateY(-50%);
417
- z-index: 3;
418
- width: 60px;
419
- height: 200px;
420
  }
421
 
422
- .lever {
423
- width: 100%;
424
- height: 100%;
425
- position: relative;
426
- cursor: pointer;
 
 
 
 
427
  }
428
 
429
- .lever-mount {
430
- position: absolute;
431
- top: 90px;
432
- left: -10px;
433
- width: 40px;
434
- height: 60px;
435
- background: linear-gradient(180deg, #555, #333);
436
- border-radius: 5px 0 0 5px;
437
- box-shadow:
438
- 0 3px 10px rgba(0,0,0,0.3),
439
- inset 0 1px 2px rgba(255,255,255,0.1);
440
  }
441
 
442
- .lever-pivot {
443
- position: absolute;
444
- bottom: 30px;
445
- left: 50%;
446
- transform: translateX(-50%);
447
- width: 30px;
448
- height: 8px;
449
- background: #888;
450
- border-radius: 4px;
451
- box-shadow: 0 2px 4px rgba(0,0,0,0.3);
 
452
  }
453
 
454
- .lever-arm {
455
- position: absolute;
456
- top: 40px;
457
- left: 5px;
458
- width: 10px;
459
- height: 80px;
460
- background: linear-gradient(180deg, #d0d0d0, #a0a0a0);
461
- border-radius: 5px;
462
- box-shadow: 0 2px 5px rgba(0,0,0,0.3);
463
- transition: all 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
464
  }
465
 
466
- .lever-ball {
467
- position: absolute;
468
- top: -30px;
469
- left: 50%;
470
- transform: translateX(-50%);
471
- width: 60px;
472
- height: 60px;
473
- background: radial-gradient(circle at 35% 35%, #ff8888, #ff4444, #cc0000);
474
- border-radius: 50%;
475
- box-shadow:
476
- 0 5px 15px rgba(0,0,0,0.4),
477
- inset -5px -5px 10px rgba(0,0,0,0.3),
478
- inset 3px 3px 5px rgba(255,255,255,0.5);
479
  }
480
 
481
- .lever.pulled .lever-arm {
482
- transform: translateY(80px);
483
- height: 10px;
 
484
  }
485
 
486
- /* Continuous spinning animation for loading */
487
  @keyframes continuousSpin {
488
  from { transform: translateY(0); }
489
- to { transform: translateY(-160px); }
490
  }
491
 
492
  .reel-strip.loading {
493
  animation: continuousSpin 1s linear infinite;
494
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  </style>
496
  </head>
497
  <body>
498
  <div class="machine-container">
499
- <h1 class="title"><a href="https://github.com/pinellolab/DNA-Diffusion" target="_blank" rel="noopener noreferrer">DNA-DIFFUSION</a></h1>
 
 
 
 
 
 
500
 
501
  <div class="cell-type-selector">
502
- <label class="cell-type-label">Cell Type-Specific Generation:</label>
503
  <div class="radio-group">
504
- <label class="radio-label">
505
  <input type="radio" name="cellType" value="K562" checked>
506
- <span>K562</span>
507
  </label>
508
- <label class="radio-label">
509
  <input type="radio" name="cellType" value="GM12878">
510
- <span>GM12878</span>
511
  </label>
512
- <label class="radio-label">
513
  <input type="radio" name="cellType" value="HepG2">
514
- <span>HepG2</span>
515
  </label>
516
  </div>
517
  </div>
@@ -520,9 +716,7 @@
520
  <div class="reels-wrapper" id="reelsWrapper"></div>
521
  <div class="lever-container">
522
  <div class="lever" id="lever">
523
- <div class="lever-mount">
524
- <div class="lever-pivot"></div>
525
- </div>
526
  <div class="lever-arm">
527
  <div class="lever-ball"></div>
528
  </div>
@@ -531,19 +725,32 @@
531
  </div>
532
 
533
  <div class="controls">
534
- <button class="spin-button" id="spinButton"><span>GENERATE</span></button>
 
535
  <div class="sequence-display" id="sequenceDisplay">
536
- Press GENERATE to create sequence
 
 
 
 
 
 
 
 
 
 
 
 
537
  </div>
538
  </div>
539
 
540
  <div class="info">
541
- 200bp Regulatory Elements Β· Cell Type-Specific Β· Synthetic Biology
542
  </div>
543
 
544
  <div class="lab-credit">
545
  <a href="https://pinellolab.org" target="_blank" rel="noopener noreferrer">
546
- Pinello Lab
547
  </a>
548
  </div>
549
  </div>
@@ -597,12 +804,18 @@
597
 
598
  // Set initial position to show a random nucleotide
599
  const randomIndex = Math.floor(Math.random() * 4);
600
- const initialOffset = -randomIndex * 40;
601
  reel.strip.style.transform = `translateY(${initialOffset}px)`;
602
- reel.currentPosition = randomIndex * 40;
603
  }
604
  }
605
 
 
 
 
 
 
 
606
  function startContinuousSpinning() {
607
  reels.forEach((reel, index) => {
608
  // Add continuous spinning animation
@@ -613,10 +826,64 @@
613
  const delay = (index % 10) * 0.1;
614
  reel.strip.style.animationDelay = `${delay}s`;
615
  });
 
 
 
 
 
 
 
 
 
 
 
616
  }
617
 
618
- function stopAndShowSequence(sequence) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
619
  TARGET_SEQUENCE = sequence;
 
620
 
621
  reels.forEach((reel, index) => {
622
  // Remove continuous spinning
@@ -625,7 +892,7 @@
625
  // Calculate target position
626
  const targetNucleotide = TARGET_SEQUENCE[index];
627
  const targetIndex = NUCLEOTIDES.indexOf(targetNucleotide);
628
- const finalPosition = targetIndex * 40;
629
 
630
  // Set up the final positioning animation
631
  setTimeout(() => {
@@ -643,9 +910,15 @@
643
  const lever = document.getElementById('lever');
644
 
645
  container.classList.remove('spinning');
646
- container.classList.add('winning-flash');
 
 
 
 
 
 
 
647
 
648
- display.innerHTML = `<strong>Generated Sequence:</strong><br>${TARGET_SEQUENCE}`;
649
  button.disabled = false;
650
  isSpinning = false;
651
 
@@ -653,8 +926,8 @@
653
  lever.classList.remove('pulled');
654
 
655
  setTimeout(() => {
656
- container.classList.remove('winning-flash');
657
- }, 1000);
658
  }, 1500);
659
  }
660
 
@@ -666,12 +939,16 @@
666
  const display = document.getElementById('sequenceDisplay');
667
  const container = document.getElementById('reelsContainer');
668
  const lever = document.getElementById('lever');
 
 
 
 
669
 
670
  // Pull the lever
671
  lever.classList.add('pulled');
672
 
673
  button.disabled = true;
674
- display.textContent = 'Generating cell type-specific regulatory element...';
675
  container.classList.add('spinning');
676
 
677
  // Start continuous spinning immediately
@@ -703,8 +980,8 @@
703
  // Listen for messages from parent window
704
  window.addEventListener('message', (event) => {
705
  if (event.data.type === 'sequence_generated') {
706
- // Stop spinning and show the actual sequence
707
- stopAndShowSequence(event.data.sequence);
708
  } else if (event.data.type === 'generation_error') {
709
  // Stop spinning and show error
710
  reels.forEach(reel => {
@@ -717,10 +994,11 @@
717
  const lever = document.getElementById('lever');
718
 
719
  container.classList.remove('spinning');
720
- display.innerHTML = '<strong style="color: #F44336;">Error:</strong> ' + event.data.error;
721
  button.disabled = false;
722
  isSpinning = false;
723
  lever.classList.remove('pulled');
 
724
  }
725
  });
726
 
@@ -731,6 +1009,18 @@
731
  startGeneration();
732
  }
733
  });
 
 
 
 
 
 
 
 
 
 
 
 
734
  </script>
735
  </body>
736
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>🧬 DNA CASINO - Protein Synthesis Slot Machine</title>
7
  <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Bebas+Neue&display=swap');
9
+
10
  * {
11
  margin: 0;
12
  padding: 0;
 
14
  }
15
 
16
  body {
17
+ background: #000;
18
  color: #fff;
19
+ font-family: 'Orbitron', monospace;
20
  overflow-x: hidden;
21
  display: flex;
22
  flex-direction: column;
 
27
  padding-top: 10px;
28
  }
29
 
30
+ /* Casino carpet pattern background */
31
  body::before {
32
+ content: '';
33
+ position: fixed;
34
+ top: 0;
35
+ left: 0;
36
+ width: 100%;
37
+ height: 100%;
38
+ background:
39
+ radial-gradient(circle at 20% 30%, #ff0066 0px, transparent 100px),
40
+ radial-gradient(circle at 80% 70%, #00ffff 0px, transparent 100px),
41
+ radial-gradient(circle at 50% 50%, #ffff00 0px, transparent 150px),
42
+ radial-gradient(circle at 30% 80%, #ff00ff 0px, transparent 80px),
43
+ radial-gradient(circle at 70% 20%, #00ff00 0px, transparent 90px);
44
+ opacity: 0.1;
45
+ z-index: 0;
46
+ animation: casinoLights 10s ease-in-out infinite;
47
+ }
48
+
49
+ @keyframes casinoLights {
50
+ 0%, 100% { filter: hue-rotate(0deg) brightness(1); }
51
+ 50% { filter: hue-rotate(180deg) brightness(1.5); }
52
+ }
53
+
54
+ /* Static TV noise overlay */
55
+ body::after {
56
  content: '';
57
  position: fixed;
58
  top: 0;
 
73
  rgba(0,0,0,0.05) 1px,
74
  transparent 1px,
75
  transparent 2px
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  );
77
+ background-size: 2px 2px, 2px 2px;
78
  pointer-events: none;
79
  z-index: 1;
80
  opacity: 0.8;
81
  animation: staticNoise 0.1s steps(8) infinite;
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  @keyframes staticNoise {
85
  0%, 100% { transform: translate(0, 0); }
86
+ 50% { transform: translate(-1px, -1px); }
 
 
 
 
 
 
 
 
87
  }
88
 
89
+ /* Main casino cabinet */
90
  .machine-container {
91
+ background: linear-gradient(145deg, #1a0000, #330000);
92
+ border: 5px solid #ffd700;
93
+ border-radius: 30px;
94
+ padding: 20px;
95
+ padding-right: 120px;
96
+ box-shadow:
97
+ 0 0 50px rgba(255, 215, 0, 0.5),
98
+ 0 20px 40px rgba(0,0,0,0.8),
99
+ inset 0 0 30px rgba(255, 215, 0, 0.2);
100
  width: 95vw;
101
  max-width: 1400px;
102
  position: relative;
103
  z-index: 2;
104
  }
105
 
106
+ /* Blinking lights around the machine */
107
+ .machine-container::before {
108
+ content: '';
109
+ position: absolute;
110
+ top: -10px;
111
+ left: -10px;
112
+ right: -10px;
113
+ bottom: -10px;
114
+ border-radius: 35px;
115
+ background: conic-gradient(
116
+ from 0deg,
117
+ #ff0000, #ff7700, #ffff00, #00ff00,
118
+ #0000ff, #ff00ff, #ff0000
119
+ );
120
+ z-index: -1;
121
+ animation: rotateGradient 3s linear infinite;
122
+ filter: blur(10px);
123
+ opacity: 0.7;
124
+ }
125
+
126
+ @keyframes rotateGradient {
127
+ 0% { transform: rotate(0deg); }
128
+ 100% { transform: rotate(360deg); }
129
+ }
130
+
131
+ /* Neon title */
132
  .title {
133
  text-align: center;
134
+ font-family: 'Bebas Neue', cursive;
135
+ font-size: 4rem;
136
+ margin-bottom: 10px;
137
+ position: relative;
138
+ text-transform: uppercase;
139
+ letter-spacing: 0.2em;
140
  }
141
 
142
  .title a {
143
  text-decoration: none;
144
+ color: #fff;
145
+ text-shadow:
146
+ 0 0 10px #ff00ff,
147
+ 0 0 20px #ff00ff,
148
+ 0 0 30px #ff00ff,
149
+ 0 0 40px #ff00ff,
150
+ 0 0 70px #ff00ff,
151
+ 0 0 80px #ff00ff,
152
+ 0 0 100px #ff00ff,
153
+ 0 0 150px #ff00ff;
154
+ animation: neonFlicker 1.5s infinite alternate;
155
  }
156
 
157
+ @keyframes neonFlicker {
158
+ 0%, 100% { opacity: 1; }
159
+ 33% { opacity: 0.8; }
160
+ 66% { opacity: 0.9; }
161
  }
162
 
163
+ .subtitle {
164
+ text-align: center;
165
+ font-size: 1.5rem;
166
+ color: #ffd700;
167
+ margin-bottom: 20px;
168
+ text-shadow: 0 0 10px #ffd700;
169
+ animation: pulse 2s ease-in-out infinite;
170
+ }
171
+
172
+ @keyframes pulse {
173
+ 0%, 100% { transform: scale(1); }
174
+ 50% { transform: scale(1.05); }
175
+ }
176
+
177
+ /* Jackpot counter */
178
+ .jackpot-display {
179
+ background: #000;
180
+ border: 3px solid #ffd700;
181
+ border-radius: 10px;
182
+ padding: 10px 20px;
183
+ margin: 10px auto;
184
+ text-align: center;
185
+ max-width: 400px;
186
+ box-shadow:
187
+ inset 0 0 20px rgba(255, 215, 0, 0.3),
188
+ 0 0 20px rgba(255, 215, 0, 0.5);
189
+ }
190
+
191
+ .jackpot-label {
192
+ font-size: 0.9rem;
193
+ color: #ffd700;
194
+ text-transform: uppercase;
195
+ letter-spacing: 2px;
196
+ }
197
+
198
+ .jackpot-value {
199
+ font-size: 2rem;
200
+ color: #00ff00;
201
+ font-weight: bold;
202
+ text-shadow: 0 0 10px #00ff00;
203
+ font-family: 'Orbitron', monospace;
204
+ }
205
+
206
+ /* Cell type selector with casino chips style */
207
  .cell-type-selector {
208
  display: flex;
209
  align-items: center;
210
  justify-content: center;
211
  gap: 20px;
212
+ margin-bottom: 20px;
 
 
 
 
 
213
  }
214
 
215
  .radio-group {
216
  display: flex;
217
+ gap: 30px;
218
  }
219
 
220
+ .chip-label {
221
+ position: relative;
222
  display: flex;
223
  align-items: center;
224
+ justify-content: center;
225
+ width: 100px;
226
+ height: 100px;
227
  cursor: pointer;
228
+ transition: all 0.3s ease;
229
+ }
230
+
231
+ .chip-label input[type="radio"] {
232
+ position: absolute;
233
+ opacity: 0;
234
+ }
235
+
236
+ .chip {
237
+ position: relative;
238
+ width: 100%;
239
+ height: 100%;
240
+ border-radius: 50%;
241
+ background: radial-gradient(circle at 30% 30%, #ff4444, #cc0000);
242
+ box-shadow:
243
+ 0 5px 15px rgba(0,0,0,0.5),
244
+ inset 0 0 20px rgba(0,0,0,0.3),
245
+ inset -3px -3px 10px rgba(255,255,255,0.2);
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: center;
249
+ font-weight: bold;
250
  font-size: 1.1rem;
251
  color: #fff;
252
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
253
+ border: 8px dashed #fff;
254
+ animation: chipRotate 20s linear infinite;
255
  }
256
 
257
+ @keyframes chipRotate {
258
+ 0% { transform: rotate(0deg); }
259
+ 100% { transform: rotate(360deg); }
260
  }
261
 
262
+ .chip-label:hover .chip {
263
+ transform: scale(1.1);
264
+ box-shadow:
265
+ 0 10px 30px rgba(255,0,0,0.5),
266
+ inset 0 0 30px rgba(255,255,255,0.3);
267
+ }
268
+
269
+ .chip-label input[type="radio"]:checked + .chip {
270
+ background: radial-gradient(circle at 30% 30%, #44ff44, #00cc00);
271
+ box-shadow:
272
+ 0 0 30px rgba(0,255,0,0.7),
273
+ inset 0 0 20px rgba(0,0,0,0.3);
274
+ animation: chipRotate 5s linear infinite, winPulse 1s ease-in-out infinite;
275
  }
276
 
277
+ @keyframes winPulse {
278
+ 0%, 100% { transform: scale(1); }
279
+ 50% { transform: scale(1.05); }
280
+ }
281
+
282
+ /* Slot machine reels */
283
  .reels-container {
284
  background: #000;
285
+ border: 5px solid #ffd700;
286
+ border-radius: 15px;
287
+ padding: 20px;
288
  max-width: 100%;
289
  position: relative;
290
+ box-shadow:
291
+ inset 0 0 50px rgba(0,0,0,0.8),
292
+ 0 0 30px rgba(255, 215, 0, 0.5);
293
  overflow: visible;
294
+ margin: 20px 0;
295
  }
296
 
297
  .reels-wrapper {
298
  display: flex;
299
+ gap: 2px;
300
  min-width: fit-content;
301
+ padding: 5px 0;
302
  justify-content: center;
303
  flex-wrap: wrap;
304
  max-width: 1200px;
305
  margin: 0 auto;
306
+ background: linear-gradient(90deg,
307
+ transparent 0%,
308
+ rgba(255, 215, 0, 0.1) 50%,
309
+ transparent 100%);
310
  }
311
 
312
  .reel {
313
+ width: 20px;
314
+ height: 50px;
315
  background: #ffffff;
316
+ border: 2px solid #ffd700;
317
+ border-radius: 3px;
318
  overflow: hidden;
319
  position: relative;
320
+ box-shadow:
321
+ inset 0 0 10px rgba(0,0,0,0.3),
322
+ 0 0 5px rgba(255, 215, 0, 0.5);
323
  }
324
 
325
  .reel-strip {
 
329
  }
330
 
331
  .nucleotide {
332
+ height: 50px;
333
  display: flex;
334
  align-items: center;
335
  justify-content: center;
336
+ font-size: 1.2rem;
337
  font-weight: bold;
338
  background: #ffffff;
339
+ text-shadow: 0 0 5px currentColor;
340
  }
341
 
342
+ .nucleotide.A { color: #00ff00; background: #001100; }
343
+ .nucleotide.T { color: #ff0000; background: #110000; }
344
+ .nucleotide.C { color: #00ffff; background: #001111; }
345
+ .nucleotide.G { color: #ffff00; background: #111100; }
346
 
347
+ /* Casino style lever */
348
+ .lever-container {
349
+ position: absolute;
350
+ right: -90px;
351
+ top: 50%;
352
+ transform: translateY(-50%);
353
+ z-index: 3;
354
+ width: 80px;
355
+ height: 250px;
356
  }
357
 
358
+ .lever {
359
+ width: 100%;
360
+ height: 100%;
361
+ position: relative;
362
+ cursor: pointer;
363
+ }
364
+
365
+ .lever-mount {
366
+ position: absolute;
367
+ top: 100px;
368
+ left: -15px;
369
+ width: 60px;
370
+ height: 80px;
371
+ background: linear-gradient(180deg, #ffd700, #b8860b);
372
+ border-radius: 10px 0 0 10px;
373
+ box-shadow:
374
+ 0 5px 20px rgba(0,0,0,0.5),
375
+ inset 0 2px 5px rgba(255,255,255,0.5);
376
+ }
377
+
378
+ .lever-arm {
379
+ position: absolute;
380
+ top: 30px;
381
+ left: 10px;
382
+ width: 15px;
383
+ height: 100px;
384
+ background: linear-gradient(180deg, #c0c0c0, #808080);
385
+ border-radius: 8px;
386
+ box-shadow: 0 3px 10px rgba(0,0,0,0.5);
387
+ transition: all 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
388
+ }
389
+
390
+ .lever-ball {
391
+ position: absolute;
392
+ top: -40px;
393
+ left: 50%;
394
+ transform: translateX(-50%);
395
+ width: 80px;
396
+ height: 80px;
397
+ background: radial-gradient(circle at 35% 35%, #ff4444, #cc0000, #800000);
398
+ border-radius: 50%;
399
+ box-shadow:
400
+ 0 10px 30px rgba(0,0,0,0.6),
401
+ inset -10px -10px 20px rgba(0,0,0,0.5),
402
+ inset 5px 5px 10px rgba(255,255,255,0.6);
403
+ position: relative;
404
+ overflow: hidden;
405
+ }
406
+
407
+ .lever-ball::before {
408
+ content: '777';
409
+ position: absolute;
410
+ top: 50%;
411
+ left: 50%;
412
+ transform: translate(-50%, -50%);
413
  font-size: 1.5rem;
414
  font-weight: bold;
415
+ color: #ffd700;
416
+ text-shadow: 0 2px 4px rgba(0,0,0,0.8);
417
+ }
418
+
419
+ .lever.pulled .lever-arm {
420
+ transform: translateY(100px);
421
+ height: 20px;
422
+ }
423
+
424
+ /* Generate button */
425
+ .spin-button {
426
+ background: linear-gradient(145deg, #ff0000, #cc0000);
427
+ border: 3px solid #ffd700;
428
+ padding: 25px 80px;
429
+ font-size: 2rem;
430
+ font-weight: bold;
431
  border-radius: 50px;
432
  cursor: pointer;
433
  text-transform: uppercase;
434
+ letter-spacing: 3px;
435
+ box-shadow:
436
+ 0 10px 30px rgba(0,0,0,0.7),
437
+ 0 0 30px rgba(255, 0, 0, 0.5),
438
+ inset 0 2px 10px rgba(255,255,255,0.3);
439
  transition: all 0.3s ease;
440
  color: #fff;
441
+ text-shadow: 0 3px 6px rgba(0,0,0,0.5);
442
  position: relative;
443
  overflow: hidden;
444
+ font-family: 'Bebas Neue', cursive;
445
  }
446
 
447
  .spin-button::before {
448
  content: '';
449
  position: absolute;
450
+ top: -50%;
451
+ left: -50%;
452
+ width: 200%;
453
+ height: 200%;
454
+ background: linear-gradient(45deg,
455
+ transparent 30%,
456
+ rgba(255,255,255,0.3) 50%,
457
+ transparent 70%);
458
+ animation: buttonShine 3s infinite;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  }
460
 
461
+ @keyframes buttonShine {
462
+ 0% { transform: rotate(0deg); }
463
+ 100% { transform: rotate(360deg); }
 
464
  }
465
 
466
+ .spin-button:hover {
467
+ transform: translateY(-3px) scale(1.05);
468
+ box-shadow:
469
+ 0 15px 40px rgba(0,0,0,0.8),
470
+ 0 0 50px rgba(255, 0, 0, 0.7);
471
  }
472
 
473
  .spin-button:active {
474
+ transform: translateY(0) scale(0.98);
475
  }
476
 
477
  .spin-button:disabled {
478
+ background: linear-gradient(145deg, #444, #222);
479
  cursor: not-allowed;
480
  box-shadow: none;
481
+ animation: none;
482
  }
483
 
484
+ /* Sequence display */
485
  .sequence-display {
486
+ background: #000;
487
+ border: 3px solid #00ff00;
488
+ border-radius: 15px;
489
+ padding: 25px;
490
+ font-family: 'Orbitron', monospace;
491
  font-size: 0.9rem;
492
+ letter-spacing: 2px;
493
  width: 100%;
494
  max-width: 1200px;
495
+ margin: 20px auto;
496
+ box-shadow:
497
+ 0 0 30px rgba(0, 255, 0, 0.5),
498
+ inset 0 0 20px rgba(0, 255, 0, 0.1);
499
  position: relative;
500
+ min-height: 100px;
501
  }
502
 
503
  .sequence-display::before {
504
+ content: '🧬 SYNTHETIC REGULATORY ELEMENT';
505
  position: absolute;
506
+ top: -15px;
507
  left: 50%;
508
  transform: translateX(-50%);
509
+ background: #000;
510
+ padding: 0 20px;
511
+ font-size: 0.8rem;
512
+ color: #00ff00;
513
+ letter-spacing: 3px;
514
+ text-shadow: 0 0 10px #00ff00;
515
  }
516
 
517
+ /* Protein analysis panel */
518
+ .protein-panel {
519
+ background: linear-gradient(145deg, #1a0033, #000033);
520
+ border: 3px solid #00ffff;
521
+ border-radius: 15px;
522
+ padding: 25px;
523
+ margin: 20px auto;
524
+ max-width: 1200px;
525
+ box-shadow:
526
+ 0 0 30px rgba(0, 255, 255, 0.5),
527
+ inset 0 0 20px rgba(0, 255, 255, 0.1);
528
+ display: none;
529
+ animation: fadeIn 0.5s ease-in;
530
  }
531
 
532
+ @keyframes fadeIn {
533
+ from { opacity: 0; transform: translateY(20px); }
534
+ to { opacity: 1; transform: translateY(0); }
535
+ }
536
+
537
+ .protein-panel.active {
538
+ display: block;
539
+ }
540
+
541
+ .protein-header {
542
+ font-size: 1.5rem;
543
+ color: #00ffff;
544
+ margin-bottom: 15px;
545
  text-align: center;
546
+ text-transform: uppercase;
547
+ letter-spacing: 3px;
548
+ text-shadow: 0 0 15px #00ffff;
549
  }
550
 
551
+ .protein-sequence {
552
+ background: #000;
553
+ border: 1px solid #00ffff;
554
+ border-radius: 10px;
555
+ padding: 15px;
556
+ margin-bottom: 20px;
557
+ font-family: 'Courier New', monospace;
558
+ font-size: 0.85rem;
559
+ word-break: break-all;
560
+ color: #00ff00;
561
+ max-height: 150px;
562
+ overflow-y: auto;
563
  }
564
 
565
+ .protein-analysis {
566
+ background: rgba(0, 255, 255, 0.05);
567
+ border: 1px solid rgba(0, 255, 255, 0.3);
568
+ border-radius: 10px;
569
+ padding: 20px;
570
  color: #fff;
571
+ line-height: 1.8;
572
+ font-size: 0.95rem;
 
573
  }
574
 
575
+ .protein-analysis h3 {
576
+ color: #00ffff;
577
+ margin-bottom: 10px;
578
+ text-shadow: 0 0 10px #00ffff;
579
  }
580
 
581
+ .protein-stats {
582
+ display: grid;
583
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
584
+ gap: 15px;
585
+ margin-bottom: 20px;
586
  }
587
 
588
+ .stat-card {
589
+ background: rgba(255, 215, 0, 0.1);
590
+ border: 1px solid #ffd700;
591
+ border-radius: 10px;
592
+ padding: 15px;
593
+ text-align: center;
594
  }
595
 
596
+ .stat-label {
597
+ font-size: 0.8rem;
598
+ color: #ffd700;
599
+ text-transform: uppercase;
600
+ letter-spacing: 1px;
601
  }
602
 
603
+ .stat-value {
604
+ font-size: 1.5rem;
605
+ color: #fff;
606
+ font-weight: bold;
607
+ margin-top: 5px;
 
 
 
608
  }
609
 
610
+ /* Info footer */
611
+ .info {
612
+ text-align: center;
613
+ margin-top: 20px;
614
+ color: #ffd700;
615
+ font-size: 1rem;
616
+ text-transform: uppercase;
617
+ letter-spacing: 2px;
618
+ text-shadow: 0 0 10px #ffd700;
619
  }
620
 
621
+ .lab-credit {
622
+ text-align: center;
623
+ margin-top: 15px;
624
+ font-size: 1.3rem;
 
 
 
 
 
 
 
625
  }
626
 
627
+ .lab-credit a {
628
+ color: #00ff00;
629
+ text-decoration: none;
630
+ font-weight: bold;
631
+ letter-spacing: 2px;
632
+ padding: 10px 30px;
633
+ border: 2px solid #00ff00;
634
+ border-radius: 30px;
635
+ display: inline-block;
636
+ transition: all 0.3s ease;
637
+ text-shadow: 0 0 10px #00ff00;
638
  }
639
 
640
+ .lab-credit a:hover {
641
+ background: #00ff00;
642
+ color: #000;
643
+ box-shadow: 0 0 30px #00ff00;
644
+ transform: scale(1.1);
 
 
 
 
 
645
  }
646
 
647
+ /* Winning animation */
648
+ .jackpot-win {
649
+ animation: jackpotFlash 2s ease-out;
 
 
 
 
 
 
 
 
 
 
650
  }
651
 
652
+ @keyframes jackpotFlash {
653
+ 0%, 100% { background-color: transparent; }
654
+ 10%, 30%, 50%, 70%, 90% { background-color: rgba(255, 215, 0, 0.3); }
655
+ 20%, 40%, 60%, 80% { background-color: transparent; }
656
  }
657
 
658
+ /* Loading animation */
659
  @keyframes continuousSpin {
660
  from { transform: translateY(0); }
661
+ to { transform: translateY(-200px); }
662
  }
663
 
664
  .reel-strip.loading {
665
  animation: continuousSpin 1s linear infinite;
666
  }
667
+
668
+ /* Scrollbar styling */
669
+ ::-webkit-scrollbar {
670
+ width: 10px;
671
+ }
672
+
673
+ ::-webkit-scrollbar-track {
674
+ background: rgba(0, 0, 0, 0.5);
675
+ border-radius: 5px;
676
+ }
677
+
678
+ ::-webkit-scrollbar-thumb {
679
+ background: #00ffff;
680
+ border-radius: 5px;
681
+ }
682
+
683
+ ::-webkit-scrollbar-thumb:hover {
684
+ background: #00cccc;
685
+ }
686
  </style>
687
  </head>
688
  <body>
689
  <div class="machine-container">
690
+ <h1 class="title"><a href="https://github.com/pinellolab/DNA-Diffusion" target="_blank" rel="noopener noreferrer">🎰 DNA CASINO 🧬</a></h1>
691
+ <div class="subtitle">β˜… PROTEIN SYNTHESIS JACKPOT β˜…</div>
692
+
693
+ <div class="jackpot-display">
694
+ <div class="jackpot-label">Current Sequence Length</div>
695
+ <div class="jackpot-value" id="sequenceCounter">0 BP</div>
696
+ </div>
697
 
698
  <div class="cell-type-selector">
 
699
  <div class="radio-group">
700
+ <label class="chip-label">
701
  <input type="radio" name="cellType" value="K562" checked>
702
+ <div class="chip">K562</div>
703
  </label>
704
+ <label class="chip-label">
705
  <input type="radio" name="cellType" value="GM12878">
706
+ <div class="chip">GM12878</div>
707
  </label>
708
+ <label class="chip-label">
709
  <input type="radio" name="cellType" value="HepG2">
710
+ <div class="chip">HepG2</div>
711
  </label>
712
  </div>
713
  </div>
 
716
  <div class="reels-wrapper" id="reelsWrapper"></div>
717
  <div class="lever-container">
718
  <div class="lever" id="lever">
719
+ <div class="lever-mount"></div>
 
 
720
  <div class="lever-arm">
721
  <div class="lever-ball"></div>
722
  </div>
 
725
  </div>
726
 
727
  <div class="controls">
728
+ <button class="spin-button" id="spinButton"><span>🎲 SPIN TO WIN 🎲</span></button>
729
+
730
  <div class="sequence-display" id="sequenceDisplay">
731
+ 🎯 Pull the lever or press SPIN to generate your winning sequence! 🎯
732
+ </div>
733
+
734
+ <div class="protein-panel" id="proteinPanel">
735
+ <div class="protein-header">πŸ”¬ Protein Analysis Report πŸ”¬</div>
736
+
737
+ <div class="protein-stats" id="proteinStats"></div>
738
+
739
+ <div class="protein-sequence" id="proteinSequence"></div>
740
+
741
+ <div class="protein-analysis" id="proteinAnalysis">
742
+ <h3>Analyzing protein structure...</h3>
743
+ </div>
744
  </div>
745
  </div>
746
 
747
  <div class="info">
748
+ 🎰 200BP REGULATORY ELEMENTS β€’ CELL-TYPE SPECIFIC β€’ SYNTHETIC BIOLOGY JACKPOT 🎰
749
  </div>
750
 
751
  <div class="lab-credit">
752
  <a href="https://pinellolab.org" target="_blank" rel="noopener noreferrer">
753
+ πŸ’Ž PINELLO LAB πŸ’Ž
754
  </a>
755
  </div>
756
  </div>
 
804
 
805
  // Set initial position to show a random nucleotide
806
  const randomIndex = Math.floor(Math.random() * 4);
807
+ const initialOffset = -randomIndex * 50;
808
  reel.strip.style.transform = `translateY(${initialOffset}px)`;
809
+ reel.currentPosition = randomIndex * 50;
810
  }
811
  }
812
 
813
+ function updateSequenceCounter(length) {
814
+ const counter = document.getElementById('sequenceCounter');
815
+ counter.textContent = `${length} BP`;
816
+ counter.style.animation = 'pulse 0.5s ease-out';
817
+ }
818
+
819
  function startContinuousSpinning() {
820
  reels.forEach((reel, index) => {
821
  // Add continuous spinning animation
 
826
  const delay = (index % 10) * 0.1;
827
  reel.strip.style.animationDelay = `${delay}s`;
828
  });
829
+
830
+ // Update counter animation
831
+ let count = 0;
832
+ const counterInterval = setInterval(() => {
833
+ if (!isSpinning) {
834
+ clearInterval(counterInterval);
835
+ return;
836
+ }
837
+ count = (count + 7) % 201;
838
+ updateSequenceCounter(count);
839
+ }, 100);
840
  }
841
 
842
+ function displayProteinAnalysis(metadata) {
843
+ const panel = document.getElementById('proteinPanel');
844
+ const statsDiv = document.getElementById('proteinStats');
845
+ const sequenceDiv = document.getElementById('proteinSequence');
846
+ const analysisDiv = document.getElementById('proteinAnalysis');
847
+
848
+ // Show panel
849
+ panel.classList.add('active');
850
+
851
+ // Display stats
852
+ statsDiv.innerHTML = `
853
+ <div class="stat-card">
854
+ <div class="stat-label">Cell Type</div>
855
+ <div class="stat-value">${metadata.cell_type || 'Unknown'}</div>
856
+ </div>
857
+ <div class="stat-card">
858
+ <div class="stat-label">DNA Length</div>
859
+ <div class="stat-value">${TARGET_SEQUENCE.length} bp</div>
860
+ </div>
861
+ <div class="stat-card">
862
+ <div class="stat-label">Protein Length</div>
863
+ <div class="stat-value">${metadata.protein_length || 0} aa</div>
864
+ </div>
865
+ <div class="stat-card">
866
+ <div class="stat-label">Generation Time</div>
867
+ <div class="stat-value">${(metadata.generation_time || 0).toFixed(1)}s</div>
868
+ </div>
869
+ `;
870
+
871
+ // Display protein sequence
872
+ if (metadata.protein_sequence) {
873
+ sequenceDiv.innerHTML = `<strong>Protein Sequence:</strong><br>${metadata.protein_sequence}`;
874
+ }
875
+
876
+ // Display analysis
877
+ if (metadata.protein_analysis) {
878
+ analysisDiv.innerHTML = `<h3>🧬 Structural & Functional Analysis</h3>${metadata.protein_analysis}`;
879
+ } else {
880
+ analysisDiv.innerHTML = '<h3>⏳ Protein analysis pending...</h3>';
881
+ }
882
+ }
883
+
884
+ function stopAndShowSequence(sequence, metadata = {}) {
885
  TARGET_SEQUENCE = sequence;
886
+ updateSequenceCounter(sequence.length);
887
 
888
  reels.forEach((reel, index) => {
889
  // Remove continuous spinning
 
892
  // Calculate target position
893
  const targetNucleotide = TARGET_SEQUENCE[index];
894
  const targetIndex = NUCLEOTIDES.indexOf(targetNucleotide);
895
+ const finalPosition = targetIndex * 50;
896
 
897
  // Set up the final positioning animation
898
  setTimeout(() => {
 
910
  const lever = document.getElementById('lever');
911
 
912
  container.classList.remove('spinning');
913
+ container.classList.add('jackpot-win');
914
+
915
+ display.innerHTML = `<strong>🎊 JACKPOT SEQUENCE 🎊</strong><br><span style="color: #00ff00; font-family: 'Courier New', monospace;">${TARGET_SEQUENCE}</span>`;
916
+
917
+ // Display protein analysis if available
918
+ if (metadata) {
919
+ displayProteinAnalysis(metadata);
920
+ }
921
 
 
922
  button.disabled = false;
923
  isSpinning = false;
924
 
 
926
  lever.classList.remove('pulled');
927
 
928
  setTimeout(() => {
929
+ container.classList.remove('jackpot-win');
930
+ }, 2000);
931
  }, 1500);
932
  }
933
 
 
939
  const display = document.getElementById('sequenceDisplay');
940
  const container = document.getElementById('reelsContainer');
941
  const lever = document.getElementById('lever');
942
+ const proteinPanel = document.getElementById('proteinPanel');
943
+
944
+ // Hide protein panel from previous spin
945
+ proteinPanel.classList.remove('active');
946
 
947
  // Pull the lever
948
  lever.classList.add('pulled');
949
 
950
  button.disabled = true;
951
+ display.innerHTML = '🎲 <strong>SPINNING THE GENETIC WHEEL OF FORTUNE...</strong> 🎲';
952
  container.classList.add('spinning');
953
 
954
  // Start continuous spinning immediately
 
980
  // Listen for messages from parent window
981
  window.addEventListener('message', (event) => {
982
  if (event.data.type === 'sequence_generated') {
983
+ // Stop spinning and show the actual sequence with metadata
984
+ stopAndShowSequence(event.data.sequence, event.data.metadata);
985
  } else if (event.data.type === 'generation_error') {
986
  // Stop spinning and show error
987
  reels.forEach(reel => {
 
994
  const lever = document.getElementById('lever');
995
 
996
  container.classList.remove('spinning');
997
+ display.innerHTML = '<strong style="color: #ff0000;">❌ BUST! ❌</strong><br>' + event.data.error;
998
  button.disabled = false;
999
  isSpinning = false;
1000
  lever.classList.remove('pulled');
1001
+ updateSequenceCounter(0);
1002
  }
1003
  });
1004
 
 
1009
  startGeneration();
1010
  }
1011
  });
1012
+
1013
+ // Add some casino ambiance
1014
+ setInterval(() => {
1015
+ if (!isSpinning && Math.random() > 0.7) {
1016
+ const chips = document.querySelectorAll('.chip');
1017
+ const randomChip = chips[Math.floor(Math.random() * chips.length)];
1018
+ randomChip.style.animation = 'none';
1019
+ setTimeout(() => {
1020
+ randomChip.style.animation = 'chipRotate 20s linear infinite';
1021
+ }, 10);
1022
+ }
1023
+ }, 5000);
1024
  </script>
1025
  </body>
1026
  </html>