Three isometric slabs for app, API and database lift apart on a spring, a signal dot runs down the stack, and they settle back. Inline SVG layers moved by CSS translate.
Also known as: isometric architecture diagram, hairline isometric, exploded stack animation.
<div class="hln-architecture-stack" role="img" aria-label="App, API and database layers lifting apart"> <svg viewBox="-110 -60 220 120" aria-hidden="true"><g transform="translate(0 27) scale(1.22)"><g><g><polygon points="-36,0 0,18 0,13 -36,-5"/><polygon points="36,0 0,18 0,13 36,-5"/><polygon points="0,-23 36,-5 0,13 -36,-5"/></g><ellipse class="hln-architecture-stack-in" cx="-18" cy="-5" rx="4.81" ry="2.4"/><ellipse class="hln-architecture-stack-in" cx="0" cy="-5" rx="4.81" ry="2.4"/><ellipse class="hln-architecture-stack-in" cx="18" cy="-5" rx="4.81" ry="2.4"/></g><line class="hln-architecture-stack-wire" x1="-18" y1="4" x2="-18" y2="-10"/><g class="hln-architecture-stack-mid"><g><polygon points="-36,-7 0,11 0,6 -36,-12"/><polygon points="36,-7 0,11 0,6 36,-12"/><polygon points="0,-30 36,-12 0,6 -36,-12"/></g><line class="hln-architecture-stack-in" x1="1" y1="-21.5" x2="22" y2="-11"/><line class="hln-architecture-stack-in" x1="-5.5" y1="-18.25" x2="15.5" y2="-7.75"/><line class="hln-architecture-stack-in" x1="-12.5" y1="-14.75" x2="8.5" y2="-4.25"/><line class="hln-architecture-stack-in" x1="-19" y1="-11.5" x2="2" y2="-1"/><polygon class="hln-architecture-stack-in" points="-2,-24 0,-23 -2,-22 -4,-23"/><polygon class="hln-architecture-stack-in" points="-8.5,-20.75 -6.5,-19.75 -8.5,-18.75 -10.5,-19.75"/><polygon class="hln-architecture-stack-in" points="-15.5,-17.25 -13.5,-16.25 -15.5,-15.25 -17.5,-16.25"/><polygon class="hln-architecture-stack-in" points="-22,-14 -20,-13 -22,-12 -24,-13"/><line class="hln-architecture-stack-wire" x1="-18" y1="-3" x2="-18" y2="-17"/></g><g class="hln-architecture-stack-top"><g><polygon points="-36,-14 0,4 0,-1 -36,-19"/><polygon points="36,-14 0,4 0,-1 36,-19"/><polygon points="0,-37 36,-19 0,-1 -36,-19"/></g><polygon class="hln-architecture-stack-in" points="0,-33 13,-26.5 0,-20 -13,-26.5"/><polygon class="hln-architecture-stack-in" points="15,-25.5 28,-19 15,-12.5 2,-19"/><polygon class="hln-architecture-stack-in" points="-15,-25.5 -2,-19 -15,-12.5 -28,-19"/><polygon class="hln-architecture-stack-in" points="0,-18 13,-11.5 0,-5 -13,-11.5"/></g><circle class="hln-architecture-stack-dot" cx="-18" cy="-12.5" r="2.1"/></g></svg> </div>
.hln-architecture-stack {
--c: var(--hln-color, #ff4f2e);
font-size: var(--hln-size, 16px);
position: relative;
display: grid;
place-items: center;
width: 22em;
height: 12em;
border-radius: 0.75em;
background: #f6f5f1;
overflow: hidden;
--u: 1px;
}
.hln-architecture-stack svg {
width: 100%;
height: 100%;
overflow: visible;
fill: #ffffff;
stroke: #1c1d21;
stroke-width: 1.25;
stroke-linejoin: round;
stroke-linecap: round;
}
.hln-architecture-stack svg * {
vector-effect: non-scaling-stroke;
}
.hln-architecture-stack .hln-architecture-stack-in {
stroke: #9a9ca3;
}
.hln-architecture-stack .hln-architecture-stack-wire {
stroke: #9a9ca3;
transform-box: fill-box;
transform-origin: 50% 100%;
animation: hln-architecture-stack-grow 5.6s infinite;
}
.hln-architecture-stack .hln-architecture-stack-mid {
animation: hln-architecture-stack-mid 5.6s infinite;
}
.hln-architecture-stack .hln-architecture-stack-top {
animation: hln-architecture-stack-top 5.6s infinite;
}
.hln-architecture-stack .hln-architecture-stack-dot {
fill: var(--c);
stroke: none;
opacity: 0;
animation: hln-architecture-stack-dot 5.6s infinite;
}
@keyframes hln-architecture-stack-mid {
0%, 100% { translate: 0 0; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
4% { translate: 0 0; animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
15% { translate: 0 calc(-13.08 * var(--u)); animation-timing-function: ease-in-out; }
21% { translate: 0 calc(-11.76 * var(--u)); animation-timing-function: ease-in-out; }
26%, 74% { translate: 0 calc(-12 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
88% { translate: 0 0; }
}
@keyframes hln-architecture-stack-top {
0%, 100% { translate: 0 0; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
4% { translate: 0 0; animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
15% { translate: 0 calc(-26.16 * var(--u)); animation-timing-function: ease-in-out; }
21% { translate: 0 calc(-23.52 * var(--u)); animation-timing-function: ease-in-out; }
26%, 74% { translate: 0 calc(-24 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
88% { translate: 0 0; }
}
@keyframes hln-architecture-stack-grow {
0%, 100% { scale: 1 0.14; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
4% { scale: 1 0.14; animation-timing-function: cubic-bezier(0.3, 0, 0.2, 1); }
15% { scale: 1 1.08; animation-timing-function: ease-in-out; }
21% { scale: 1 0.98; animation-timing-function: ease-in-out; }
26%, 74% { scale: 1 1; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
88% { scale: 1 0.14; }
}
@keyframes hln-architecture-stack-dot {
0%, 24% { opacity: 0; translate: 0 calc(-19 * var(--u)); animation-timing-function: ease-out; }
28% { opacity: 1; translate: 0 calc(-19 * var(--u)); animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
40%, 46% { opacity: 1; translate: 0 0; animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
58% { opacity: 1; translate: 0 calc(19 * var(--u)); animation-timing-function: ease-in; }
64%, 100% { opacity: 0; translate: 0 calc(19 * var(--u)); }
}
@media (prefers-reduced-motion: reduce) {
.hln-architecture-stack * {
animation: none !important;
}
.hln-architecture-stack .hln-architecture-stack-mid { translate: 0 calc(-12 * var(--u)); }
.hln-architecture-stack .hln-architecture-stack-top { translate: 0 calc(-24 * var(--u)); }
.hln-architecture-stack .hln-architecture-stack-dot { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.hln-architecture-stack, .hln-architecture-stack *, .hln-architecture-stack::before, .hln-architecture-stack::after, .hln-architecture-stack *::before, .hln-architecture-stack *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hln-color on the element or a parent.
Currently previewing #3b82f6.--hln-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.