← back to Only CSS: Infinite Plug Incompare with ground truth →
model output
Gemini 3 Flash Preview
Only CSS: Infinite Plug In
A 0.63T 0.27
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>3D Isometric Folding Conveyor</title>
7 <style>
8 :root {
9 --paper-color: #ffffff;
10 --paper-shadow: #e0e0e0;
11 --green: #66d9ab;
12 --orange: #d35400;
13 --blue: #3498db;
14 --darkblue: #1a237e;
15 --olive: #827717;
16 --well-length: 160px; /* Length of one full well cycle */
17 --anim-speed: 5s; /* Total cycle for 5 cubes */
18 --cube-size: 40px;
19 }
20
21 body {
22 margin: 0;
23 overflow: hidden;
24 background: #fff;
25 display: flex;
26 justify-content: center;
27 align-items: center;
28 height: 100vh;
29 width: 100vw;
30 }
31
32 .scene {
33 perspective: 1200px;
34 width: 100%;
35 height: 100%;
36 display: flex;
37 justify-content: center;
38 align-items: center;
39 }
40
41 .viewport {
42 transform: rotateX(60deg) rotateZ(-45deg);
43 transform-style: preserve-3d;
44 width: 0;
45 height: 0;
46 position: relative;
47 }
48
49 /* Track Animation */
50 .track {
51 position: absolute;
52 transform-style: preserve-3d;
53 animation: moveTrack var(--anim-speed) linear infinite;
54 display: flex;
55 flex-direction: column;
56 align-items: center;
57 }
58
59 @keyframes moveTrack {
60 0% { transform: translateY(calc(var(--well-length) * -2.5)); }
61 100% { transform: translateY(calc(var(--well-length) * 2.5)); }
62 }
63
64 /* Paper Track Components */
65 .well {
66 width: 80px;
67 height: var(--well-length);
68 position: relative;
69 transform-style: preserve-3d;
70 }
71
72 .face {
73 position: absolute;
74 background: var(--paper-color);
75 transform-style: preserve-3d;
76 }
77
78 /* Folding Geometry */
79 .bottom {
80 width: 80px;
81 height: 60px;
82 top: 50px;
83 left: 0;
84 background: #fdfdfd;
85 box-shadow: inset 0 0 15px rgba(0,0,0,0.05);
86 }
87
88 .wall-up {
89 width: 80px;
90 height: 50px;
91 top: 0;
92 transform-origin: bottom;
93 transform: translateY(0) rotateX(-50deg);
94 background: linear-gradient(to top, #eee, #fff);
95 }
96
97 .wall-down {
98 width: 80px;
99 height: 50px;
100 top: 110px;
101 transform-origin: top;
102 transform: rotateX(50deg);
103 background: linear-gradient(to bottom, #eee, #fff);
104 }
105
106 .bridge {
107 width: 80px;
108 height: 30px;
109 top: -20px;
110 transform: translateZ(38px);
111 background: #fff;
112 box-shadow: 0 5px 10px rgba(0,0,0,0.05);
113 }
114
115 /* 3D Cube */
116 .cube {
117 position: absolute;
118 width: var(--cube-size);
119 height: var(--cube-size);
120 top: 60px;
121 left: 20px;
122 transform-style: preserve-3d;
123 animation: cubeFall var(--anim-speed) cubic-bezier(0.47, 0, 0.74, 0.71) infinite;
124 }
125
126 @keyframes cubeFall {
127 0% { transform: translateZ(500px) scale3d(0.8, 0.8, 1); opacity: 0; }
128 5% { opacity: 1; }
129 20% { transform: translateZ(0) scale3d(1.1, 1.1, 0.9); }
130 25% { transform: translateZ(0) scale3d(1, 1, 1); }
131 100% { transform: translateZ(0); }
132 }
133
134 .cube-face {
135 position: absolute;
136 width: var(--cube-size);
137 height: var(--cube-size);
138 border: 0.5px solid rgba(0,0,0,0.05);
139 }
140
141 .cube-top { transform: translateZ(var(--cube-size)); }
142 .cube-front { transform: rotateX(-90deg) translateZ(calc(var(--cube-size) / 2)) translateY(calc(var(--cube-size) / -2)); filter: brightness(85%); }
143 .cube-right { transform: rotateY(90deg) translateZ(calc(var(--cube-size) / 2)) translateX(calc(var(--cube-size) / 2)); filter: brightness(70%); }
144 .cube-left { transform: rotateY(-90deg) translateZ(calc(var(--cube-size) / 2)) translateX(calc(var(--cube-size) / -2)); filter: brightness(60%); }
145 .cube-back { transform: rotateX(90deg) translateZ(calc(var(--cube-size) / 2)) translateY(calc(var(--cube-size) / 2)); filter: brightness(50%); }
146
147 /* Shadow beneath cube */
148 .shadow {
149 position: absolute;
150 width: calc(var(--cube-size) * 0.8);
151 height: calc(var(--cube-size) * 0.8);
152 background: rgba(0,0,0,0.15);
153 top: 70px;
154 left: 30px;
155 filter: blur(8px);
156 border-radius: 50%;
157 transform: translateZ(1px);
158 animation: shadowScale var(--anim-speed) cubic-bezier(0.47, 0, 0.74, 0.71) infinite;
159 }
160
161 @keyframes shadowScale {
162 0% { transform: scale(0.2) translateZ(1px); opacity: 0; }
163 20% { transform: scale(1.2) translateZ(1px); opacity: 0.4; }
164 25% { transform: scale(1) translateZ(1px); opacity: 0.3; }
165 100% { transform: scale(1) translateZ(1px); opacity: 0.3; }
166 }
167
168 /* Sequential Delays and Colors */
169 .well:nth-child(1) .cube-face { background-color: var(--green); }
170 .well:nth-child(2) .cube-face { background-color: var(--orange); }
171 .well:nth-child(3) .cube-face { background-color: var(--blue); }
172 .well:nth-child(4) .cube-face { background-color: var(--darkblue); }
173 .well:nth-child(5) .cube-face { background-color: var(--olive); }
174
175 /* Repeat colors for seamless loop if needed, but 5 is enough for a cycle */
176 .well:nth-child(1) .cube, .well:nth-child(1) .shadow { animation-delay: 0s; }
177 .well:nth-child(2) .cube, .well:nth-child(2) .shadow { animation-delay: -1s; }
178 .well:nth-child(3) .cube, .well:nth-child(3) .shadow { animation-delay: -2s; }
179 .well:nth-child(4) .cube, .well:nth-child(4) .shadow { animation-delay: -3s; }
180 .well:nth-child(5) .cube, .well:nth-child(5) .shadow { animation-delay: -4s; }
181
182 </style>
183</head>
184<body>
185
186 <div class="scene">
187 <div class="viewport">
188 <div class="track" id="track">
189 <!-- Track units will be generated by JS -->
190 </div>
191 </div>
192 </div>
193
194 <script>
195 const track = document.getElementById('track');
196 const colors = ['green', 'orange', 'blue', 'darkblue', 'olive'];
197
198 // We need several sets of wells to cover the viewport and handle the loop
199 function createWells() {
200 // Creating 15 wells (3 full cycles) to ensure the track is always filled
201 for (let i = 0; i < 15; i++) {
202 const well = document.createElement('div');
203 well.className = 'well';
204
205 well.innerHTML = `218`;
219
220 // Color indices repeat every 5
221 const colorIdx = i % 5;
222 const cubeFaces = well.querySelectorAll('.cube-face');
223 const cube = well.querySelector('.cube');
224 const shadow = well.querySelector('.shadow');
225
226 // Set animation delays based on position in cycle
227 // Note: Delays are negative to start animations at different points in their timeline
228 const delay = (i % 5) * -1;
229 cube.style.animationDelay = `${delay}s`;
230 shadow.style.animationDelay = `${delay}s`;
231
232 track.appendChild(well);
233 }
234 }
235
236 createWells();
237 </script>
238</body>
239</html>