.spinner {
    position: relative;
    width: 64px;
    height: 64px;
}
.spinner::before,
.spinner::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 4px solid transparent;
}
.spinner::before {
    border-top-color: var(--accent);
    border-right-color: var(--accent);
    animation: spin 1s cubic-bezier(.6, .2, .4, .8) infinite;
}
.spinner::after {
    inset: 10px;
    border-bottom-color: var(--accent-2);
    border-left-color: var(--accent-2);
    animation: spin 1.4s linear infinite reverse;
}

.progress {
    width: 100%;
    height: 4px;
    border-radius: 999px;
    background: var(--border);
    overflow: hidden;
}
.progress::before {
    content: "";
    display: block;
    width: 40%;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, var(--accent), var(--accent-2));
    animation: slide 1.6s ease-in-out infinite;
}

.dots::after {
    content: "";
    display: inline-block;
    width: 1.2em;
    text-align: left;
    animation: dots 1.5s steps(4, end) infinite;
}

@keyframes spin  { to { transform: rotate(360deg); } }
@keyframes slide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}
@keyframes dots {
    0%   { content: ""; }
    25%  { content: "."; }
    50%  { content: ".."; }
    75%  { content: "..."; }
}

@media (prefers-reduced-motion: reduce) {
    .spinner::before, .spinner::after,
    .progress::before, .dots::after { animation-duration: 4s; }
}
