All examples / feature card
Isometric analytics: rising bars and a climbing chart
Four isometric bars on a soft platform rise one after another to their full height, hold, then settle together, while a coral dot climbs the rising line chart on a small standing board. One six-second loop.
Prompt tested
Feature card size
Prompt
Draw a looping isometric illustration for an 'Analytics' feature card as one inline SVG with CSS keyframes only (no JavaScript, no libraries). Scene: a light paper-coloured isometric platform (30° projection). At the back right stand four square isometric bars in a row going diagonally back-left to front-right: three sky-blue bars of medium heights with a dip in the middle, and a taller mint bar last. At the front left stands a small grey board facing right, with a paper-coloured screen showing faint grid lines and a sky-blue line chart that rises from bottom-left to top-right. Motion: the bars start low, rise one after another to their full heights (a short stagger between each), hold, then sink back down together; to keep the top faces undistorted, each bar slides up out of the floor (translate only) and a clip path at its footprint hides the part below the floor. A coral dot fades in at the start of the line chart, climbs it point by point, rests at the top while the bars are full, then fades out. Use a navy outline (#1F2A44, 1.5 px, round joins) and the palette ink #1F2A44, slate #5B6B8C, sky #7FB6FF, mint #6FD6B4, sun #FFC861, coral #FF8A7A, paper #F6F4EF; shade each box with a light top, mid right face and darker left face. Loop every 6 seconds with no visible jump; animate only transform and opacity; add a prefers-reduced-motion rule that stops all animation and leaves a calm still frame with every bar at full height and the dot resting at the top of the line.
Prompt test
A fresh AI session given only the prompt above rebuilt this on 2026-11-03 using claude-opus-5-5; a separate fresh session using claude-opus-5-5 judged it “like this”.


Lesson: Naming the mechanism ("each bar slides up out of the floor (translate only) and a clip path at its footprint hides the part below the floor") got undistorted rising bars on the first try. The prompt did not say how far the bars sink or what shape the platform is, so the rebuild chose its own; say "settle to about 40 % of their height" and "a long, shallow slab" if those matter, and ask for the footprint outline to be redrawn on top of the clip.
Words it rests on
- isometric illustration (30° projection)
- inline SVG
- CSS @keyframes
- seamless loop
- staggered rise (bar chart grow-in)
- translate inside a clip path (rise out of the floor)
- three-tone face shading
- prefers-reduced-motion still frame
- feature card
Facts
- Tags
- feature card css keyframes inline svg svg clip path isometric flat shaded harbor
- Weight
- 1.7 KB gzip (SVG + CSS)
- Needs
- No library, no JavaScript
- Browser support
- All current browsers (Chrome, Edge, Firefox, Safari 15+); CSS transforms on SVG groups inside clip paths.
- Loop
- 6 s, seamless; still frame with reduced motion
- Link
/examples/iso-analytics/
Source
Paste both parts into any page. Wrap the SVG in <div class="ma-iso-analytics"> and put the CSS in a <style> element or your stylesheet; every class, id and animation name starts with ma-iso-analytics, so it will not clash with your styles.
demo.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" role="img" aria-labelledby="ma-iso-analytics-title">
<title id="ma-iso-analytics-title">Bars on an isometric platform rise one after another while a dot climbs a line chart on a standing board</title>
<g stroke="#1F2A44" stroke-width="1.5" stroke-linejoin="round">
<defs>
<clipPath id="ma-iso-analytics-clip-1"><path d="M205.3 0L205.3 143L222.6 153L239.9 143L239.9 0Z" fill="#000" stroke="none"/></clipPath>
<clipPath id="ma-iso-analytics-clip-2"><path d="M229.5 0L229.5 157L246.9 167L264.2 157L264.2 0Z" fill="#000" stroke="none"/></clipPath>
<clipPath id="ma-iso-analytics-clip-3"><path d="M253.8 0L253.8 171L271.1 181L288.4 171L288.4 0Z" fill="#000" stroke="none"/></clipPath>
<clipPath id="ma-iso-analytics-clip-4"><path d="M278 0L278 185L295.4 195L312.7 185L312.7 0Z" fill="#000" stroke="none"/></clipPath>
</defs>
<path d="M156.3 93.7L346.8 203.7L232.5 269.7L42 159.7Z" fill="#1F2A44" opacity=".08"/>
<path d="M352.5 185L238.2 251L238.2 240L352.5 174Z" fill="#C9D2E3"/>
<path d="M47.7 141L238.2 251L238.2 240L47.7 130Z" fill="#A3B0C8"/>
<path d="M162 64L352.5 174L238.2 240L47.7 130Z" fill="#F6F4EF"/>
<path d="M139.5 113L87.5 143L87.5 85L139.5 55Z" fill="#B7C1D3"/>
<path d="M82.3 140L87.5 143L87.5 85L82.3 82Z" fill="#8F9BB3"/>
<path d="M134.3 52L139.5 55L87.5 85L82.3 82Z" fill="#E8ECF3"/>
<path d="M91.9 132.5L135.2 107.5L135.2 63.5L91.9 88.5Z" fill="#F6F4EF" stroke-width="1"/>
<path d="M95.3 119.5L131.7 98.5" fill="none" stroke="#C9D2E3" stroke-width="1" stroke-linecap="round"/>
<path d="M95.3 108.5L131.7 87.5" fill="none" stroke="#C9D2E3" stroke-width="1" stroke-linecap="round"/>
<path d="M95.3 97.5L131.7 76.5" fill="none" stroke="#C9D2E3" stroke-width="1" stroke-linecap="round"/>
<path d="M96.2 124L104.8 109L113.5 107L122.2 90L130.8 74" fill="none" stroke="#7FB6FF" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<g clip-path="url(#ma-iso-analytics-clip-1)">
<g class="ma-iso-analytics-bar ma-iso-analytics-bar-1">
<path d="M239.9 179L222.6 189L222.6 117L239.9 107Z" fill="#7FB6FF"/>
<path d="M205.3 179L222.6 189L222.6 117L205.3 107Z" fill="#5F96E0"/>
<path d="M222.6 97L239.9 107L222.6 117L205.3 107Z" fill="#CFE4FF"/>
</g>
</g>
<path d="M205.3 143L222.6 153L239.9 143" fill="none" stroke="#1F2A44" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<g clip-path="url(#ma-iso-analytics-clip-2)">
<g class="ma-iso-analytics-bar ma-iso-analytics-bar-2">
<path d="M264.2 211L246.9 221L246.9 113L264.2 103Z" fill="#7FB6FF"/>
<path d="M229.5 211L246.9 221L246.9 113L229.5 103Z" fill="#5F96E0"/>
<path d="M246.9 93L264.2 103L246.9 113L229.5 103Z" fill="#CFE4FF"/>
</g>
</g>
<path d="M229.5 157L246.9 167L264.2 157" fill="none" stroke="#1F2A44" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<g clip-path="url(#ma-iso-analytics-clip-3)">
<g class="ma-iso-analytics-bar ma-iso-analytics-bar-3">
<path d="M288.4 217L271.1 227L271.1 135L288.4 125Z" fill="#7FB6FF"/>
<path d="M253.8 217L271.1 227L271.1 135L253.8 125Z" fill="#5F96E0"/>
<path d="M271.1 115L288.4 125L271.1 135L253.8 125Z" fill="#CFE4FF"/>
</g>
</g>
<path d="M253.8 171L271.1 181L288.4 171" fill="none" stroke="#1F2A44" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<g clip-path="url(#ma-iso-analytics-clip-4)">
<g class="ma-iso-analytics-bar ma-iso-analytics-bar-4">
<path d="M312.7 259L295.4 269L295.4 121L312.7 111Z" fill="#6FD6B4"/>
<path d="M278 259L295.4 269L295.4 121L278 111Z" fill="#4FB896"/>
<path d="M295.4 101L312.7 111L295.4 121L278 111Z" fill="#A8E8D2"/>
</g>
</g>
<path d="M278 185L295.4 195L312.7 185" fill="none" stroke="#1F2A44" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<circle class="ma-iso-analytics-dot" cx="96.2" cy="124" r="4.5" fill="#FF8A7A" transform="translate(34.6 -50)"/>
</g>
</svg>
demo.css
/* Isometric analytics card: four bars rise one after another, hold, then settle together,
while a dot climbs the line chart on the board. Loop period 6 s. Each bar slides up out of
the floor (a clip path at its footprint hides the rest), so only transform and opacity animate.
The -3 s delay makes the first frame match the still frame drawn in the markup. */
.ma-iso-analytics svg {
display: block;
width: 100%;
height: auto;
}
.ma-iso-analytics .ma-iso-analytics-bar,
.ma-iso-analytics .ma-iso-analytics-dot {
animation-duration: 6s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-delay: -3s;
}
.ma-iso-analytics .ma-iso-analytics-bar-1 {
animation-name: ma-iso-analytics-bar-1;
}
.ma-iso-analytics .ma-iso-analytics-bar-2 {
animation-name: ma-iso-analytics-bar-2;
}
.ma-iso-analytics .ma-iso-analytics-bar-3 {
animation-name: ma-iso-analytics-bar-3;
}
.ma-iso-analytics .ma-iso-analytics-bar-4 {
animation-name: ma-iso-analytics-bar-4;
}
/* Each bar starts at 40 % of its height, rises in turn, holds, and settles with the others. */
@keyframes ma-iso-analytics-bar-1 {
0%, 6%, 96%, 100% { transform: translate(0px, 21.6px); }
24%, 84% { transform: translate(0px, 0px); }
}
@keyframes ma-iso-analytics-bar-2 {
0%, 11%, 96%, 100% { transform: translate(0px, 32.4px); }
29%, 84% { transform: translate(0px, 0px); }
}
@keyframes ma-iso-analytics-bar-3 {
0%, 16%, 96%, 100% { transform: translate(0px, 27.6px); }
34%, 84% { transform: translate(0px, 0px); }
}
@keyframes ma-iso-analytics-bar-4 {
0%, 21%, 96%, 100% { transform: translate(0px, 44.4px); }
39%, 84% { transform: translate(0px, 0px); }
}
/* The dot fades in at the start of the line, climbs it point by point, rests, then fades. */
.ma-iso-analytics .ma-iso-analytics-dot {
animation-name: ma-iso-analytics-trace;
animation-timing-function: linear;
}
@keyframes ma-iso-analytics-trace {
0%, 100% { transform: translate(0px, 0px); opacity: 0; }
8% { transform: translate(0px, 0px); opacity: 1; }
19% { transform: translate(8.7px, -15px); opacity: 1; }
29% { transform: translate(17.3px, -17px); opacity: 1; }
40% { transform: translate(26px, -34px); opacity: 1; }
50%, 84% { transform: translate(34.6px, -50px); opacity: 1; }
92% { transform: translate(34.6px, -50px); opacity: 0; }
}
/* Calm still frame: every bar at full height and the dot resting at the top of the line. */
@media (prefers-reduced-motion: reduce) {
.ma-iso-analytics,
.ma-iso-analytics * {
animation: none !important;
}
}