animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Neon Loaders

model output

GPT-5.4

Neon Loaders

A 0.80T 0.25
compare with ground truth →
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>Glowing Dots Loader</title>
7<style>
8  :root{
9    --bg-edge:#2b2d31;
10    --bg-mid:#14161a;
11    --bg-core:#050607;
12
13    --pink:#ff0aa8;
14    --violet:#9a4dff;
15    --cyan:#18b8ff;
16
17    --dot-size:min(3.2vmin, 26px);
18    --gap:min(7.8vmin, 80px);
19    --cycle:2.4s;
20  }
21
22  *{box-sizing:border-box}
23  html,body{
24    margin:0;
25    width:100%;
26    height:100%;
27    overflow:hidden;
28    background:
29      radial-gradient(circle at 50% 50%,
30        var(--bg-core) 0%,
31        #07090b 12%,
32        #0d1014 28%,
33        #171a1f 52%,
34        #23262b 78%,
35        var(--bg-edge) 100%);
36  }
37
38  body{
39    display:grid;
40    place-items:center;
41    font-family:system-ui,sans-serif;
42  }
43
44  .stage{
45    position:relative;
46    width:100vw;
47    height:100vh;
48    filter: blur(.15px);
49  }
50
51  .loader{
52    position:absolute;
53    left:50%;
54    top:50%;
55    transform:translate(-50%,-50%);
56    width:calc(var(--gap) * 2 + var(--dot-size));
57    height:calc(var(--dot-size) * 2.2);
58  }
59
60  .dot{
61    position:absolute;
62    top:50%;
63    width:var(--dot-size);
64    height:var(--dot-size);
65    border-radius:50%;
66    transform:translate(-50%,-50%) scale(1);
67    opacity:.18;
68    will-change:opacity, transform, filter;
69  }
70
71  .dot::before{
72    content:"";
73    position:absolute;
74    inset:0;
75    border-radius:50%;
76    background:currentColor;
77    box-shadow:
78      0 0 8px currentColor,
79      0 0 16px currentColor,
80      0 0 28px currentColor;
81  }
82
83  .dot::after{
84    content:"";
85    position:absolute;
86    inset:-55%;
87    border-radius:50%;
88    background:radial-gradient(circle, currentColor 0%, color-mix(in srgb, currentColor 55%, transparent) 28%, transparent 72%);
89    filter:blur(10px);
90    opacity:.55;
91  }
92
93  .pink{ left:0%; color:var(--pink); animation:pulse var(--cycle) infinite ease-in-out; }
94  .violet{ left:50%; color:var(--violet); animation:pulse var(--cycle) infinite ease-in-out .28s; }
95  .cyan{ left:100%; color:var(--cyan); animation:pulse var(--cycle) infinite ease-in-out .56s; }
96
97  @keyframes pulse{
98    0%, 18%{
99      opacity:.16;
100      transform:translate(-50%,-50%) scale(.92);
101      filter:brightness(.65);
102    }
103    28%, 42%{
104      opacity:1;
105      transform:translate(-50%,-50%) scale(1.08);
106      filter:brightness(1.25);
107    }
108    52%{
109      opacity:.72;
110      transform:translate(-50%,-50%) scale(1);
111      filter:brightness(1);
112    }
113    70%, 100%{
114      opacity:.16;
115      transform:translate(-50%,-50%) scale(.92);
116      filter:brightness(.65);
117    }
118  }
119
120  /* subtle center vignette softness */
121  .stage::after{
122    content:"";
123    position:absolute;
124    inset:0;
125    background:
126      radial-gradient(circle at 50% 50%,
127        transparent 0 8%,
128        rgba(0,0,0,.08) 20%,
129        rgba(0,0,0,.18) 42%,
130        rgba(0,0,0,.28) 100%);
131    pointer-events:none;
132    mix-blend-mode:multiply;
133  }
134</style>
135</head>
136<body>
137  <div class="stage">
138    <div class="loader" aria-label="loading animation">
139      <span class="dot pink"></span>
140      <span class="dot violet"></span>
141      <span class="dot cyan"></span>
142    </div>
143  </div>
144
145<script>
146  // Keep the animation phase aligned on load for a clean first frame.
147  document.documentElement.animate(
148    [{ opacity: 1 }, { opacity: 1 }],
149    { duration: 1, fill: "forwards" }
150  );
151</script>
152</body>
153</html>