← back to Only CSS: Planet Ringcompare with ground truth →
model output
GPT-5.4
Only CSS: Planet Ring
A 0.71T 0.36
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>Orbit Rings Animation</title>
7<style>
8 :root{
9 --bg:#e7e6f4;
10 --ring:#2f3038;
11 --planet:#ff5a3a;
12 --planet2:#ff6a33;
13 --highlight:#ff7a3f;
14 --stroke:#050505;
15 --size:min(72vmin, 620px);
16 }
17
18 html,body{
19 margin:0;
20 height:100%;
21 overflow:hidden;
22 background:var(--bg);
23 font-family:system-ui,sans-serif;
24 }
25
26 .scene{
27 width:100vw;
28 height:100vh;
29 display:grid;
30 place-items:center;
31 background:var(--bg);
32 }
33
34 svg{
35 width:var(--size);
36 height:var(--size);
37 overflow:visible;
38 }
39
40 .rings{
41 transform-origin:50% 50%;
42 animation: wobble 5.8s linear infinite;
43 }
44
45 .ring{
46 fill:none;
47 stroke:rgba(20,20,24,.74);
48 stroke-width:4.2;
49 vector-effect:non-scaling-stroke;
50 transform-origin:50% 50%;
51 mix-blend-mode:multiply;
52 }
53
54 .planet{
55 transform-origin:50% 50%;
56 animation: planetSpin 5.8s linear infinite;
57 }
58
59 .planet-body{
60 fill:url(#planetGrad);
61 stroke:var(--stroke);
62 stroke-width:7;
63 vector-effect:non-scaling-stroke;
64 }
65
66 .planet-shade{
67 fill:rgba(255,40,40,.18);
68 }
69
70 @keyframes planetSpin{
71 from{ transform:rotate(0deg); }
72 to{ transform:rotate(-360deg); }
73 }
74
75 /* Built to mimic the changing tilt / precession seen in the frames */
76 @keyframes wobble{
77 0% { transform:rotate(0deg) scaleX(1) scaleY(1); }
78 8% { transform:rotate(8deg) scaleX(.34) scaleY(1.08); }
79 16% { transform:rotate(22deg) scaleX(.82) scaleY(.92); }
80 24% { transform:rotate(58deg) scaleX(.38) scaleY(1.06); }
81 32% { transform:rotate(108deg) scaleX(.92) scaleY(.56); }
82 40% { transform:rotate(136deg) scaleX(.12) scaleY(1.18); }
83 48% { transform:rotate(162deg) scaleX(.72) scaleY(.72); }
84 56% { transform:rotate(196deg) scaleX(.96) scaleY(.84); }
85 64% { transform:rotate(228deg) scaleX(.52) scaleY(1.02); }
86 72% { transform:rotate(266deg) scaleX(.98) scaleY(.98); }
87 80% { transform:rotate(302deg) scaleX(.46) scaleY(1.08); }
88 88% { transform:rotate(334deg) scaleX(.86) scaleY(.78); }
89 100% { transform:rotate(360deg) scaleX(1) scaleY(1); }
90 }
91</style>
92</head>
93<body>
94<div class="scene">
95 <svg viewBox="0 0 600 600" aria-label="Abstract orbit animation">
96 <defs>
97 <radialGradient id="planetGrad" cx="38%" cy="34%" r="75%">
98 <stop offset="0%" stop-color="#ff6d38"/>
99 <stop offset="72%" stop-color="#ff6736"/>
100 <stop offset="100%" stop-color="#ff4d31"/>
101 </radialGradient>
102 </defs>
103
104 <g class="rings" id="rings"></g>
105
106 <g class="planet">
107 <circle class="planet-body" cx="300" cy="300" r="88"></circle>
108 <circle class="planet-shade" cx="332" cy="332" r="72"></circle>
109 <ellipse cx="272" cy="262" rx="54" ry="46" fill="rgba(255,170,90,.16)"></ellipse>
110 </g>
111 </svg>
112</div>
113
114<script>
115 const g = document.getElementById('rings');
116 const cx = 300, cy = 300;
117
118 // Compact generation of many concentric ellipses.
119 // Slightly varying opacity/size reproduces the dense dark ring stack.
120 const count = 13;
121 for(let i=0;i<count;i++){
122 const e = document.createElementNS('http://www.w3.org/2000/svg','ellipse');
123 const rx = 92 + i * 18.5;
124 const ry = 92 + i * 18.5;
125 e.setAttribute('class','ring');
126 e.setAttribute('cx',cx);
127 e.setAttribute('cy',cy);
128 e.setAttribute('rx',rx);
129 e.setAttribute('ry',ry);
130 e.style.strokeWidth = (3.2 + i * 0.18).toFixed(2);
131 e.style.opacity = (0.58 + i * 0.025).toFixed(3);
132 g.appendChild(e);
133 }
134</script>
135</body>
136</html>