/**
 * Braille Unicode Spinner Animations
 * CSS-only. No JS, no SVG.
 *
 * Canonical CSS-only BrailleSpinner for the marketing site (mirrors the totem app's BrailleSpinner patterns).
 * Font is self-hosted via global.css @font-face (Chrome extension CSP).
 *
 * Usage:
 *   <span class="loader breathe"></span>
 *
 * Canonical screen → pattern mapping lives in the component, not here.
 */

.loader {
  display: inline-block;
  font: 200 24px/1 "Cascadia Mono", "JetBrains Mono", monospace;
  /* color and opacity are driven by keyframes — no base value here */
  text-align: center;
  min-width: 1ch;
}

.loader::after {
  display: block;
}

/* ─── 1-char patterns ──────────────────────────────────────────────── */

/*
 * braille — fast diagnostic spinner, unchanged
 */
.loader.braille::after {
  animation: braille 800ms linear infinite;
  content: '⠁';
}
@keyframes braille {
  0%    { content: '⠁'; }
  12.5% { content: '⠈'; }
  25%   { content: '⠐'; }
  37.5% { content: '⠠'; }
  50%   { content: '⢀'; }
  62.5% { content: '⡀'; }
  75%   { content: '⠄'; }
  87.5% { content: '⠂'; }
  100%  { content: '⠁'; }
}

/*
 * orbit — 14 s slow drift.
 * The dot is ALWAYS visible — starts as a tiny dim grey speck, grows
 * and turns copper at its peak position, retreats back to a speck
 * before teleporting to the next position.
 *
 * Each of 8 positions = 12.5% (1.75 s).
 * Within each slot:
 *   arrive (small, dim grey) → peak (scale 1.35, copper) → retreat (small, dim)
 *
 * transform/color interpolate smoothly. content jumps discretely.
 */
.loader.orbit::after {
  animation: orbit 14000ms linear infinite;
  content: '⠂';
}
@keyframes orbit {
  /* ── position 1 · ⠂ ── */
  0%     { content: '⠂'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  3%     { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  9%     { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  12%    { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  /* ── position 2 · ⠄ ── */
  12.5%  { content: '⠄'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  15.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  21.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  24.5%  { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  /* ── position 3 · ⡀ ── */
  25%    { content: '⡀'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  28%    { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  34%    { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  37%    { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  /* ── position 4 · ⢀ ── */
  37.5%  { content: '⢀'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  40.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  46.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  49.5%  { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  /* ── position 5 · ⠠ ── */
  50%    { content: '⠠'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  53%    { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  59%    { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  62%    { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  /* ── position 6 · ⠐ ── */
  62.5%  { content: '⠐'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  65.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  71.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  74.5%  { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  /* ── position 7 · ⠈ ── */
  75%    { content: '⠈'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  78%    { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  84%    { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  87%    { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  /* ── position 8 · ⠁ ── */
  87.5%  { content: '⠁'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  90.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  96.5%  { transform: scale(1.35); color: #D4AF37; opacity: 0.95; }
  99.5%  { transform: scale(0.75); color: #3a3530; opacity: 0.30; }
  100%   { content: '⠂'; transform: scale(0.75); color: #3a3530; opacity: 0.30; }
}

/*
 * breathe — 12 s organic breathing cycle.
 *
 * Rest state is ⠆ (a few dots visible) NOT ⠀ (blank) — the spinner
 * is always visible as a small dim cluster. As it inhales, it fills,
 * grows, and shifts to copper gold. At full (⣿) it glows at peak.
 * Then it exhales back to the dim small cluster.
 *
 *   0  – 28 % : inhale  (⠆ → ⣿, scale 0.80 → 1.20, grey → copper)
 *   28 – 48 % : hold full  (⣿, copper)
 *   48 – 76 % : exhale  (⣿ → ⠆, copper → grey, scale 1.20 → 0.80)
 *   76 – 100% : rest (⠆, dim, scale 0.80)
 */
.loader.breathe::after {
  animation: breathe 12000ms linear infinite;
  content: '⠆';
}
@keyframes breathe {
  /* — inhale — */
  0%    { content: '⠆'; transform: scale(0.80); color: #3a3530; opacity: 0.32; }
  7%    { content: '⠇'; transform: scale(0.88); color: #5a4535; opacity: 0.45; }
  13%   { content: '⠏'; transform: scale(0.96); color: #8b5a2b; opacity: 0.58; }
  19%   { content: '⠟'; transform: scale(1.05); color: #b07030; opacity: 0.72; }
  24%   { content: '⠿'; transform: scale(1.13); color: #c49030; opacity: 0.84; }
  28%   { content: '⣿'; transform: scale(1.20); color: #D4AF37; opacity: 0.95; }
  /* — hold full — */
  36%   { content: '⣿'; transform: scale(1.20); color: #D4AF37; opacity: 0.95; }
  44%   { content: '⣿'; transform: scale(1.17); color: #D4AF37; opacity: 0.90; }
  48%   { content: '⣿'; transform: scale(1.14); color: #c49030; opacity: 0.86; }
  /* — exhale — */
  54%   { content: '⠿'; transform: scale(1.06); color: #b07030; opacity: 0.74; }
  60%   { content: '⠟'; transform: scale(0.99); color: #8b5a2b; opacity: 0.62; }
  65%   { content: '⠏'; transform: scale(0.93); color: #5a4535; opacity: 0.50; }
  70%   { content: '⠇'; transform: scale(0.86); color: #3a3530; opacity: 0.40; }
  76%   { content: '⠆'; transform: scale(0.80); color: #3a3530; opacity: 0.32; }
  /* — rest — always visible as a small dim cluster — */
  100%  { content: '⠆'; transform: scale(0.80); color: #3a3530; opacity: 0.32; }
}
 *
 * Each of 8 positions occupies 12.5% (= 1.5 s).
 * Within each slot:
 *   arrive  → peak (scale 1.3, copper, opacity 0.95) → retreat (scale 0.8, grey, opacity 0.20)
 *
 * transform and color interpolate smoothly; content jumps discretely.
 */
.loader.orbit::after {
  animation: orbit 12000ms linear infinite;
  content: '⠂';
}
@keyframes orbit {
  /* ── position 1 · ⠂ ── */
  0%     { content: '⠂'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  2%     { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  8%     { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  11.5%  { transform: scale(0.80); color: #525252; opacity: 0.20; }
  /* ── position 2 · ⠄ ── */
  12.5%  { content: '⠄'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  14.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  20.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  24%    { transform: scale(0.80); color: #525252; opacity: 0.20; }
  /* ── position 3 · ⡀ ── */
  25%    { content: '⡀'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  27%    { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  33%    { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  36.5%  { transform: scale(0.80); color: #525252; opacity: 0.20; }
  /* ── position 4 · ⢀ ── */
  37.5%  { content: '⢀'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  39.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  45.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  49%    { transform: scale(0.80); color: #525252; opacity: 0.20; }
  /* ── position 5 · ⠠ ── */
  50%    { content: '⠠'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  52%    { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  58%    { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  61.5%  { transform: scale(0.80); color: #525252; opacity: 0.20; }
  /* ── position 6 · ⠐ ── */
  62.5%  { content: '⠐'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  64.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  70.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  74%    { transform: scale(0.80); color: #525252; opacity: 0.20; }
  /* ── position 7 · ⠈ ── */
  75%    { content: '⠈'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  77%    { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  83%    { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  86.5%  { transform: scale(0.80); color: #525252; opacity: 0.20; }
  /* ── position 8 · ⠁ ── */
  87.5%  { content: '⠁'; transform: scale(0.80); color: #525252; opacity: 0.20; }
  89.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  95.5%  { transform: scale(1.30); color: #D4AF37; opacity: 0.95; }
  99%    { transform: scale(0.80); color: #525252; opacity: 0.20; }
  100%   { content: '⠂'; transform: scale(0.80); color: #525252; opacity: 0.20; }
}

/*
 * breathe — 11 s organic breathing cycle.
 * As the cell FILLS, the whole glyph grows and shifts to copper.
 * At full (⣿): scale 1.2, copper, glowing — the "lead" moment.
 * As it EMPTIES: shrinks back, colour drains to grey.
 * Long rest at empty before the next breath.
 *
 *   0  – 30 % : inhale  (⠀ → ⣿, scale 0.85 → 1.20, grey → copper)
 *   30 – 48 % : hold full  (⣿, scale eases 1.20 → 1.15)
 *   48 – 78 % : exhale  (⣿ → ⠀, scale 1.15 → 0.85, copper → grey)
 *   78 – 100% : rest empty (⠀, scale 0.85, very dim)
 */
.loader.breathe::after {
  animation: breathe 11000ms linear infinite;
  content: '⠀';
}
@keyframes breathe {
  /* — inhale — */
  0%    { content: '⠀'; transform: scale(0.85); color: #525252; opacity: 0.18; }
  5%    { content: '⠄'; transform: scale(0.90); color: #6b6560; opacity: 0.30; }
  10%   { content: '⠆'; transform: scale(0.95); color: #8b5a2b; opacity: 0.44; }
  15%   { content: '⠇'; transform: scale(1.00); color: #9e7040; opacity: 0.58; }
  19%   { content: '⠏'; transform: scale(1.06); color: #b07030; opacity: 0.70; }
  23%   { content: '⠟'; transform: scale(1.12); color: #c49030; opacity: 0.82; }
  27%   { content: '⠿'; transform: scale(1.17); color: #D4AF37; opacity: 0.90; }
  30%   { content: '⣿'; transform: scale(1.20); color: #D4AF37; opacity: 0.95; }
  /* — hold full — */
  38%   { content: '⣿'; transform: scale(1.20); color: #D4AF37; opacity: 0.95; }
  46%   { content: '⣿'; transform: scale(1.15); color: #D4AF37; opacity: 0.88; }
  48%   { content: '⣿'; transform: scale(1.15); color: #c49030; opacity: 0.84; }
  /* — exhale — */
  53%   { content: '⠿'; transform: scale(1.08); color: #b07030; opacity: 0.72; }
  58%   { content: '⠟'; transform: scale(1.02); color: #9e7040; opacity: 0.60; }
  62%   { content: '⠏'; transform: scale(0.97); color: #8b5a2b; opacity: 0.48; }
  66%   { content: '⠇'; transform: scale(0.93); color: #6b6560; opacity: 0.38; }
  70%   { content: '⠆'; transform: scale(0.89); color: #525252; opacity: 0.28; }
  74%   { content: '⠄'; transform: scale(0.86); color: #525252; opacity: 0.22; }
  78%   { content: '⠀'; transform: scale(0.85); color: #525252; opacity: 0.18; }
  /* — rest empty — */
  100%  { content: '⠀'; transform: scale(0.85); color: #525252; opacity: 0.18; }
  88.2%  { content: '⠀'; }
  94.1%  { content: '⠀'; }
  100%   { content: '⠀'; }
}

/* ─── 2-char patterns ──────────────────────────────────────────────── */

.loader.snake { min-width: 2ch; }
.loader.snake::after {
  animation: snake 1280ms linear infinite;
  content: '⠂⠀';
}
@keyframes snake {
  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: '⠂⠀'; }
}

.loader.fillsweep { min-width: 2ch; }
.loader.fillsweep::after {
  animation: fillsweep 1050ms linear infinite;
  content: '⠀⠀';
}
@keyframes fillsweep {
  0%     { content: '⠀⠀'; }
  3.2%   { content: '⡀⠀'; }
  6.5%   { content: '⣀⠀'; }
  9.7%   { content: '⣄⠀'; }
  12.9%  { content: '⣤⠀'; }
  16.1%  { content: '⣦⠀'; }
  19.4%  { content: '⣶⠀'; }
  22.6%  { content: '⣷⠀'; }
  25.8%  { content: '⣿⠀'; }
  29%    { content: '⣿⡀'; }
  32.3%  { content: '⣿⣀'; }
  35.5%  { content: '⣿⣄'; }
  38.7%  { content: '⣿⣤'; }
  41.9%  { content: '⣿⣦'; }
  45.2%  { content: '⣿⣶'; }
  48.4%  { content: '⣿⣷'; }
  51.6%  { content: '⣿⣿'; }
  54.8%  { content: '⣷⣿'; }
  58.1%  { content: '⣦⣿'; }
  61.3%  { content: '⣤⣿'; }
  64.5%  { content: '⣄⣿'; }
  67.7%  { content: '⣀⣿'; }
  71%    { content: '⡀⣿'; }
  74.2%  { content: '⠀⣿'; }
  77.4%  { content: '⠀⣷'; }
  80.6%  { content: '⠀⣦'; }
  83.9%  { content: '⠀⣤'; }
  87.1%  { content: '⠀⣄'; }
  90.3%  { content: '⠀⣀'; }
  93.5%  { content: '⠀⡀'; }
  96.8%  { content: '⠀⠀'; }
  100%   { content: '⠀⠀'; }
}

.loader.diagswipe { min-width: 2ch; }
.loader.diagswipe::after {
  animation: diagswipe 960ms linear infinite;
  content: '⠁⠀';
}
@keyframes diagswipe {
  0%    { content: '⠁⠀'; }
  7.7%  { content: '⠃⠀'; }
  15.4% { content: '⠇⠀'; }
  23.1% { content: '⡇⠀'; }
  30.8% { content: '⡇⠁'; }
  38.5% { content: '⡇⠃'; }
  46.2% { content: '⡇⠇'; }
  53.8% { content: '⡇⡇'; }
  61.5% { content: '⠀⡇'; }
  69.2% { content: '⠀⠇'; }
  76.9% { content: '⠀⠃'; }
  84.6% { content: '⠀⠁'; }
  92.3% { content: '⠀⠀'; }
  100%  { content: '⠁⠀'; }
}

.loader.helix { min-width: 2ch; }
.loader.helix::after {
  animation: helix 1280ms linear infinite;
  content: '⡇⢸';
}
@keyframes helix {
  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: '⡇⢸'; }
}

/* ─── 3-char patterns ──────────────────────────────────────────────── */

/*
 * pulse — 12 s gentle heartbeat.
 * Rest state is ⠂⠂⠂ (three small dim dots), always visible.
 * Centre column leads: blooms copper + grows. Flanks follow dimmer.
 * Long rest between beats.
 */
.loader.pulse { min-width: 3ch; }
.loader.pulse::after {
  animation: pulse 12000ms linear infinite;
  content: '⠂⠂⠂';
}
@keyframes pulse {
  /* — rest — */
  0%    { content: '⠂⠂⠂'; transform: scale(0.78); color: #3a3530; opacity: 0.28; }
  10%   { content: '⠂⠂⠂'; transform: scale(0.78); color: #3a3530; opacity: 0.28; }
  /* — bloom: centre leads — */
  16%   { content: '⠂⠇⠂'; transform: scale(0.90); color: #6b5535; opacity: 0.42; }
  22%   { content: '⠆⣇⠆'; transform: scale(1.02); color: #9e6030; opacity: 0.60; }
  27%   { content: '⠇⣷⠇'; transform: scale(1.12); color: #c49030; opacity: 0.78; }
  32%   { content: '⠇⣿⠇'; transform: scale(1.20); color: #D4AF37; opacity: 0.95; }
  /* — hold peak — */
  40%   { content: '⠇⣿⠇'; transform: scale(1.20); color: #D4AF37; opacity: 0.95; }
  46%   { content: '⠇⣿⠇'; transform: scale(1.16); color: #D4AF37; opacity: 0.88; }
  /* — fade: flanks first — */
  52%   { content: '⠆⣷⠆'; transform: scale(1.06); color: #c49030; opacity: 0.74; }
  57%   { content: '⠂⣇⠂'; transform: scale(0.96); color: #9e6030; opacity: 0.58; }
  62%   { content: '⠂⠇⠂'; transform: scale(0.88); color: #6b5535; opacity: 0.44; }
  67%   { content: '⠂⠂⠂'; transform: scale(0.78); color: #3a3530; opacity: 0.28; }
  /* — long rest — */
  100%  { content: '⠂⠂⠂'; transform: scale(0.78); color: #3a3530; opacity: 0.28; }
}

.loader.columns { min-width: 3ch; }
.loader.columns::after {
  animation: columns 1560ms linear infinite;
  content: '⠀⠀⠀';
}
@keyframes columns {
  0%    { content: '⠀⠀⠀'; }
  2.9%  { content: '⠄⠀⠀'; }
  5.9%  { content: '⠆⠀⠀'; }
  8.8%  { content: '⠇⠀⠀'; }
  11.8% { content: '⡇⠀⠀'; }
  14.7% { content: '⣇⠀⠀'; }
  17.6% { content: '⣧⠀⠀'; }
  20.6% { content: '⣷⠀⠀'; }
  23.5% { content: '⣿⠀⠀'; }
  26.5% { content: '⣿⠄⠀'; }
  29.4% { content: '⣿⠆⠀'; }
  32.4% { content: '⣿⠇⠀'; }
  35.3% { content: '⣿⡇⠀'; }
  38.2% { content: '⣿⣇⠀'; }
  41.2% { content: '⣿⣧⠀'; }
  44.1% { content: '⣿⣷⠀'; }
  47.1% { content: '⣿⣿⠀'; }
  50%   { content: '⣿⣿⠄'; }
  52.9% { content: '⣿⣿⠆'; }
  55.9% { content: '⣿⣿⠇'; }
  58.8% { content: '⣿⣿⡇'; }
  61.8% { content: '⣿⣿⣇'; }
  64.7% { content: '⣿⣿⣧'; }
  67.6% { content: '⣿⣿⣷'; }
  70.6% { content: '⣿⣿⣿'; }
  73.5% { content: '⠿⣿⣿'; }
  76.5% { content: '⠏⣿⣿'; }
  79.4% { content: '⠁⣿⣿'; }
  82.4% { content: '⠀⠿⣿'; }
  85.3% { content: '⠀⠏⣿'; }
  88.2% { content: '⠀⠁⣿'; }
  91.2% { content: '⠀⠀⠿'; }
  94.1% { content: '⠀⠀⠏'; }
  97.1% { content: '⠀⠀⠁'; }
  100%  { content: '⠀⠀⠀'; }
}

.loader.checkerboard { min-width: 3ch; }
.loader.checkerboard::after {
  animation: checkerboard 1000ms step-start infinite;
  content: '⡕⢪⡕';
}
@keyframes checkerboard {
  0%   { content: '⡕⢪⡕'; }
  50%  { content: '⢪⡕⢪'; }
  100% { content: '⡕⢪⡕'; }
}

/* ─── 4-char patterns ──────────────────────────────────────────────── */

.loader.scan { min-width: 4ch; }
.loader.scan::after {
  animation: scan 700ms linear infinite;
  content: '⡀⠀⠀⠀';
}
@keyframes scan {
  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: '⡀⠀⠀⠀'; }
}

.loader.cascade { min-width: 4ch; }
.loader.cascade::after {
  animation: cascade 840ms linear infinite;
  content: '⠁⠀⠀⠀';
}
@keyframes cascade {
  0%    { content: '⠁⠀⠀⠀'; }
  11.1% { content: '⠉⠁⠀⠀'; }
  22.2% { content: '⠙⠉⠁⠀'; }
  33.3% { content: '⠹⠙⠉⠁'; }
  44.4% { content: '⠸⠹⠙⠉'; }
  55.6% { content: '⠀⠸⠹⠙'; }
  66.7% { content: '⠀⠀⠸⠹'; }
  77.8% { content: '⠀⠀⠀⠸'; }
  88.9% { content: '⠀⠀⠀⠀'; }
  100%  { content: '⠁⠀⠀⠀'; }
}

.loader.rain { min-width: 4ch; }
.loader.rain::after {
  animation: rain 1200ms linear infinite;
  content: '⠁⠀⠀⠀';
}
@keyframes rain {
  0%    { content: '⠁⠀⠀⠀'; }
  11.1% { content: '⠉⠁⠀⠀'; }
  22.2% { content: '⠹⠉⠁⠀'; }
  33.3% { content: '⢹⠹⠉⠁'; }
  44.4% { content: '⢸⢹⠹⠉'; }
  55.6% { content: '⠀⢸⢹⠹'; }
  66.7% { content: '⠀⠀⢸⢹'; }
  77.8% { content: '⠀⠀⠀⢸'; }
  88.9% { content: '⠀⠀⠀⠀'; }
  100%  { content: '⠁⠀⠀⠀'; }
}

.loader.sparkle { min-width: 4ch; }
.loader.sparkle::after {
  animation: sparkle 900ms linear infinite;
  content: '⠀⠀⠀⠀';
}
@keyframes sparkle {
  0%    { content: '⠀⠀⠀⠀'; }
  8.3%  { content: '⠁⠀⠀⠀'; }
  16.7% { content: '⠀⠈⠀⠀'; }
  25%   { content: '⠁⠀⠁⠀'; }
  33.3% { content: '⠀⠈⠀⠈'; }
  41.7% { content: '⠁⠈⠀⠀'; }
  50%   { content: '⠀⠀⠁⠈'; }
  58.3% { content: '⡀⠀⠀⢀'; }
  66.7% { content: '⠀⢀⡀⠀'; }
  75%   { content: '⡀⠈⠁⢀'; }
  83.3% { content: '⠁⢀⡀⠈'; }
  91.7% { content: '⠀⠀⠀⠀'; }
  100%  { content: '⠀⠀⠀⠀'; }
}

.loader.waverows { min-width: 4ch; }
.loader.waverows::after {
  animation: waverows 1440ms linear infinite;
  content: '⠒⠒⠒⠒';
}
@keyframes waverows {
  0%    { content: '⠒⠒⠒⠒'; }
  8.3%  { content: '⠛⠒⠒⠒'; }
  16.7% { content: '⠿⠛⠒⠒'; }
  25%   { content: '⣿⠿⠛⠒'; }
  33.3% { content: '⣿⣿⠿⠛'; }
  41.7% { content: '⣿⣿⣿⠿'; }
  50%   { content: '⣿⣿⣿⣿'; }
  58.3% { content: '⠿⣿⣿⣿'; }
  66.7% { content: '⠛⠿⣿⣿'; }
  75%   { content: '⠒⠛⠿⣿'; }
  83.3% { content: '⠒⠒⠛⠿'; }
  91.7% { content: '⠒⠒⠒⠛'; }
  100%  { content: '⠒⠒⠒⠒'; }
}
