A pointer glides under a finished reply and taps thumbs up: the icon fills, pops and throws a ring of sparks, then Thanks, feedback saved slides in beside the actions with a green check.
Also known as: thumbs up animation, rate response feedback, like button burst.
Done. Sessions now expire after 15 minutes, and the stale token test passes.
<div class="aia-feedback-thumbs-saved" role="status" aria-label="Feedback saved">
<p class="aia-feedback-thumbs-saved-reply">Done. Sessions now expire after 15 minutes, and the stale token test passes.</p>
<div class="aia-feedback-thumbs-saved-actions">
<button type="button" aria-label="Copy"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="8.5" y="8.5" width="12" height="12" rx="2"/><path d="M15.5 8.5V5.5a2 2 0 0 0-2-2h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h3"/></svg></button>
<button type="button" class="aia-feedback-thumbs-saved-up" aria-label="Good response">
<span class="aia-feedback-thumbs-saved-burst" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i></span>
<svg class="aia-feedback-thumbs-saved-line" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7 10.5v10"/><path d="M15 5.9 14 10.5h5.6a2 2 0 0 1 1.9 2.5l-2.2 7.5a2 2 0 0 1-1.9 1.5H4.5a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h2.7a2 2 0 0 0 1.8-1.1L12 3a3 3 0 0 1 3 2.9z"/></svg>
<svg class="aia-feedback-thumbs-saved-fill" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linejoin="round" aria-hidden="true"><path d="M7 10.5v10"/><path d="M15 5.9 14 10.5h5.6a2 2 0 0 1 1.9 2.5l-2.2 7.5a2 2 0 0 1-1.9 1.5H4.5a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h2.7a2 2 0 0 0 1.8-1.1L12 3a3 3 0 0 1 3 2.9z"/></svg>
</button>
<button type="button" aria-label="Bad response"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 13.5v-10"/><path d="M9 18.1l1-4.6H4.4a2 2 0 0 1-1.9-2.5l2.2-7.5a2 2 0 0 1 1.9-1.5h12.9a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-2.7a2 2 0 0 0-1.8 1.1L12 21a3 3 0 0 1-3-2.9z"/></svg></button>
<button type="button" aria-label="Regenerate"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 12a8.5 8.5 0 1 0 2.6-6.1L3.5 8.5"/><path d="M3.5 3.5v5h5"/></svg></button>
<span class="aia-feedback-thumbs-saved-note"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5.5 12.5 4 4 9-9.5"/></svg>Thanks, feedback saved</span>
<svg class="aia-feedback-thumbs-saved-cursor" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 3.5v15.2l4.1-3.9 2.6 6 2.7-1.2-2.6-5.9h5.7z"/></svg>
</div>
</div>.aia-feedback-thumbs-saved {
--c: var(--aia-color, #7c5cff);
font-size: var(--aia-size, 16px);
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
line-height: 1.4;
position: relative;
box-sizing: border-box;
padding: 0.9em 1em;
border-radius: 0.9em;
background: color-mix(in srgb, currentColor 3%, transparent);
box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 11%, transparent), 0 0.1em 0.2em color-mix(in srgb, currentColor 4%, transparent), 0 0.9em 2em -1.1em rgb(0 0 0 / 0.3);
--d: 7s;
--ok: color-mix(in srgb, #16a34a 78%, currentColor);
width: 21em;
padding: 0.85em 0.9em 0.6em;
}
.aia-feedback-thumbs-saved-reply {
margin: 0 0 0.45em 0.25em;
font-size: 0.85em;
line-height: 1.5;
}
.aia-feedback-thumbs-saved-actions {
position: relative;
display: flex;
align-items: center;
gap: 0.15em;
}
.aia-feedback-thumbs-saved-actions button {
position: relative;
display: grid;
place-items: center;
width: 1.9em;
height: 1.9em;
padding: 0;
border: 0;
border-radius: 0.5em;
background: transparent;
color: color-mix(in srgb, currentColor 50%, transparent);
cursor: pointer;
}
.aia-feedback-thumbs-saved-actions button:focus-visible {
outline: 2px solid var(--c);
outline-offset: 1px;
}
.aia-feedback-thumbs-saved-actions button > svg {
grid-area: 1 / 1;
width: 1.05em;
height: 1.05em;
}
.aia-feedback-thumbs-saved-actions .aia-feedback-thumbs-saved-up {
animation: aia-feedback-thumbs-saved-well var(--d) ease infinite;
}
.aia-feedback-thumbs-saved-up > .aia-feedback-thumbs-saved-line {
animation: aia-feedback-thumbs-saved-hide var(--d) ease infinite;
}
.aia-feedback-thumbs-saved-up > .aia-feedback-thumbs-saved-fill {
color: var(--c);
animation: aia-feedback-thumbs-saved-pop var(--d) cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}
.aia-feedback-thumbs-saved-burst {
grid-area: 1 / 1;
position: relative;
width: 0;
height: 0;
}
.aia-feedback-thumbs-saved-burst i {
--a: 0deg;
position: absolute;
left: -0.14em;
top: -0.14em;
width: 0.28em;
height: 0.28em;
border-radius: 50%;
background: var(--c);
opacity: 0;
animation: aia-feedback-thumbs-saved-spark var(--d) cubic-bezier(0.2, 0.7, 0.3, 1) infinite;
}
.aia-feedback-thumbs-saved-burst i:nth-child(2) { --a: 60deg; }
.aia-feedback-thumbs-saved-burst i:nth-child(3) { --a: 120deg; }
.aia-feedback-thumbs-saved-burst i:nth-child(4) { --a: 180deg; }
.aia-feedback-thumbs-saved-burst i:nth-child(5) { --a: 240deg; }
.aia-feedback-thumbs-saved-burst i:nth-child(6) { --a: 300deg; }
.aia-feedback-thumbs-saved-burst i:nth-child(even) { background: color-mix(in srgb, var(--c) 50%, #f59e0b); }
.aia-feedback-thumbs-saved-note {
display: inline-flex;
align-items: center;
gap: 0.35em;
margin-left: 0.5em;
color: color-mix(in srgb, currentColor 60%, transparent);
font-size: 0.74em;
font-weight: 500;
white-space: nowrap;
animation: aia-feedback-thumbs-saved-note var(--d) cubic-bezier(0.3, 1.2, 0.5, 1) infinite;
}
.aia-feedback-thumbs-saved-note svg {
width: 1.15em;
height: 1.15em;
color: var(--ok);
stroke-width: 3;
}
.aia-feedback-thumbs-saved-cursor {
position: absolute;
left: 3.05em;
top: 1.05em;
width: 1.35em;
height: 1.35em;
fill: #111;
stroke: #fff;
stroke-width: 1.4;
stroke-linejoin: round;
filter: drop-shadow(0 0.1em 0.15em rgb(0 0 0 / 0.35));
pointer-events: none;
transform-origin: 20% 15%;
animation: aia-feedback-thumbs-saved-cursor var(--d) cubic-bezier(0.45, 0, 0.25, 1) infinite;
}
@keyframes aia-feedback-thumbs-saved-cursor {
0%, 6% { opacity: 0; transform: translate(9em, 0.2em); }
10% { opacity: 1; transform: translate(8.4em, 0.15em); }
26% { opacity: 1; transform: none; }
29% { transform: scale(0.82); }
32%, 58% { opacity: 1; transform: none; }
72% { opacity: 0; transform: translate(6em, 0.3em); }
100% { opacity: 0; transform: translate(9em, 0.2em); }
}
@keyframes aia-feedback-thumbs-saved-well {
0%, 28%, 96%, 100% { background: transparent; transform: none; }
30% { background: color-mix(in srgb, var(--c) 14%, transparent); transform: scale(0.85); }
34%, 92% { background: color-mix(in srgb, var(--c) 12%, transparent); transform: none; }
}
@keyframes aia-feedback-thumbs-saved-hide {
0%, 30%, 97%, 100% { opacity: 1; }
31%, 95% { opacity: 0; }
}
@keyframes aia-feedback-thumbs-saved-pop {
0%, 30% { opacity: 0; transform: scale(0.5) rotate(0deg); }
36% { opacity: 1; transform: scale(1.35) rotate(-14deg); }
44%, 93% { opacity: 1; transform: none; }
97%, 100% { opacity: 0; transform: scale(0.8); }
}
@keyframes aia-feedback-thumbs-saved-spark {
0%, 31% { opacity: 0; transform: rotate(var(--a)) translateY(-0.75em) scale(1.2); }
33% { opacity: 1; }
47%, 100% { opacity: 0; transform: rotate(var(--a)) translateY(-1.65em) scale(0.3); }
}
@keyframes aia-feedback-thumbs-saved-note {
0%, 38% { opacity: 0; transform: translateX(-0.8em); }
46%, 90% { opacity: 1; transform: none; }
95%, 100% { opacity: 0; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
.aia-feedback-thumbs-saved *,
.aia-feedback-thumbs-saved *::before {
animation-play-state: paused;
animation-delay: calc(var(--d) * -0.6);
}
}
@media (prefers-reduced-motion: reduce) {
.aia-feedback-thumbs-saved, .aia-feedback-thumbs-saved *, .aia-feedback-thumbs-saved::before, .aia-feedback-thumbs-saved::after, .aia-feedback-thumbs-saved *::before, .aia-feedback-thumbs-saved *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--aia-color on the element or a parent.
Currently previewing #3b82f6.--aia-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.