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>9-dot Morph Grid Animation</title>
7<style>
8 :root{
9 --bg:#f2f2f2;
10 --gray:#6b6b6b;
11 --gray-light:#b9b9b9;
12 --coral:#ff7f78;
13 --blue:#aee6f6;
14 --size:48px;
15 --gap:36px;
16 --dur:4.8s;
17 --ease:cubic-bezier(.42,0,.2,1);
18 }
19
20 html,body{
21 height:100%;
22 margin:0;
23 background:var(--bg);
24 overflow:hidden;
25 font-family:system-ui,sans-serif;
26 }
27
28 .stage{
29 height:100%;
30 display:grid;
31 place-items:center;
32 }
33
34 .grid{
35 position:relative;
36 width:calc(var(--size) * 3 + var(--gap) * 2);
37 height:calc(var(--size) * 3 + var(--gap) * 2);
38 }
39
40 .dot{
41 position:absolute;
42 width:var(--size);
43 height:var(--size);
44 left:calc(var(--c) * (var(--size) + var(--gap)));
45 top:calc(var(--r) * (var(--size) + var(--gap)));
46 border-radius:11px;
47 background:var(--gray);
48 transform-origin:center;
49 animation:tile var(--dur) var(--ease) infinite;
50 animation-delay:var(--delay, 0s);
51 will-change:transform, border-radius, background-color, opacity;
52 }
53
54 @keyframes tile{
55 /* initial dark rounded squares */
56 0%,10%{
57 transform:scale(1) rotate(0deg);
58 border-radius:11px;
59 background:var(--gray);
60 opacity:1;
61 }
62
63 /* shrink and soften */
64 18%{
65 transform:scale(.62) rotate(8deg);
66 border-radius:12px;
67 background:#8f8f8f;
68 opacity:.95;
69 }
70
71 /* become tiny gray dots */
72 28%,34%{
73 transform:scale(.28) rotate(0deg);
74 border-radius:50%;
75 background:var(--gray-light);
76 opacity:.95;
77 }
78
79 /* color phase begins */
80 42%{
81 transform:scale(var(--s1,.42)) rotate(0deg);
82 border-radius:50%;
83 background:var(--c1,var(--gray-light));
84 opacity:1;
85 }
86
87 /* coral/blue diamonds */
88 52%,60%{
89 transform:scale(var(--s2,.78)) rotate(45deg);
90 border-radius:10px;
91 background:var(--c2,var(--gray-light));
92 opacity:1;
93 }
94
95 /* wave shifts downward */
96 70%{
97 transform:scale(var(--s3,.62)) rotate(45deg);
98 border-radius:10px;
99 background:var(--c3,var(--gray-light));
100 opacity:1;
101 }
102
103 /* fade back to gray dots */
104 82%{
105 transform:scale(.30) rotate(0deg);
106 border-radius:50%;
107 background:var(--g2,#b3b3b3);
108 opacity:1;
109 }
110
111 /* rebuild dark squares from top */
112 92%{
113 transform:scale(var(--s4,.72)) rotate(var(--r4,4deg));
114 border-radius:10px;
115 background:var(--c4,#8a8a8a);
116 opacity:1;
117 }
118
119 100%{
120 transform:scale(1) rotate(0deg);
121 border-radius:11px;
122 background:var(--gray);
123 opacity:1;
124 }
125 }
126
127 /* positions */
128 .d0{--r:0;--c:0;}
129 .d1{--r:0;--c:1;}
130 .d2{--r:0;--c:2;}
131 .d3{--r:1;--c:0;}
132 .d4{--r:1;--c:1;}
133 .d5{--r:1;--c:2;}
134 .d6{--r:2;--c:0;}
135 .d7{--r:2;--c:1;}
136 .d8{--r:2;--c:2;}
137
138 /* color/scale choreography approximating the frame sequence */
139
140 /* top row */
141 .d0{
142 --c1:#e7b2b0; --s1:.42;
143 --c2:var(--coral); --s2:.86;
144 --c3:#d9b0ae; --s3:.46;
145 --g2:#8f8f8f;
146 --c4:var(--gray); --s4:.96; --r4:-4deg;
147 }
148 .d1{
149 --c1:#dfb0ae; --s1:.40;
150 --c2:var(--coral); --s2:.82;
151 --c3:#d4afad; --s3:.44;
152 --g2:#a8a8a8;
153 --c4:#7a7a7a; --s4:.82; --r4:-6deg;
154 }
155 .d2{
156 --c1:#d8afad; --s1:.38;
157 --c2:#f58f89; --s2:.78;
158 --c3:#d8b0ae; --s3:.52;
159 --g2:#b0b0b0;
160 --c4:#8a8a8a; --s4:.62; --r4:-3deg;
161 }
162
163 /* middle row */
164 .d3{
165 --c1:#cdb7b8; --s1:.34;
166 --c2:#f39a95; --s2:.72;
167 --c3:var(--coral); --s3:.84;
168 --g2:#b0b0b0;
169 --c4:#8d8d8d; --s4:.78; --r4:-7deg;
170 }
171 .d4{
172 --c1:var(--gray-light); --s1:.30;
173 --c2:var(--blue); --s2:.74;
174 --c3:var(--blue); --s3:.74;
175 --g2:#b8c8cf;
176 --c4:#9a9a9a; --s4:.62; --r4:-8deg;
177 }
178 .d5{
179 --c1:#c8b8b8; --s1:.32;
180 --c2:#e59a96; --s2:.66;
181 --c3:var(--coral); --s3:.82;
182 --g2:#b7b0b0;
183 --c4:#9f9f9f; --s4:.46; --r4:0deg;
184 }
185
186 /* bottom row */
187 .d6{
188 --c1:#bdbdbd; --s1:.28;
189 --c2:#dca09d; --s2:.52;
190 --c3:var(--coral); --s3:.82;
191 --g2:#c4b0b0;
192 --c4:#b8b8b8; --s4:.30; --r4:0deg;
193 }
194 .d7{
195 --c1:#bdbdbd; --s1:.28;
196 --c2:#d89f9b; --s2:.50;
197 --c3:#ff8a82; --s3:.78;
198 --g2:#c8b8b8;
199 --c4:#bdbdbd; --s4:.28; --r4:0deg;
200 }
201 .d8{
202 --c1:#bdbdbd; --s1:.28;
203 --c2:#d59d99; --s2:.48;
204 --c3:#ff8d85; --s3:.86;
205 --g2:#d2b0ae;
206 --c4:#c2c2c2; --s4:.28; --r4:0deg;
207 }
208
209 /* subtle stagger to mimic organic propagation */
210 .d0,.d1,.d2{ animation-delay:0s; }
211 .d3,.d4,.d5{ animation-delay:.08s; }
212 .d6,.d7,.d8{ animation-delay:.16s; }
213
214 /* keep overall composition slightly smaller like the reference */
215 .grid{
216 transform:scale(.92);
217 }
218</style>
219</head>
220<body>
221 <div class="stage">
222 <div class="grid" aria-label="animated 3 by 3 dot grid">
223 <div class="dot d0"></div>
224 <div class="dot d1"></div>
225 <div class="dot d2"></div>
226 <div class="dot d3"></div>
227 <div class="dot d4"></div>
228 <div class="dot d5"></div>
229 <div class="dot d6"></div>
230 <div class="dot d7"></div>
231 <div class="dot d8"></div>
232 </div>
233 </div>
234</body>
235</html>