{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "prozent-zaehler",
 "name": "Prozent-Zähler-Preloader (0 bis 100)",
 "name_en": "Percentage counter preloader",
 "kurz": "Riesige Prozentziffern zählen bis 100, rollen, wandern oder messen echt, und gleiten dann aus der Maske, bevor der Loader wegwischt.",
 "kategorie": "Preloader & Intro",
 "kategorie_slug": "preloader-intro",
 "kategorie_nr": 2,
 "bau_chat": "C3",
 "prioritaet": "B",
 "trendstatus": "abklingend",
 "belegstatus": "belegt",
 "website_belege": 3,
 "stimmung": [
  "editorial",
  "präzise",
  "experimentell"
 ],
 "stimmung_roh": [
  "technisch",
  "typografisch",
  "klassisch-award"
 ],
 "technik": [
  "gsap",
  "css",
  "vanilla-js",
  "three"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "gsap",
  "webgl"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Große Ziffern zählen von 0 bis 100, meist in einer Display-Schrift mit fester Ziffernbreite. Oft springen sie in unregelmäßigen Schritten (1–10, 20, 23, 30, 50 …), damit es echt wirkt. Dabei wandert der Zähler mit dem Fortschritt über den Bildschirm, füllt eine Linie oder rollt wie ein Kilometerzähler. Bei 100 gleiten die Ziffern aus ihrer Maske nach oben, dann wischt oder blendet der Loader weg.",
  "warum_es_wirkt": "Der Fortschritt ist sofort lesbar, und die Zahl wird selbst zum typografischen Bild. Die Wartezeit bekommt einen Takt und ein klares Ende. Ein Award-Klassiker der 2020er.",
  "wann_einsetzen": "Wenn es echten Ladebedarf gibt (WebGL, Video, große Kampagnenbilder) und der Fortschritt wirklich gemessen wird. Passt zu Marken, die Typografie in den Vordergrund stellen.",
  "wann_nicht": "Als reine Deko auf schnellen Seiten. Ein Fake-Zähler kostet Zeit, verschlechtert den LCP und gilt 2026 als Klischee. Gabriel Contassot nennt seinen Zähler in der eigenen Case Study dekorativ, weil es wenig zu laden gibt.",
  "varianten": [
   "Wandern: Der Zähler schiebt sich per translateX mit dem Fortschritt über den Bildschirm (Contassot).",
   "Rollen: Jede Stelle ist eine senkrechte Ziffernspalte und rollt per translateY (Odometer, Lusion).",
   "Feste Stufen: Der Wert springt mit steps(14) in 3 s auf 100 (Joffrey Spitzer).",
   "Gemessen: echter Fortschritt aus geladenen Dateien oder aus THREE.LoadingManager.onProgress.",
   "Zähler plus Bild-Flicker.",
   "Zähler, der zur Seitenzahl wird (siehe loader-wird-layout)."
  ],
  "umsetzung": "Echter Fortschritt: Assets per Promise laden und den Anteil erledigter Promises zählen, oder THREE.LoadingManager(onLoad, onProgress(url, loaded, total)) nutzen. Den Anzeigewert glätten, damit er nicht springt: gsap.to(obj, { val: ziel, duration: 0.4, ease: 'power2.out', onUpdate }). Gegen Zittern braucht jede Stelle eine feste Breite: font-variant-numeric: tabular-nums oder, wenn die Tabellenziffern der Schrift anders aussehen, eine Box je Stelle. Mindest- und Höchstdauer setzen (z. B. min 1000 ms, max 3000 ms, dann trotzdem weiter). Fallstrick: Der Fortschritt bleibt oft bei 99 % stehen, weil Schriften fehlen oder Bilder noch nicht decodiert sind. Deshalb auf document.fonts.ready und img.decode() warten. Abgang wie bei Joffrey Spitzer: Label und Zahl yPercent -105 in 1 s power2.out, 150 ms versetzt.",
  "mobil": "Ziffern kleiner. Den wandernden Zähler am Rand begrenzen: Contassot deckelt die Translation auf Mobilgeräten bei 95 %.",
  "reduzierte_bewegung": "Statischer Prozentwert oder Balken. Nichts rollt, nichts wandert. Den Loader am Ende kurz ausblenden statt wegwischen.",
  "barrierefreiheit": "role=\"progressbar\" mit aria-valuenow, oder eine Live Region mit wenigen Ansagen (25, 50, 75, 100). Nicht jedes Prozent ansagen. aria-busy am main, bis der Loader weg ist. Die großen Ziffern selbst aria-hidden setzen."
 },
 "messwerte": {
  "easing": "steps(14) (Joffrey); expoInOut je Ziffer (Lusion)",
  "dauer_ms": "Zählen 3000, Abgang 1000",
  "stagger_ms": "Abgang 150",
  "distanz": "Abgang yPercent -105",
  "sonstiges": "Ziffern als Rollspalten (Lusion) statt Textwechsel",
  "herkunft": "beobachtet",
  "quelle": "https://joffreyspitzer.com/_astro/layout.astro_astro_type_script_index_0_lang.QNTHFiVA.js"
 },
 "kurve": {
  "bezier": [
   0.87,
   0,
   0.13,
   1
  ],
  "css": "cubic-bezier(0.87, 0, 0.13, 1)",
  "name": "expo.inOut",
  "dauer_ms": 3000
 },
 "gesehen_bei": [
  {
   "seite": "Gabriel Contassot Portfolio 2024",
   "url": "https://tympanus.net/codrops/2024/04/24/case-study-gabriel-contassots-portfolio-2024/",
   "auszeichnung": "",
   "beobachtung": "Dekorativer Zähler, der sich per transformX über den Screen bewegt. Folge 1–10, 20, 23, 30, 50, 70, 80, 100 (17 Schritte) in 2,8 s, etwa 165 ms je Schritt. Auf Mobile bei 95% Translation gedeckelt. Danach GSAP autoAlpha 0 über 0,8 s plus 800 ms Timeout.",
   "art": "artikel"
  },
  {
   "seite": "Joffrey Spitzer Portfolio",
   "url": "https://joffreyspitzer.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft: HTML .preloader__progress__title \"Loading\" + .preloader__progress__percentage \"0\"; JS zählt 0 → 100 in 3s mit ease steps(14) und schiebt beides danach yPercent -105 weg (1s power2.out, Stagger .15).",
   "art": "website"
  },
  {
   "seite": "Lusion",
   "url": "https://lusion.co/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft: HTML #preloader > #preloader-percent-digits mit rollenden Ziffernspalten (.preloader-percent-digit-num); hoisted.CUO_IjfL.js verschiebt jede Ziffer per translateY mit ease.expoInOut.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "OFF+BRAND",
   "url": "https://www.itsoffbrand.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft (ob.2026.index.23.js): Preloader schreibt Math.round(progress()×100) als Text, über gsap.ticker aktualisiert.",
   "art": "website",
   "browser_gemessen": true
  }
 ],
 "tutorials": [
  {
   "titel": "Case Study: Gabriel Contassot's Portfolio — 2024 (Codrops)",
   "url": "https://tympanus.net/codrops/2024/04/24/case-study-gabriel-contassots-portfolio-2024/"
  }
 ],
 "kombinierbar_mit": [
  "loader-wird-layout",
  "bildstapel-intro",
  "webgl-ladeszene-fortschritt"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/preloader-intro/prozent-zaehler/",
  "meta": "https://cecodesign.de/lab/fundus/preloader-intro/prozent-zaehler/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/preloader-intro/prozent-zaehler/demo"
 },
 "herkunft": {
  "quelldateien": [
   "uebergaenge.json",
   "patch-belege-3.json"
  ],
  "pruefnotizen": [
   "patch-belege-3.json: Drei Produktionsbelege; Awwwards-Inspiration entfernt."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Riesige Prozentziffern zählen bis 100, rollen, wandern oder messen echt, und gleiten dann aus der Maske, bevor der Loader wegwischt.",
  "demo": true,
  "abhaengigkeiten": [
   "gsap@3.15.0"
  ],
  "werte": {
   "kurve_wisch": "expo.inOut = cubic-bezier(0.87, 0, 0.13, 1)",
   "wisch": "Loader yPercent 0 → -100, 1000 ms expo.inOut, Start 550 ms nach Abgangsbeginn",
   "abgang": "Label und Zahl yPercent 0 → -105, 1000 ms power2.out, Versatz 150 ms",
   "abgang_rest": "Kopf, Mitte, Fußzeile autoAlpha 0 in 300 ms linear; Fortschrittslinie scaleX → 0 (Ursprung rechts) 600 ms expo.inOut",
   "rollen": "0 → 100 in 3000 ms mit ease steps(14) (0, 7, 14, 21, 29 … 100); jede Stelle rollt 214 ms expo.inOut vorwärts (Band 2 × 0–9), führende Nullen 20 % Deckkraft",
   "wandern": "Folge 1–10, 20, 23, 30, 50, 70, 80, 100 (17 Schritte) je 165 ms; x = Fortschritt × (Spurbreite − Zählerbreite), 165 ms power2.out",
   "gemessen": "6 Dateien nacheinander (2 Schriften per document.fonts.load, 4 Bilder malen + img.decode); Anzeige gsap.to 400 ms power2.out; min 1000 ms, max 3000 ms",
   "pause_vor_abgang_ms": "350 nach 100 (Rollen, Gemessen), 450 nach dem letzten Schritt (Wandern)",
   "seite": "Hero-Text opacity 0 → 1, 1000 ms cubic-bezier(0.25, 1, 0.5, 1), Versatz 120 ms",
   "ziffern": "Zalando Sans wdth 125, wght 300, clamp(110px, 21vw, 300px), line-height 0.8; feste Stellenbreite = breiteste Ziffer (gemessen) statt tnum",
   "ui_ms": 150,
   "reduziert": "Wert in Vierteln, Loader opacity → 0 in 250 ms linear",
   "vorfuehrung": "Rollen → Wandern → Gemessen, 2400 ms auf der fertigen Seite"
  },
  "ausloeser": "laden",
  "touch": "Gleicher Ablauf wie am Desktop. Ziffern kleiner (min 110 px), Meta-Zeile oben ausgeblendet, Wirkstoff- bzw. Dateiliste unter dem Motto; Produktreihe als Scroll-Snap-Karussell.",
  "reduziert": "Loader bleibt, zählt aber echt gemessen in Vierteln (0, 25, 50, 75, 100). Nichts rollt oder wandert, kein Masken-Abgang, kein Wisch: der Loader blendet in 250 ms aus.",
  "korrekturen": {
   "beschreibung": "Große Ziffern zählen von 0 bis 100, meist in einer Display-Schrift mit fester Ziffernbreite. Oft springen sie in unregelmäßigen Schritten (1–10, 20, 23, 30, 50 …), damit es echt wirkt. Dabei wandert der Zähler mit dem Fortschritt über den Bildschirm, füllt eine Linie oder rollt wie ein Kilometerzähler. Bei 100 gleiten die Ziffern aus ihrer Maske nach oben, dann wischt oder blendet der Loader weg.",
   "warum_es_wirkt": "Der Fortschritt ist sofort lesbar, und die Zahl wird selbst zum typografischen Bild. Die Wartezeit bekommt einen Takt und ein klares Ende. Ein Award-Klassiker der 2020er.",
   "wann_einsetzen": "Wenn es echten Ladebedarf gibt (WebGL, Video, große Kampagnenbilder) und der Fortschritt wirklich gemessen wird. Passt zu Marken, die Typografie in den Vordergrund stellen.",
   "wann_nicht": "Als reine Deko auf schnellen Seiten. Ein Fake-Zähler kostet Zeit, verschlechtert den LCP und gilt 2026 als Klischee. Gabriel Contassot nennt seinen Zähler in der eigenen Case Study dekorativ, weil es wenig zu laden gibt.",
   "varianten": [
    "Wandern: Der Zähler schiebt sich per translateX mit dem Fortschritt über den Bildschirm (Contassot).",
    "Rollen: Jede Stelle ist eine senkrechte Ziffernspalte und rollt per translateY (Odometer, Lusion).",
    "Feste Stufen: Der Wert springt mit steps(14) in 3 s auf 100 (Joffrey Spitzer).",
    "Gemessen: echter Fortschritt aus geladenen Dateien oder aus THREE.LoadingManager.onProgress.",
    "Zähler plus Bild-Flicker.",
    "Zähler, der zur Seitenzahl wird (siehe loader-wird-layout)."
   ],
   "umsetzung": "Echter Fortschritt: Assets per Promise laden und den Anteil erledigter Promises zählen, oder THREE.LoadingManager(onLoad, onProgress(url, loaded, total)) nutzen. Den Anzeigewert glätten, damit er nicht springt: gsap.to(obj, { val: ziel, duration: 0.4, ease: 'power2.out', onUpdate }). Gegen Zittern braucht jede Stelle eine feste Breite: font-variant-numeric: tabular-nums oder, wenn die Tabellenziffern der Schrift anders aussehen, eine Box je Stelle. Mindest- und Höchstdauer setzen (z. B. min 1000 ms, max 3000 ms, dann trotzdem weiter). Fallstrick: Der Fortschritt bleibt oft bei 99 % stehen, weil Schriften fehlen oder Bilder noch nicht decodiert sind. Deshalb auf document.fonts.ready und img.decode() warten. Abgang wie bei Joffrey Spitzer: Label und Zahl yPercent -105 in 1 s power2.out, 150 ms versetzt.",
   "mobil": "Ziffern kleiner. Den wandernden Zähler am Rand begrenzen: Contassot deckelt die Translation auf Mobilgeräten bei 95 %.",
   "reduzierte_bewegung": "Statischer Prozentwert oder Balken. Nichts rollt, nichts wandert. Den Loader am Ende kurz ausblenden statt wegwischen.",
   "barrierefreiheit": "role=\"progressbar\" mit aria-valuenow, oder eine Live Region mit wenigen Ansagen (25, 50, 75, 100). Nicht jedes Prozent ansagen. aria-busy am main, bis der Loader weg ist. Die großen Ziffern selbst aria-hidden setzen."
  },
  "geprueft": "01.11.2026",
  "notiz": "Welt: Rezept mode-beauty-kollektion, erfundene Hautpflege-Marke Solgut aus Halle (Saale); Zalando Sans (wdth 125, nicht fett) + Fragment Mono, Off-White-Seite hinter einem fast schwarzen Loader, Kampagnenbild und Packshots auf Canvas gemalt. Drei Varianten per Umschalter: Rollen (Odometer, steps(14) + expo.inOut je Stelle), Wandern (Contassot-Folge, translateX) und Gemessen (zählt wirklich 6 Dateien: Schriften laden, Bilder malen und decodieren; die Demo malt die Bilder bei jedem Durchlauf neu, damit es etwas zu messen gibt). Rollen und Wandern sind als dekorativ gekennzeichnet. Besonderheit: Die Tabellenziffern von Zalando Sans haben eine Null mit Schrägstrich, deshalb feste Stellenbreite aus der breitesten Ziffer statt tnum (auch Preise ohne tnum). Abgang für alle Varianten nach Joffrey Spitzer, danach Wisch expo.inOut. AD-Review 01.11.2026: Note 5 (Loader reicht in der Vorschau und bei eingeklapptem Pult bis zum unteren Rand). Zugang 02.11.2026: --meta #8c857b → #736d64 (4,6:1, auch im Pult); Seite und Produktreihe inert, solange der Loader liegt (data-zustand ≠ fertig, per MutationObserver), damit der Fokus nicht unter dem Overlay und nicht auf unsichtbaren Held-Text springt; Kontrastmodus-Rahmen für Knöpfe. Offen: führende Nullen der Rollen-Zahl (Alpha .2, Absicht) zählt die Prüfung trotz aria-hidden; Wert steht im progressbar (aria-valuenow)."
 }
}
