{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "loader",
  "type": "registry:ui",
  "title": "Loader (MIAN)",
  "description": "Eight loading indicators, dots, bars, wave, grid, pulse, orbit, ring and a top-of-page line, in the current colour.",
  "categories": [
    "feedback",
    "loader",
    "loading",
    "spinner",
    "busy"
  ],
  "registryDependencies": [
    "https://mian.ro/r/mian-base.json"
  ],
  "files": [
    {
      "path": "mian/components/loader.css",
      "type": "registry:file",
      "target": "mian/components/loader.css",
      "content": ".mn-loader { --_s: 1.5rem; position: relative; display: inline-flex; align-items: center; justify-content: center; gap: calc(var(--_s) * .14); width: var(--_s); height: var(--_s); color: var(--_c, var(--mn-primary)); vertical-align: middle; flex: none; }\n.mn-loader-sm { --_s: 1rem; } .mn-loader-lg { --_s: 2.5rem; }\n.mn-loader > i { display: block; flex: none; background: currentColor; }\n/* dots */\n.mn-loader-dots { width: calc(var(--_s) * 1.8); }\n.mn-loader-dots > i { width: calc(var(--_s) * .3); height: calc(var(--_s) * .3); border-radius: 50%; animation: mn-ld-bounce 1s ease-in-out infinite; }\n/* bars (equaliser) */\n.mn-loader-bars > i { width: calc(var(--_s) * .13); height: 100%; border-radius: 2px; transform-origin: 50% 100%; animation: mn-ld-eq 1s ease-in-out infinite; }\n/* wave */\n.mn-loader-wave { width: calc(var(--_s) * 2); }\n.mn-loader-wave > i { width: calc(var(--_s) * .22); height: calc(var(--_s) * .22); border-radius: 50%; animation: mn-ld-wave 1.2s ease-in-out infinite; }\n.mn-loader > i:nth-child(2) { animation-delay: .12s; } .mn-loader > i:nth-child(3) { animation-delay: .24s; } .mn-loader > i:nth-child(4) { animation-delay: .36s; } .mn-loader > i:nth-child(5) { animation-delay: .48s; }\n/* grid of nine squares */\n.mn-loader-grid { display: inline-grid; grid-template-columns: repeat(3, 1fr); gap: calc(var(--_s) * .08); }\n.mn-loader-grid > i { width: 100%; aspect-ratio: 1; border-radius: 2px; animation: mn-ld-fade 1.2s ease-in-out infinite; }\n.mn-loader-grid > i:nth-child(3n+2) { animation-delay: .15s; } .mn-loader-grid > i:nth-child(3n) { animation-delay: .3s; }\n.mn-loader-grid > i:nth-child(n+4) { animation-delay: .2s; } .mn-loader-grid > i:nth-child(n+7) { animation-delay: .4s; }\n/* pulse */\n.mn-loader-pulse::before, .mn-loader-pulse::after { content: \"\"; position: absolute; inset: 0; border-radius: 50%; background: currentColor; animation: mn-ld-pulse 1.6s cubic-bezier(.2, .6, .4, 1) infinite; }\n.mn-loader-pulse::after { animation-delay: .8s; }\n/* orbit */\n.mn-loader-orbit { border-radius: 50%; box-shadow: inset 0 0 0 2px color-mix(in oklab, currentColor 20%, transparent); animation: mn-spin 1.1s linear infinite; }\n.mn-loader-orbit > i { position: absolute; top: calc(var(--_s) * -.08); left: 50%; width: calc(var(--_s) * .26); height: calc(var(--_s) * .26); margin-left: calc(var(--_s) * -.13); border-radius: 50%; }\n.mn-loader-orbit > i + i { top: auto; bottom: calc(var(--_s) * -.08); opacity: .45; }\n/* ring with a fading tail */\n.mn-loader-ring { border-radius: 50%; background: conic-gradient(from 0deg, transparent 10%, currentColor); -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)); mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)); animation: mn-spin .9s linear infinite; }\n/* top-of-page line */\n.mn-loader-line { display: block; width: 100%; height: 3px; overflow: hidden; border-radius: 999px; background: color-mix(in oklab, currentColor 16%, transparent); }\n.mn-loader-line::after { content: \"\"; position: absolute; top: 0; bottom: 0; width: 35%; border-radius: inherit; background: currentColor; animation: mn-ld-line 1.3s cubic-bezier(.6, 0, .4, 1) infinite; }\n@keyframes mn-ld-bounce { 0%, 80%, 100% { transform: scale(.5); opacity: .45; } 40% { transform: scale(1); opacity: 1; } }\n@keyframes mn-ld-eq { 0%, 100% { transform: scaleY(.3); } 50% { transform: scaleY(1); } }\n@keyframes mn-ld-wave { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(calc(var(--_s) * -.35)); } }\n@keyframes mn-ld-fade { 0%, 100% { opacity: .2; transform: scale(.8); } 50% { opacity: 1; transform: scale(1); } }\n@keyframes mn-ld-pulse { from { transform: scale(0); opacity: .8; } to { transform: scale(1); opacity: 0; } }\n@keyframes mn-ld-line { from { left: -35%; } to { left: 100%; } }\n@media (prefers-reduced-motion: reduce) {\n  .mn-loader, .mn-loader > i, .mn-loader::before, .mn-loader::after { animation-duration: 3s !important; }"
    },
    {
      "path": "mian/examples/loader.html",
      "type": "registry:file",
      "target": "mian/examples/loader.html",
      "content": "<!-- Loaders -->\n<span class=\"mn-loader mn-loader-lg mn-loader-dots\" role=\"status\" aria-label=\"Loading\"><i></i><i></i><i></i></span>\n<span class=\"mn-loader mn-loader-lg mn-loader-bars\" role=\"status\" aria-label=\"Loading\"><i></i><i></i><i></i><i></i><i></i></span>\n<span class=\"mn-loader mn-loader-lg mn-loader-wave mn-accent\" role=\"status\" aria-label=\"Loading\"><i></i><i></i><i></i><i></i><i></i></span>\n<span class=\"mn-loader mn-loader-lg mn-loader-grid\" role=\"status\" aria-label=\"Loading\"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span>\n<span class=\"mn-loader mn-loader-lg mn-loader-pulse mn-info\" role=\"status\" aria-label=\"Loading\"></span>\n<span class=\"mn-loader mn-loader-lg mn-loader-orbit\" role=\"status\" aria-label=\"Loading\"><i></i><i></i></span>\n<span class=\"mn-loader mn-loader-lg mn-loader-ring mn-success\" role=\"status\" aria-label=\"Loading\"></span>\n\n<!-- Sizes and a line -->\n<div class=\"mn-stack\" style=\"max-width:24rem\">\n  <div class=\"mn-row\" style=\"--mn-gap:1.25rem\"><span class=\"mn-loader mn-loader-dots mn-loader-sm\" role=\"status\" aria-label=\"Loading\"><i></i><i></i><i></i></span><span class=\"mn-loader mn-loader-dots\" role=\"status\" aria-label=\"Loading\"><i></i><i></i><i></i></span><span class=\"mn-loader mn-loader-dots mn-loader-lg\" role=\"status\" aria-label=\"Loading\"><i></i><i></i><i></i></span></div>\n  <div class=\"mn-card\"><span class=\"mn-loader mn-loader-line\" role=\"status\" aria-label=\"Loading invoices\"></span><div class=\"mn-card-body mn-muted\">Loading invoices…</div></div>\n</div>"
    }
  ],
  "docs": "MIAN components are HTML + CSS classes, not React components. The styles are already included in mian-base; this item adds the component's CSS section and example markup for reference. Docs: https://mian.ro/components/loader",
  "meta": {
    "mian": {
      "license": "LicenseRef-MIAN-1.0",
      "requiresJs": false,
      "classes": [
        "mn-loader",
        "mn-loader-dots · -bars · -wave · -grid",
        "mn-loader-pulse · -ring",
        "mn-loader-orbit",
        "mn-loader-line"
      ],
      "accessibility": [
        "Give the loader role=\"status\" and an aria-label (“Loading invoices”), or put visible text next to it.",
        "Under prefers-reduced-motion every loader slows to a gentle 3-second cycle.",
        "For waits over a few seconds, prefer a progress bar with a value, or a skeleton."
      ],
      "intents": [
        "loading animation",
        "page loader",
        "loading dots",
        "progress line"
      ]
    }
  }
}
