← back to [single element] CSS Double Helixcompare with ground truth →
model output
Gemini 3 Flash Preview
[single element] CSS Double Helix
A 0.64T 0.30
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Rotating Dot Chain Animation</title>
7 <style>
8 body, html {
9 margin: 0;
10 padding: 0;
11 width: 100%;
12 height: 100%;
13 overflow: hidden;
14 background-color: #98f362; /* Center green base */
15 }
16
17 /* Recreating the vibrant mesh gradient background */
18 .background {
19 position: absolute;
20 top: 0;
21 left: 0;
22 width: 100%;
23 height: 100%;
24 background:
25 radial-gradient(circle at 0% 0%, #515ada 30%, transparent 70%),
26 radial-gradient(circle at 100% 0%, #ef4d2d 30%, transparent 70%),
27 radial-gradient(circle at 100% 100%, #d64661 30%, transparent 70%),
28 radial-gradient(circle at 0% 100%, #4182f0 30%, transparent 70%),
29 radial-gradient(circle at 50% 50%, #98f362 20%, transparent 80%);
30 display: flex;
31 justify-content: center;
32 align-items: center;
33 }
34
35 .chain-container {
36 position: relative;
37 width: 110%; /* Slightly wider to ensure screen coverage */
38 display: flex;
39 justify-content: center;
40 align-items: center;
41 gap: 15px; /* Spacing between cluster centers */
42 }
43
44 .cluster {
45 position: relative;
46 width: 60px;
47 height: 60px;
48 /* Constant rotation matching the video speed (approx 4s per cycle) */
49 animation: rotate-cluster 4s linear infinite;
50 }
51
52 @keyframes rotate-cluster {
53 from { transform: rotate(0deg); }
54 to { transform: rotate(-360deg); } /* Rotating counter-clockwise */
55 }
56
57 .dot {
58 position: absolute;
59 background-color: white;
60 border-radius: 50%;
61 box-shadow: 0 0 2px rgba(255, 255, 255, 0.5);
62 transform-origin: center;
63 }
64
65 /* Specific positions for the 6 dots in the cluster hexagon-like pattern */
66 /* Angles: 0, 60, 120, 180, 240, 300 */
67
68 .dot-0 { top: 50%; left: 100%; transform: translate(-50%, -50%); width: 12px; height: 9px; border-radius: 45% 55% 55% 45% / 50%; } /* Horizontal teardrop-ish */
69 .dot-60 { top: 15%; left: 80%; transform: translate(-50%, -50%); width: 7px; height: 7px; }
70 .dot-120 { top: 15%; left: 20%; transform: translate(-50%, -50%); width: 7px; height: 7px; }
71 .dot-180 { top: 50%; left: 0%; transform: translate(-50%, -50%); width: 12px; height: 9px; border-radius: 55% 45% 45% 55% / 50%; } /* Horizontal teardrop-ish */
72 .dot-240 { top: 85%; left: 20%; transform: translate(-50%, -50%); width: 7px; height: 7px; }
73 .dot-300 { top: 85%; left: 80%; transform: translate(-50%, -50%); width: 7px; height: 7px; }
74
75 </style>
76</head>
77<body>
78
79 <div class="background">
80 <div class="chain-container" id="chain">
81 <!-- Clusters will be generated by JavaScript -->
82 </div>
83 </div>
84
85 <script>
86 const chainContainer = document.getElementById('chain');
87 const clusterCount = 30; // Sufficient to cover most screen widths
88
89 for (let i = 0; i < clusterCount; i++) {
90 const cluster = document.createElement('div');
91 cluster.className = 'cluster';
92
93 // Create 6 dots for each cluster
94 const angles = [0, 60, 120, 180, 240, 300];
95 angles.forEach(angle => {
96 const dot = document.createElement('div');
97 dot.className = `dot dot-${angle}`;
98
99 // Position dots using trig for precise circular placement
100 // Radius is roughly 28px
101 const radius = 28;
102 const radians = (angle * Math.PI) / 180;
103 const x = 30 + radius * Math.cos(radians);
104 const y = 30 + radius * Math.sin(radians);
105
106 dot.style.left = `${x}px`;
107 dot.style.top = `${y}px`;
108
109 cluster.appendChild(dot);
110 });
111
112 chainContainer.appendChild(cluster);
113 }
114
115 // To perfectly match the video, we ensure they are in sync.
116 // The CSS animation handles this, but we can offset them if we wanted a wave.
117 // In the video, they are perfectly synced.
118 </script>
119</body>
120</html>