{
  "schemaVersion": 1,
  "id": "number-reveal",
  "version": "1.1.0",
  "status": "published",
  "kind": "example",
  "title": "Minimal Animated Number Reveal",
  "summary": "A big number rolls up over a soft glowing background, pops when it lands, and a label springs in.",
  "description": "A clean milestone reveal: an odometer counts up to your number over a slowly drifting gradient, gives a satisfying little pop as it lands, then a label bounces into place underneath. Set the number, the $ or + around it, the label and the three background colours. Plain browser JavaScript (Canvas 2D) — no frameworks.",
  "role": "Complete example scene.",
  "collections": [
    "kinetic-text",
    "product-reveals",
    "backgrounds"
  ],
  "tags": [
    "number",
    "counter",
    "stat",
    "milestone",
    "reveal",
    "gradient",
    "minimal",
    "text",
    "2d",
    "canvas",
    "example"
  ],
  "synonyms": [
    "number reveal",
    "stat animation",
    "milestone video",
    "revenue reveal",
    "user count",
    "big number animation"
  ],
  "useCases": [
    "Milestone posts (10k users, $1M raised)",
    "Stats in a pitch or launch video",
    "Year-in-review numbers"
  ],
  "featured": 0,
  "publishedAt": "2026-10-03",
  "uses": [
    {
      "id": "gradient-background",
      "version": "1.0.0",
      "role": "Background layer."
    },
    {
      "id": "rolling-counter",
      "version": "1.1.0",
      "role": "The counting number."
    },
    {
      "id": "spring-motion",
      "version": "1.0.0",
      "role": "Spring pop on the number and label."
    }
  ],
  "implementation": {
    "target": "canvas2d",
    "runtime": "browser",
    "language": "javascript",
    "module": "esm",
    "entry": "demo.js",
    "exports": [
      {
        "name": "createDemo",
        "signature": "createDemo({ canvas, width, height, params, fps, duration }) => { renderFrame(info), dispose() }",
        "description": "Draws the layers each frame."
      }
    ],
    "reusable": [],
    "demo": "demo.js",
    "harness": "index.html"
  },
  "dependencies": [
    {
      "id": "gradient-background",
      "version": "1.0.0",
      "reason": "Background."
    },
    {
      "id": "rolling-counter",
      "version": "1.1.0",
      "reason": "Counter."
    },
    {
      "id": "spring-motion",
      "version": "1.0.0",
      "reason": "Springs."
    },
    {
      "id": "apw-runtime",
      "version": "1.0.0",
      "reason": "Harness and export tools."
    }
  ],
  "params": [
    {
      "key": "to",
      "label": "Number",
      "type": "integer",
      "min": 1,
      "max": 999999999,
      "step": 1,
      "default": 100000
    },
    {
      "key": "prefix",
      "label": "Before the number",
      "type": "text",
      "default": "",
      "maxLength": 6,
      "sensitive": true
    },
    {
      "key": "suffix",
      "label": "After the number",
      "type": "text",
      "default": "+",
      "maxLength": 12,
      "sensitive": true
    },
    {
      "key": "label",
      "label": "Label",
      "type": "text",
      "default": "creators joined",
      "maxLength": 40,
      "sensitive": true
    },
    {
      "key": "countSeconds",
      "label": "Counting time (s)",
      "type": "number",
      "min": 1,
      "max": 6,
      "step": 0.1,
      "default": 2.6
    },
    {
      "key": "colorA",
      "label": "Glow 1",
      "type": "color",
      "default": "#7c6cff"
    },
    {
      "key": "colorB",
      "label": "Glow 2",
      "type": "color",
      "default": "#ff6fb5"
    },
    {
      "key": "colorC",
      "label": "Glow 3",
      "type": "color",
      "default": "#38d6ff"
    },
    {
      "key": "base",
      "label": "Base colour",
      "type": "color",
      "default": "#0b0912"
    }
  ],
  "presets": [
    {
      "id": "default",
      "label": "Community milestone",
      "params": {}
    },
    {
      "id": "revenue",
      "label": "Revenue",
      "params": {
        "to": 1000000,
        "prefix": "$",
        "suffix": "",
        "label": "raised this year",
        "colorA": "#5ee6c3",
        "colorB": "#3b82f6",
        "colorC": "#a7f3d0",
        "base": "#06110f"
      }
    },
    {
      "id": "warm",
      "label": "Warm",
      "params": {
        "to": 365,
        "suffix": "",
        "label": "days of shipping",
        "colorA": "#ff8a3d",
        "colorB": "#ffcf73",
        "colorC": "#ff4d6d",
        "base": "#170a08"
      }
    }
  ],
  "output": {
    "width": 1080,
    "height": 1080,
    "fps": 30,
    "durationSeconds": 5,
    "posterSeconds": 4.5,
    "alpha": false,
    "motion": "procedural",
    "loop": {
      "seamless": false,
      "method": "Counts once and holds."
    },
    "seed": null
  },
  "composition": {
    "inputs": "Parameters only.",
    "outputs": "A Canvas 2D frame.",
    "coordinates": "Pixels.",
    "lighting": "None.",
    "timing": "Pure function of time.",
    "compatibleWith": [],
    "notes": [
      "Works without React, Remotion or a bundler."
    ]
  },
  "reuse": [
    "Swap the background for Hypnotic Particle Tunnel for a louder version.",
    "Place three counters side by side for a stats slide.",
    "Use the spring pop on any element that should land with emphasis."
  ],
  "integration": {
    "newProject": "Download the pack, npm install, npm run serve and open number-reveal/1.0.0/index.html. Export with npm run render -- number-reveal/1.0.0 --param to=25000.",
    "existingProject": "Copy the three ingredient files and reproduce the layering from demo.js in your own canvas loop."
  },
  "performance": {
    "notes": "Light.",
    "limits": "None notable."
  },
  "limitations": [
    "Whole numbers only."
  ],
  "license": {
    "spdx": "MIT",
    "notice": "Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.",
    "thirdParty": []
  },
  "provenance": "Original code written for AI Pixel Wizard in October 2026. Demo and typography rebuilt in October 2026 to the catalog quality bar (docs/QUALITY.md).",
  "changelog": [
    {
      "version": "1.1.0",
      "date": "2026-10-03",
      "notes": "Typography and layout rebuilt: the label sits above the number as a small line, the number is set flush-left and large on a shared margin, the glow is restrained to one corner with grain. Uses rolling-counter 1.1.0 (align)."
    },
    {
      "version": "1.0.0",
      "date": "2026-10-02",
      "notes": "Initial release."
    }
  ]
}
