{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "spinner-ladeindikator",
 "name": "Spinner und Ladeindikatoren",
 "name_en": "Loading spinner / loaders",
 "kurz": "Ein Ring mit atmendem Bogen, zwölf verblassende Balken oder die gezeichnete Blattkontur aus dem Logo: Ladeindikatoren im Spenden-Knopf und in einer Terminliste eines Weimarer Baumvereins.",
 "kategorie": "Mikroanimationen",
 "kategorie_slug": "mikroanimationen",
 "kategorie_nr": 9,
 "bau_chat": "C4",
 "prioritaet": "B",
 "trendstatus": "etabliert",
 "belegstatus": "belegt",
 "website_belege": 2,
 "stimmung": [
  "ruhig",
  "präzise"
 ],
 "stimmung_roh": [
  "funktional",
  "ruhig"
 ],
 "technik": [
  "css",
  "svg"
 ],
 "technik_gruppen": [
  "css",
  "canvas"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Ein Indikator für unbestimmte Wartezeiten. Gängige Formen: ein Ring mit wachsendem und schrumpfendem Bogen, zwölf Balken, die reihum verblassen, springende oder pulsierende Punkte, sich füllender Text oder ein endlos gezeichneter Pfad. Nativ geht das 2026 mit einem <progress> ohne value: conic-gradient mit background-clip: border-area, Drehung 1,5 s linear, Bogen 3 s ease-in-out.",
  "warum_es_wirkt": "Der Indikator sagt: Das System arbeitet, deine Eingabe ist angekommen. Gleichmäßige Bewegung beruhigt beim Warten. Mit einer eigenen Form, etwa der Logo-Kontur, wird er zum Gestaltungselement der Marke.",
  "wann_einsetzen": "Kurze, unbestimmte Wartezeiten: in Buttons nach dem Absenden, in Overlays und in Inline-Bereichen, die nachladen.",
  "wann_nicht": "Bei bekannter Dauer, dann den Fortschritt zeigen. Beim Laden der Seitenstruktur, dann Skeleton. Nicht als Preloader vor der ganzen Seite.",
  "varianten": [
   "Nativer <progress>-Ring mit conic-gradient und atmendem Bogen",
   "12-Balken-Spinner mit Opacity-Abfall von 1 auf .15 (Sonner bei Attio 1,2 s, Geist-Spinner bei Vercel 16 px)",
   "Springende Punkte, Puls-Punkte, Ripple",
   "Text, der sich füllt",
   "Endlos gezeichneter SVG-Pfad, etwa die Logo-Kontur",
   "Ladelinie oben am Bildschirm"
  ],
  "umsetzung": "<progress class=\"spinner\" aria-label=\"Lädt\"></progress>. CSS: appearance: none; inline-size: 40px; aspect-ratio: 1; border-radius: 50%; border: 2px solid transparent; background: conic-gradient(var(--farbe) var(--bogen), var(--spur) 0) border-area; background-clip: border-area; animation: drehen 1.5s linear infinite, bogen 3s ease-in-out infinite. --bogen per @property als <percentage> registrieren, damit es animierbar ist. ::-webkit-progress-bar und ::-webkit-progress-value transparent setzen. Rückfall ohne border-area: die Innenfläche mit mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 0) ausstanzen. Im Button den Indikator aria-hidden setzen, den Knopf auf aria-disabled stellen und den Status über eine role=\"status\"-Region ansagen; die Knopfbreite fest halten, damit nichts springt.",
  "mobil": "Identisch.",
  "reduzierte_bewegung": "Verlangsamen statt anhalten, etwa auf 6 s je Umdrehung. Ein stehender Spinner wirkt wie ein Absturz.",
  "barrierefreiheit": "Natives <progress> mit aria-label, keine zusätzliche Rolle nötig. Eigene Formen bekommen role=\"progressbar\" und aria-label. Der ladende Bereich trägt aria-busy=\"true\", das Ergebnis kommt über aria-live an. Dekorative Indikatoren im Button sind aria-hidden, der Status wird per role=\"status\" angesagt."
 },
 "messwerte": {
  "easing": "linear (Rotation); ease-in-out (Bogen)",
  "dauer_ms": "1500 Rotation; 3000 Bogen; 6000 bei Reduced Motion; 1200 (Attio/Sonner)",
  "stagger_ms": "",
  "distanz": "40 px Größe, 2 px Ring; 16 px (Vercel)",
  "sonstiges": "12-Balken-Spinner mit Opacity-Abfall 1 → .15",
  "herkunft": "beobachtet",
  "quelle": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-components/spinner; https://attio.com/ ; https://vercel.com/"
 },
 "kurve": {
  "bezier": [
   0.42,
   0,
   0.58,
   1
  ],
  "css": "cubic-bezier(0.42, 0, 0.58, 1)",
  "name": "ease-in-out",
  "dauer_ms": 1500
 },
 "gesehen_bei": [
  {
   "seite": "Chrome Developers: Spinner",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-components/spinner",
   "auszeichnung": "",
   "beobachtung": "<progress aria-label='Loading'> ohne value; 40 px, 2 px Ring, Rotation 1.5 s linear infinite, Bogen 3 s ease-in-out via @property; Reduced Motion: 6 s.",
   "art": "artikel"
  },
  {
   "seite": "Motion Examples: Loading jumping dots / circle spinner / fill text",
   "url": "https://motion.dev/examples/js-loading-jumping-dots",
   "auszeichnung": "",
   "beobachtung": "Offizielle Loader-Beispielfamilie (JS/React/Vue).",
   "art": "demo"
  },
  {
   "seite": "Attio",
   "url": "https://attio.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (Chunk 1cl_mt6_hc4us.js): Sonner-Spinner mit 12 Balken (Array(12)), .sonner-loading-bar animation sonner-spin 1.2s linear infinite.",
   "art": "website"
  },
  {
   "seite": "Vercel",
   "url": "https://vercel.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (Bundle 2tcg760-ilivm.css): Geist-Spinner – @keyframes spinner-opacity {0% opacity 1 → opacity .15}, Größe über --spinner-size (16px).",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Chrome: Spinner",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-components/spinner"
  }
 ],
 "kombinierbar_mit": [
  "button-zustaende",
  "skeleton-shimmer",
  "fortschrittsring"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/mikroanimationen/spinner-ladeindikator/",
  "meta": "https://cecodesign.de/lab/fundus/mikroanimationen/spinner-ladeindikator/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/mikroanimationen/spinner-ladeindikator/demo"
 },
 "herkunft": {
  "quelldateien": [
   "hover.json",
   "r3-belege-b.json"
  ],
  "pruefnotizen": [
   "r3-belege-b.json (Runde 3, 31.10.2026): Zwei Produktionsbelege für den 12-Balken-Typ."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Ein Ring mit atmendem Bogen, zwölf verblassende Balken oder die gezeichnete Blattkontur aus dem Logo: Ladeindikatoren im Spenden-Knopf und in einer Terminliste eines Weimarer Baumvereins.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "groesse_px": "40 im Inline-Bereich, 16 im Knopf",
   "strich_px": 2,
   "ring": "<progress> ohne value, conic-gradient(Farbe var(--bogen), Spur 0) mit background-clip: border-area; Rückfall: mask radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px))",
   "ring_drehung": "1500 ms linear, unendlich",
   "ring_bogen": "@property --bogen 8 % → 72 % → 8 %, 3000 ms cubic-bezier(0.42, 0, 0.58, 1), unendlich",
   "balken": "12 Balken, je 30° gedreht, 27 % × 8,5 % der Größe, Abstand vom Mittelpunkt translateX(68 %)",
   "balken_opacity": "1 → 0.15, 1200 ms linear, unendlich, Versatz 100 ms je Balken (negativer delay)",
   "blattkontur": "ein SVG-Pfad (Logo), pathLength 100, stroke-dasharray 100 100, stroke-dashoffset 100 → 0 → -100 in 3000 ms cubic-bezier(0.42, 0, 0.58, 1); Spur in 16 % der Farbe darunter; vector-effect: non-scaling-stroke",
   "spur_farbe": "color-mix(in srgb, currentColor 16%, transparent)",
   "farben": "auf Petrol #0f3d37: Weiß; im gelben Knopf #ffca0a: Tinte #222520",
   "knopf_zustaende": "bereit → lädt (2400 ms) → danke (2200 ms) → bereit; Ebenen gleiten um 70 % senkrecht und blenden über, 200 ms cubic-bezier(0.645, 0.045, 0.355, 1); Knopf behält seine Breite",
   "liste_ladezeit_ms": "1600 bei Ortswechsel, 1800 beim Start (Vorführung 3000)",
   "liste_einblenden": "opacity 0 → 1 und translateY 8 px → 0, 400 ms cubic-bezier(0.645, 0.045, 0.355, 1), Versatz 60 ms je Zeile",
   "ui_ms": "200 cubic-bezier(0.645, 0.045, 0.355, 1) für Schalter und Chips; Knopf-Hintergrund 150 ms linear",
   "reduziert": "jede Schleife 6000 ms (Drehung, Balken, Blattkontur), Bogen fest 25 %, Zustandswechsel nur opacity 150 ms linear"
  },
  "ausloeser": "klick",
  "touch": "Identisch, der Spinner braucht keinen Zeiger. Orts-Chips und Varianten-Schalter haben unter hover: none 40 bzw. 36 px Höhe; Hover-Farben gibt es nur bei hover: hover.",
  "reduziert": "Indikatoren laufen weiter, aber langsam: jede Schleife 6 s statt 1,2 bis 3 s. Der Ring dreht nur noch, sein Bogen steht fest bei 25 %. Knopf-Zustände und Listenzeilen blenden nur per opacity in 150 ms um, ohne Gleiten.",
  "korrekturen": {
   "beschreibung": "Ein Indikator für unbestimmte Wartezeiten. Gängige Formen: ein Ring mit wachsendem und schrumpfendem Bogen, zwölf Balken, die reihum verblassen, springende oder pulsierende Punkte, sich füllender Text oder ein endlos gezeichneter Pfad. Nativ geht das 2026 mit einem <progress> ohne value: conic-gradient mit background-clip: border-area, Drehung 1,5 s linear, Bogen 3 s ease-in-out.",
   "warum_es_wirkt": "Der Indikator sagt: Das System arbeitet, deine Eingabe ist angekommen. Gleichmäßige Bewegung beruhigt beim Warten. Mit einer eigenen Form, etwa der Logo-Kontur, wird er zum Gestaltungselement der Marke.",
   "wann_einsetzen": "Kurze, unbestimmte Wartezeiten: in Buttons nach dem Absenden, in Overlays und in Inline-Bereichen, die nachladen.",
   "wann_nicht": "Bei bekannter Dauer, dann den Fortschritt zeigen. Beim Laden der Seitenstruktur, dann Skeleton. Nicht als Preloader vor der ganzen Seite.",
   "varianten": [
    "Nativer <progress>-Ring mit conic-gradient und atmendem Bogen",
    "12-Balken-Spinner mit Opacity-Abfall von 1 auf .15 (Sonner bei Attio 1,2 s, Geist-Spinner bei Vercel 16 px)",
    "Springende Punkte, Puls-Punkte, Ripple",
    "Text, der sich füllt",
    "Endlos gezeichneter SVG-Pfad, etwa die Logo-Kontur",
    "Ladelinie oben am Bildschirm"
   ],
   "umsetzung": "<progress class=\"spinner\" aria-label=\"Lädt\"></progress>. CSS: appearance: none; inline-size: 40px; aspect-ratio: 1; border-radius: 50%; border: 2px solid transparent; background: conic-gradient(var(--farbe) var(--bogen), var(--spur) 0) border-area; background-clip: border-area; animation: drehen 1.5s linear infinite, bogen 3s ease-in-out infinite. --bogen per @property als <percentage> registrieren, damit es animierbar ist. ::-webkit-progress-bar und ::-webkit-progress-value transparent setzen. Rückfall ohne border-area: die Innenfläche mit mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 0) ausstanzen. Im Button den Indikator aria-hidden setzen, den Knopf auf aria-disabled stellen und den Status über eine role=\"status\"-Region ansagen; die Knopfbreite fest halten, damit nichts springt.",
   "mobil": "Identisch.",
   "reduzierte_bewegung": "Verlangsamen statt anhalten, etwa auf 6 s je Umdrehung. Ein stehender Spinner wirkt wie ein Absturz.",
   "barrierefreiheit": "Natives <progress> mit aria-label, keine zusätzliche Rolle nötig. Eigene Formen bekommen role=\"progressbar\" und aria-label. Der ladende Bereich trägt aria-busy=\"true\", das Ergebnis kommt über aria-live an. Dekorative Indikatoren im Button sind aria-hidden, der Status wird per role=\"status\" angesagt."
  },
  "geprueft": "01.11.2026",
  "notiz": "Spenden- und Mitmachseite des erfundenen Vereins Ilmlinde e. V. (Stadtbäume für Weimar), nach Rezept verein-nonprofit-wirkung: Big Shoulders 800 versal, Archivo, Geist Mono; Petrol #0f3d37 als Markenton (Bäume statt Wasser), helles Grün #eaf2ef, Gelb #ffca0a nur für Spenden. Eigene Bildwelt: Jahresringe als SVG und ein Lindenblatt als Logo. Der Spinner zeigt sich in zwei Größen: 40 px in der Terminliste (lädt beim Start und bei jedem Ortswechsel, aria-busy) und 16 px im Spenden-Knopf (bereit, lädt, danke). Umschalter: Ring (nativer <progress> mit border-area und Masken-Rückfall), 12 Balken (Sonner/Geist), Blattkontur (Logo-Pfad zeichnet sich endlos). Werte aus den Messwerten (Chrome-Spinner, Attio, Vercel). Das Rezept verbietet Preloader; die Demo zeigt deshalb nur Inline- und Button-Indikatoren. Vorführung: Termine laden, 60 € wählen, spenden, Ort wechseln, dann nächste Variante (Start mit Blattkontur). AD-Review 01.11.2026: Note 4. Zeilenhöhe der Headline .95 → 1.02, die Ü-Punkte stießen an die Ziffern der ersten Zeile. Zugang 02.11.2026: --leise Alpha .62 → .7 (≥ 5:1 auch auf Mint #eaf2ef); Kontrastmodus-Rahmen für Knöpfe."
 }
}
