A hairline isometric smart speaker wakes: an accent arc sweeps once round the light ring on its top face and settles on a spring. The grille is a field of dots on the cylinder's visible half.
Also known as: claude hairline, isometric smart speaker, voice assistant ring animation.
<div class="hln-speaker-ring" role="img" aria-label="A smart speaker with its light ring sweeping">
<svg viewBox="-110 -60 220 120" aria-hidden="true">
<g transform="translate(0 17.9) scale(1.15)">
<g><path d="M-22.63,-30 V0 A22.63,11.31 0 0 0 22.63,0 V-30 Z"/><ellipse cx="0" cy="-30" rx="22.63" ry="11.31"/></g>
<path class="hln-speaker-ring-l hln-speaker-ring-o" d="M-22.63,-3 A22.63,11.31 0 0 0 22.63,-3"/>
<circle class="hln-speaker-ring-l" cx="22.35" cy="-4.23" r=".45"/>
<circle class="hln-speaker-ring-l" cx="20.91" cy="-1.67" r=".45"/>
<circle class="hln-speaker-ring-l" cx="18.31" cy="0.65" r=".45"/>
<circle class="hln-speaker-ring-l" cx="14.7" cy="2.6" r=".45"/>
<circle class="hln-speaker-ring-l" cx="10.27" cy="4.08" r=".45"/>
<circle class="hln-speaker-ring-l" cx="5.28" cy="5" r=".45"/>
<circle class="hln-speaker-ring-l" cx="0" cy="5.31" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-5.28" cy="5" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-10.27" cy="4.08" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-14.7" cy="2.6" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-18.31" cy="0.65" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-20.91" cy="-1.67" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-22.35" cy="-4.23" r=".45"/>
<circle class="hln-speaker-ring-l" cx="22.35" cy="-7.83" r=".45"/>
<circle class="hln-speaker-ring-l" cx="20.91" cy="-5.27" r=".45"/>
<circle class="hln-speaker-ring-l" cx="18.31" cy="-2.95" r=".45"/>
<circle class="hln-speaker-ring-l" cx="14.7" cy="-1" r=".45"/>
<circle class="hln-speaker-ring-l" cx="10.27" cy="0.48" r=".45"/>
<circle class="hln-speaker-ring-l" cx="5.28" cy="1.4" r=".45"/>
<circle class="hln-speaker-ring-l" cx="0" cy="1.71" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-5.28" cy="1.4" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-10.27" cy="0.48" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-14.7" cy="-1" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-18.31" cy="-2.95" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-20.91" cy="-5.27" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-22.35" cy="-7.83" r=".45"/>
<circle class="hln-speaker-ring-l" cx="22.35" cy="-11.43" r=".45"/>
<circle class="hln-speaker-ring-l" cx="20.91" cy="-8.87" r=".45"/>
<circle class="hln-speaker-ring-l" cx="18.31" cy="-6.55" r=".45"/>
<circle class="hln-speaker-ring-l" cx="14.7" cy="-4.6" r=".45"/>
<circle class="hln-speaker-ring-l" cx="10.27" cy="-3.12" r=".45"/>
<circle class="hln-speaker-ring-l" cx="5.28" cy="-2.2" r=".45"/>
<circle class="hln-speaker-ring-l" cx="0" cy="-1.89" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-5.28" cy="-2.2" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-10.27" cy="-3.12" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-14.7" cy="-4.6" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-18.31" cy="-6.55" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-20.91" cy="-8.87" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-22.35" cy="-11.43" r=".45"/>
<circle class="hln-speaker-ring-l" cx="22.35" cy="-15.03" r=".45"/>
<circle class="hln-speaker-ring-l" cx="20.91" cy="-12.47" r=".45"/>
<circle class="hln-speaker-ring-l" cx="18.31" cy="-10.15" r=".45"/>
<circle class="hln-speaker-ring-l" cx="14.7" cy="-8.2" r=".45"/>
<circle class="hln-speaker-ring-l" cx="10.27" cy="-6.72" r=".45"/>
<circle class="hln-speaker-ring-l" cx="5.28" cy="-5.8" r=".45"/>
<circle class="hln-speaker-ring-l" cx="0" cy="-5.49" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-5.28" cy="-5.8" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-10.27" cy="-6.72" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-14.7" cy="-8.2" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-18.31" cy="-10.15" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-20.91" cy="-12.47" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-22.35" cy="-15.03" r=".45"/>
<circle class="hln-speaker-ring-l" cx="22.35" cy="-18.63" r=".45"/>
<circle class="hln-speaker-ring-l" cx="20.91" cy="-16.07" r=".45"/>
<circle class="hln-speaker-ring-l" cx="18.31" cy="-13.75" r=".45"/>
<circle class="hln-speaker-ring-l" cx="14.7" cy="-11.8" r=".45"/>
<circle class="hln-speaker-ring-l" cx="10.27" cy="-10.32" r=".45"/>
<circle class="hln-speaker-ring-l" cx="5.28" cy="-9.4" r=".45"/>
<circle class="hln-speaker-ring-l" cx="0" cy="-9.09" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-5.28" cy="-9.4" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-10.27" cy="-10.32" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-14.7" cy="-11.8" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-18.31" cy="-13.75" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-20.91" cy="-16.07" r=".45"/>
<circle class="hln-speaker-ring-l" cx="-22.35" cy="-18.63" r=".45"/>
<g transform="matrix(1 .5 -1 .5 0 -30)"><circle class="hln-speaker-ring-l" cx="0" cy="0" r="12.6"/><circle class="hln-speaker-ring-l" cx="0" cy="0" r="10.8"/><circle class="hln-speaker-ring-l" cx="-3.5" cy="0" r="0.9"/><circle class="hln-speaker-ring-l" cx="3.5" cy="0" r="0.9"/><g class="hln-speaker-ring-sweep"><path class="hln-speaker-ring-a hln-speaker-ring-o" d="M9.66,-6.61 A11.7,11.7 0 0 1 9.66,6.61"/></g></g>
</g>
</svg>
</div>.hln-speaker-ring {
--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;
}
.hln-speaker-ring svg {
width: 100%;
height: 100%;
overflow: visible;
fill: #ffffff;
stroke: #1c1d21;
stroke-width: 1.25;
stroke-linejoin: round;
stroke-linecap: round;
}
.hln-speaker-ring svg * {
vector-effect: non-scaling-stroke;
}
.hln-speaker-ring .hln-speaker-ring-o {
fill: none;
}
.hln-speaker-ring .hln-speaker-ring-l {
stroke: #9a9ca3;
}
.hln-speaker-ring .hln-speaker-ring-a {
stroke: var(--c);
}
.hln-speaker-ring .hln-speaker-ring-sweep {
animation: hln-speaker-ring-sweep 5s infinite;
}
@keyframes hln-speaker-ring-sweep {
0% { transform: rotate(-120deg); opacity: 0; }
8% { transform: rotate(-120deg); opacity: 0; }
11% { transform: rotate(-90deg); opacity: 1; animation-timing-function: linear(0, 0.031, 0.107, 0.208, 0.321, 0.434, 0.541, 0.639, 0.724, 0.796, 0.855, 0.903, 0.94, 0.968, 0.988, 1.002, 1.011, 1.017, 1.019, 1.02, 1.019, 1.018, 1.016, 1.013, 1.011, 1.009, 1.007, 1.005, 1.004, 1.003, 1.002, 1.001, 1); }
40% { transform: rotate(270deg); opacity: 1; }
82% { transform: rotate(270deg); opacity: 1; animation-timing-function: cubic-bezier(.65,0,.35,1); }
90% { transform: rotate(290deg); opacity: 0; }
100% { transform: rotate(-120deg); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.hln-speaker-ring * {
animation: none !important;
}
}
@media (prefers-reduced-motion: reduce) {
.hln-speaker-ring, .hln-speaker-ring *, .hln-speaker-ring::before, .hln-speaker-ring::after, .hln-speaker-ring *::before, .hln-speaker-ring *::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.