← back to Thinking about SVG-preloaderscompare with ground truth →
model output
GPT-5.4
Thinking about SVG-preloaders
A 0.91T 0.25
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" />
6<title>Rotating Dot Loader</title>
7<style>
8 :root{
9 --bg:#050607;
10 --grid1:rgba(255,255,255,.035);
11 --grid2:rgba(255,255,255,.02);
12 --size:120px;
13 --dot:18px;
14 --radius:44px;
15 --count:12;
16 --dur:1.15s;
17 }
18
19 html,body{
20 height:100%;
21 margin:0;
22 overflow:hidden;
23 background:
24 repeating-linear-gradient(45deg,var(--grid1) 0 1px,transparent 1px 12px),
25 repeating-linear-gradient(-45deg,var(--grid2) 0 1px,transparent 1px 12px),
26 radial-gradient(circle at 50% 50%, #07090b 0%, #030405 70%, #020304 100%);
27 background-color:var(--bg);
28 }
29
30 body{
31 display:grid;
32 place-items:center;
33 font-family:system-ui,sans-serif;
34 }
35
36 .loader{
37 position:relative;
38 width:var(--size);
39 height:var(--size);
40 transform:translateY(-6px);
41 animation:spin var(--dur) linear infinite;
42 filter: drop-shadow(0 0 4px rgba(255,210,80,.06));
43 }
44
45 .dot{
46 position:absolute;
47 left:50%;
48 top:50%;
49 width:var(--dot);
50 height:var(--dot);
51 margin:calc(var(--dot) / -2);
52 border-radius:50%;
53 transform:
54 rotate(calc(var(--i) * 30deg))
55 translateY(calc(var(--radius) * -1));
56 background:hsl(var(--h), 82%, var(--l));
57 opacity:var(--a);
58 box-shadow:0 0 8px color-mix(in srgb, currentColor 35%, transparent);
59 }
60
61 @keyframes spin{
62 from{ transform:translateY(-6px) rotate(0deg); }
63 to{ transform:translateY(-6px) rotate(360deg); }
64 }
65
66 /* Slight softness like the reference */
67 .loader::after{
68 content:"";
69 position:absolute;
70 inset:22px;
71 border-radius:50%;
72 background:radial-gradient(circle, rgba(0,0,0,0) 55%, rgba(0,0,0,.08) 100%);
73 pointer-events:none;
74 }
75</style>
76</head>
77<body>
78 <div class="loader" id="loader" aria-label="Loading animation"></div>
79
80<script>
81 const loader = document.getElementById('loader');
82
83 // Ordered to match the visible color sweep in the frames:
84 // bright yellow -> lime -> blue -> violet -> maroon -> orange/brown trail
85 const hues = [48, 60, 215, 255, 320, 350, 8, 18, 28, 34, 40, 44];
86 const light = [50, 48, 56, 60, 58, 18, 22, 28, 34, 40, 45, 48];
87 const alpha = [1, .95, .92, .55, .22, .14, .18, .34, .52, .68, .82, .92];
88
89 for(let i=0;i<12;i++){
90 const d = document.createElement('span');
91 d.className = 'dot';
92 d.style.setProperty('--i', i);
93 d.style.setProperty('--h', hues[i]);
94 d.style.setProperty('--l', light[i] + '%');
95 d.style.setProperty('--a', alpha[i]);
96 loader.appendChild(d);
97 }
98</script>
99</body>
100</html>