/* Braille spinners — MIT License, https://github.com/ledihildawan/unicode-braille-animations */

:root {
  --loader-shimmer-base: #737d95;
  --loader-shimmer-peak: #8bd3ff;
  --loader-glow-lg: 0.625rem;
  --loader-glow-sm: 0.125rem;
  --loader-glow-color: #8bd3ff;
}

.loading-row {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.loading-text {
  color: var(--muted, #a8b0c2);
  font-size: 14px;
}

.braille-loader {
  display: inline-block;
  width: 2.5rem;
  height: 1.25rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  vertical-align: middle;
  line-height: 1;
}

.braille-loader::after {
  display: inline-block;
  white-space: pre;
  font-size: 1.125rem;
  background: linear-gradient(
    90deg,
    var(--loader-shimmer-base) 0%,
    color-mix(in oklch, var(--loader-shimmer-base) 80%, var(--loader-shimmer-peak)) 30%,
    var(--loader-shimmer-peak) 50%,
    color-mix(in oklch, var(--loader-shimmer-base) 80%, var(--loader-shimmer-peak)) 70%,
    var(--loader-shimmer-base) 100%
  );
  background-size: 200% auto;
  color: transparent;
  -webkit-background-clip: text;
  background-clip: text;
  will-change: background-position, filter;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .braille-loader::after {
    animation: none !important;
    content: "⠋" !important;
    filter: none !important;
    background: none !important;
    color: var(--accent, #8bd3ff) !important;
  }
}

@keyframes l-swp { 0% { background-position: 200% center; filter: brightness(0.6) contrast(1.2); } 50% { filter: brightness(1.5) drop-shadow(0 0 var(--loader-glow-sm) var(--loader-glow-color)) drop-shadow(0 0 var(--loader-glow-lg) color-mix(in oklch, var(--loader-glow-color) 40%, transparent)); } 100% { background-position: -200% center; filter: brightness(0.6) contrast(1.2); } }

@keyframes l-swp-diag { 0% { background-position: 200% 200%; filter: brightness(0.6) contrast(1.2); } 50% { filter: brightness(1.5) drop-shadow(0 0 var(--loader-glow-sm) var(--loader-glow-color)) drop-shadow(0 0 var(--loader-glow-lg) color-mix(in oklch, var(--loader-glow-color) 40%, transparent)); } 100% { background-position: -200% -200%; filter: brightness(0.6) contrast(1.2); } }

@keyframes l-swp-y-dn { 0% { background-position: center -200%; filter: brightness(0.6) contrast(1.2); } 50% { filter: brightness(1.5) drop-shadow(0 0 var(--loader-glow-sm) var(--loader-glow-color)) drop-shadow(0 0 var(--loader-glow-lg) color-mix(in oklch, var(--loader-glow-color) 40%, transparent)); } 100% { background-position: center 200%; filter: brightness(0.6) contrast(1.2); } }

@keyframes l-swp-y-up { 0% { background-position: center 200%; filter: brightness(0.6) contrast(1.2); } 50% { filter: brightness(1.5) drop-shadow(0 0 var(--loader-glow-sm) var(--loader-glow-color)) drop-shadow(0 0 var(--loader-glow-lg) color-mix(in oklch, var(--loader-glow-color) 40%, transparent)); } 100% { background-position: center -200%; filter: brightness(0.6) contrast(1.2); } }

@keyframes l-brt-sync { 0%, 100% { opacity: 0.3; filter: brightness(0.5); background-position: 200% center; } 45%, 55% { opacity: 1; filter: brightness(1.6) drop-shadow(0 0 var(--loader-glow-sm) var(--loader-glow-color)) drop-shadow(0 0 calc(var(--loader-glow-lg) * 1.5) color-mix(in oklch, var(--loader-glow-color) 50%, transparent)); background-position: 50% center; } }

@keyframes l-pls-sync { 0%, 50%, 100% { opacity: 0.3; filter: brightness(0.5); background-position: 200% center; } 18% { opacity: 1; filter: brightness(1.8) drop-shadow(0 0 var(--loader-glow-sm) var(--loader-glow-color)) drop-shadow(0 0 calc(var(--loader-glow-lg) * 2) color-mix(in oklch, var(--loader-glow-color) 60%, transparent)); background-position: 50% center; } 34% { background-position: -100% center; } }

@keyframes l-glc-sync { 0%, 60%, 100% { filter: brightness(.6); } 12%, 18%, 45%, 85%, 90% { filter: brightness(2) drop-shadow(0 0 var(--loader-glow-sm) var(--loader-glow-color)) drop-shadow(0 0 var(--loader-glow-lg) color-mix(in oklch, var(--loader-glow-color) 50%, transparent)); } }

@keyframes sp-csc{0%,100%{content:"⠁⠀⠀⠀"}7.1%{content:"⠋⠀⠀⠀"}14.2%{content:"⠞⠁⠀⠀"}21.4%{content:"⡴⠋⠀⠀"}28.5%{content:"⣠⠞⠁⠀"}35.7%{content:"⢀⡴⠋⠀"}42.8%{content:"⠀⣠⠞⠁"}50%{content:"⠀⢀⡴⠋"}57.1%{content:"⠀⠀⣠⠞"}64.2%{content:"⠀⠀⢀⡴"}71.4%{content:"⠀⠀⠀⣠"}78.5%{content:"⠀⠀⠀⢀"}85.7%,92.8%{content:"⠀⠀⠀⠀"}}

@keyframes sp-wav{0%,100%{content:"⠑⢄⠔⠑"}12.5%{content:"⠊⠆⢄⠊"}25%{content:"⠢⠑⢄⠢"}37.5%{content:"⢄⠢⠑⢄"}50%{content:"⠔⢄⠢⠔"}62.5%{content:"⠒⠔⢄⠒"}75%{content:"⠆⠒⠔⠆"}87.5%{content:"⠁⠆⠒⠁"}}

@keyframes sp-hlx{0%,100%{content:"⢁⠦⠔⡈"}16.6%{content:"⠦⠔⡈⠔"}33.3%{content:"⠔⡈⠔⠦"}50%{content:"⡈⠔⠦⢁"}66.6%{content:"⠔⠦⢁⠦"}83.3%{content:"⠦⢁⠦⠔"}}

@keyframes sp-ran{0%,100%{content:"⠁⠄⠂⡀"}12.5%{content:"⠊⡀⠌⠀"}25%{content:"⠔⠈⡐⠁"}37.5%{content:"⡀⠑⠡⠊"}50%{content:"⠡⠢⢂⠔"}62.5%{content:"⢂⢄⠄⡠"}75%{content:"⠄⡀⡀⢀"}87.5%{content:"⡀⠀⠁⠁"}}

@keyframes sp-brt{0%{content:"⠀"}8%{content:"⠁"}15%{content:"⠑"}21%{content:"⠕"}26%{content:"⢕"}30%{content:"⢝"}34%{content:"⢟"}38%{content:"⢿"}45%,55%{content:"⣿"}62%{content:"⢿"}66%{content:"⢟"}70%{content:"⢝"}74%{content:"⢕"}79%{content:"⠕"}85%{content:"⠑"}92%{content:"⠁"}100%{content:"⠀"}}

@keyframes sp-dgl{0%,100%{content:"⠀⠀"}7.1%{content:"⠁⠀"}14.2%{content:"⠋⠀"}21.4%{content:"⠟⠁"}28.5%{content:"⡿⠋"}35.7%{content:"⣿⠟"}42.8%{content:"⣿⡿"}50%{content:"⣿⣿"}57.1%{content:"⣾⣿"}64.2%{content:"⣴⣿"}71.4%{content:"⣠⣾"}78.5%{content:"⢀⣴"}85.7%{content:"⠀⣠"}92.8%{content:"⠀⢀"}}

@keyframes sp-pls{0%,100%{content:"⠀⠶⠀"}10%{content:"⠰⣿⠆"}18%{content:"⢾⣿⡷"}26%{content:"⢾⣉⡷"}34%{content:"⣏⣉⣹"}42%{content:"⡁⠀⢈"}50%{content:"⠀⠶⠀"}}

@keyframes sp-snk{0%{content:"⣁⠀⠀"}6.25%{content:"⡉⠀⠀"}12.5%{content:"⠉⠀⠁"}18.75%{content:"⠈⠀⠉"}25%{content:"⠀⠀⠙"}31.25%{content:"⠀⠀⠚"}37.5%{content:"⠐⠀⠒"}43.75%{content:"⠒⠀⠂"}50%{content:"⠖⠀⠀"}56.25%{content:"⠦⠀⠀"}62.5%{content:"⠤⠀⠄"}68.75%{content:"⠠⠀⠤"}75%{content:"⠀⠀⢤"}81.25%{content:"⠀⠀⣠"}87.5%{content:"⢀⠀⣀"}93.75%{content:"⣀⠀⡀"}100%{content:"⣁⠀⠀"}}

@keyframes sp-glc{0%,60%,100%{content:"⢕⢕⢕"}12%,85%{content:"⡪⡪⡪"}18%,90%{content:"⢊⠔⡡"}45%{content:"⡡⢊⠔"}}

@keyframes sp-col{0%,100%{content:"⠀⠀⠀"}4%{content:"⡀⠀⠀"}8%{content:"⡄⠀⠀"}12%{content:"⡆⠀⠀"}16%{content:"⡇⠀⠀"}20%{content:"⣇⠀⠀"}24%{content:"⣧⠀⠀"}28%{content:"⣷⠀⠀"}32%{content:"⣿⠀⠀"}36%{content:"⣿⡀⠀"}40%{content:"⣿⡄⠀"}44%{content:"⣿⡆⠀"}48%{content:"⣿⡇⠀"}52%{content:"⣿⣇⠀"}56%{content:"⣿⣧⠀"}60%{content:"⣿⣷⠀"}64%{content:"⣿⠀"}68%{content:"⣿⣿⡀"}72%{content:"⣿⣿⡄"}76%{content:"⣿⣿⡆"}80%{content:"⣿⣿⡇"}84%{content:"⣿⣿⣇"}88%{content:"⣿⣿⣧"}92%{content:"⣿⣿⣷"}96%{content:"⣿⣿⣿"}}

@keyframes sp-scn{0%{content:"⣿⠀⠀⠀"}16.6%{content:"⢸⡇⠀⠀"}33.3%{content:"⠀⣿⠀⠀"}50%{content:"⠀⢸⡇⠀"}66.6%{content:"⠀⠀⣿⠀"}83.3%{content:"⠀⠀⢸⡇"}100%{content:"⠀⠀⠀⣿"}}

@keyframes sp-swp{0%{content:"⠀⠀⠀"}12.5%{content:"⣀⠀⣀"}25%{content:"⣤⠀⣤"}37.5%{content:"⣶⠀⣶"}50%{content:"⣿⠀⣿"}62.5%{content:"⣶⠀⣶"}75%{content:"⣤⠀⣤"}87.5%{content:"⣀⠀⣀"}100%{content:"⠀⠀⠀"}}

@keyframes sp-orb{0%{content:"⠉"}12.5%{content:"⠘"}25%{content:"⠰"}37.5%{content:"⢠"}50%{content:"⣀"}62.5%{content:"⡄"}75%{content:"⠆"}87.5%{content:"⠃"}100%{content:"⠉"}}

@keyframes sp-spr{0%,90%,100%{content:"⠀⠁⠀⠂"}10%{content:"⠠⠀⢀⠀"}20%{content:"⠀⠐⠉⠁"}30%{content:"⠁⠂⠀⠐"}40%{content:"⠑⠊⠔⠢"}50%{content:"⠀⢀⠠⠀"}60%{content:"⠂⠀⠁⠀"}70%{content:"⠐⠀⠐⠀"}80%{content:"⢀⠠⠑⠊"}}

@keyframes sp-bsc{0%{content:"⠋"}10%{content:"⠙"}20%{content:"⠹"}30%{content:"⠸"}40%{content:"⠼"}50%{content:"⠴"}60%{content:"⠦"}70%{content:"⠧"}80%{content:"⠇"}90%{content:"⠏"}100%{content:"⠋"}}

.spinner-cascade::after { content: "⠁⠀⠀⠀"; animation: sp-csc 1.1s step-end infinite, l-swp-diag 1.1s linear infinite; }

.spinner-wave::after { content: "⠑⢄⠔⠑"; animation: sp-wav 0.8s step-end infinite, l-swp 0.8s linear infinite; }

.spinner-helix::after { content: "⢁⠦⠔⡈"; animation: sp-hlx 0.6s step-end infinite, l-swp 0.6s ease-in-out infinite alternate; }

.spinner-rain::after { content: "⠁⠄⠂⡀"; animation: sp-ran 0.7s step-end infinite, l-swp-y-dn 0.7s linear infinite; }

.spinner-breathe::after { content: "⠀"; animation: sp-brt 2.2s step-end infinite, l-brt-sync 2.2s ease-in-out infinite; }

.spinner-diagonal::after { content: "⠀⠀"; animation: sp-dgl 1.12s step-end infinite, l-swp-diag 1.12s linear infinite; }

.spinner-pulse::after { content: "⠀⠶⠀"; animation: sp-pls 1.4s step-end infinite, l-pls-sync 1.4s cubic-bezier(.1,.9,.2,1) infinite; }

.spinner-snake::after { content: "⣁⠀⠀"; animation: sp-snk 1.2s step-end infinite, l-swp 0.6s ease-in-out infinite alternate; }

.spinner-glitch::after { content: "⢕⢕⢕"; animation: sp-glc 0.8s step-end infinite, l-glc-sync 0.8s step-end infinite; }

.spinner-columns::after { content: "⠀⠀⠀"; animation: sp-col 1.8s step-end infinite, l-swp-y-up 1.8s linear infinite; }

.spinner-scan::after { content: "⣿⠀⠀⠀"; animation: sp-scn 0.6s step-end infinite alternate, l-swp 0.6s ease-in-out infinite alternate; }

.spinner-sweep::after { content: "⠀⠀⠀"; animation: sp-swp 1.4s step-end infinite, l-swp-y-up 0.7s ease-in-out infinite alternate; }

.spinner-orbit::after { content: "⠉"; animation: sp-orb 0.6s step-end infinite, l-swp 0.6s linear infinite; }

.spinner-sparkle::after { content: "⠀⠁⠀⠂"; animation: sp-spr 0.5s step-end infinite, l-glc-sync 0.5s step-end infinite; }

.spinner-basic::after { content: "⠋"; animation: sp-bsc 0.8s step-end infinite, l-swp 0.8s linear infinite; }
