{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "stats-band",
  "title": "Stats Band",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/stats-band/stats-band.component.ts",
      "content": "// Interactive live telemetry and performance matrix band with multi-timeframe\n// switching, real-time SLA verification, regional cluster drilldown, and JSON export.\n// Port of the Vue block 1:1.\nimport { ChangeDetectionStrategy, Component, computed, Input, signal } from '@angular/core'\nimport { Check, Clock, Copy, Globe, LucideAngularModule, ShieldCheck, TrendingUp, Users, Zap } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\n\nexport type StatsTimeframe = 'realtime' | '24h' | '7d' | '30d'\nexport type StatsVariant = 'plain' | 'bordered'\n\ninterface TimeframeValue {\n  main: string\n  change: string\n  isPositive: boolean\n  note: string\n}\n\ninterface MetricData {\n  id: string\n  label: string\n  subtitle: string\n  values: Record<StatsTimeframe, TimeframeValue>\n  icon: unknown\n  breakdown: { region: string; val: string; status: string }[]\n}\n\nconst stats: MetricData[] = [\n  {\n    id: 'uptime',\n    label: 'Platform Availability',\n    subtitle: 'Multi-region Active-Active SLA',\n    icon: ShieldCheck,\n    values: {\n      realtime: { main: '100.00%', change: '0 incident in 90d', isPositive: true, note: 'Zero degradation' },\n      '24h': { main: '99.95%', change: '+0.001%', isPositive: true, note: '100% healthy' },\n      '7d': { main: '99.995%', change: '+0.005%', isPositive: true, note: 'Target > 99.99%' },\n      '30d': { main: '99.988%', change: '+0.02%', isPositive: true, note: 'Statutory SLA met' },\n    },\n    breakdown: [\n      { region: 'us-east-1 (N. Virginia)', val: '100.0%', status: 'Operational' },\n      { region: 'eu-west-1 (Frankfurt)', val: '100.0%', status: 'Operational' },\n      { region: 'ap-southeast-1 (Singapore)', val: '100.0%', status: 'Operational' },\n      { region: 'sa-east-1 (São Paulo)', val: '99.99%', status: 'Operational' },\n    ],\n  },\n  {\n    id: 'throughput',\n    label: 'Component Installs & Pulls',\n    subtitle: 'Daily registry resolutions',\n    icon: Zap,\n    values: {\n      realtime: { main: '1.42M', change: '+34.2k / hr', isPositive: true, note: 'Peak throughput' },\n      '24h': { main: '3.89M', change: '+22.4% vs prev', isPositive: true, note: '320k unique repos' },\n      '7d': { main: '26.4M', change: '+18.8%', isPositive: true, note: '1.4k new teams' },\n      '30d': { main: '104.2M', change: '+41.0%', isPositive: true, note: 'Global scale' },\n    },\n    breakdown: [\n      { region: 'Vue 3.5 / Nuxt 4 Core', val: '58.2%', status: 'Dominant' },\n      { region: 'React 19 / Next.js Mirror', val: '41.8%', status: 'Growing' },\n      { region: 'Direct CLI Installations', val: '88.4%', status: 'Automated' },\n      { region: 'Manual Source Downloads', val: '11.6%', status: 'Direct' },\n    ],\n  },\n  {\n    id: 'latency',\n    label: 'Global Edge P99 Latency',\n    subtitle: 'Cloudflare Workers cache hits',\n    icon: Clock,\n    values: {\n      realtime: { main: '12ms', change: '-4ms reduction', isPositive: true, note: 'Global median: 8ms' },\n      '24h': { main: '14ms', change: '-2ms vs baseline', isPositive: true, note: '99.9% cache hit' },\n      '7d': { main: '16ms', change: '-12ms optimization', isPositive: true, note: 'Zero edge cold-starts' },\n      '30d': { main: '18ms', change: '-24ms', isPositive: true, note: 'V4 pipeline rollout' },\n    },\n    breakdown: [\n      { region: 'North America (Edge)', val: '9ms', status: 'Fastest' },\n      { region: 'Europe (Edge)', val: '11ms', status: 'Optimal' },\n      { region: 'Asia-Pacific (Edge)', val: '14ms', status: 'Optimal' },\n      { region: 'Latin America (Edge)', val: '18ms', status: 'Optimal' },\n    ],\n  },\n  {\n    id: 'satisfaction',\n    label: 'Enterprise Developer NPS',\n    subtitle: 'Surveyed across 450+ companies',\n    icon: Users,\n    values: {\n      realtime: { main: '+78', change: 'Top 1% dev tools', isPositive: true, note: 'Verified feedback' },\n      '24h': { main: '4.94 / 5', change: '99.2% positive', isPositive: true, note: 'From 1,240 ratings' },\n      '7d': { main: '+76', change: '+4 pts vs qtr', isPositive: true, note: '98% retention' },\n      '30d': { main: '+74', change: '+12 pts YoY', isPositive: true, note: 'Industry benchmark' },\n    },\n    breakdown: [\n      { region: 'Code Quality & Typing', val: '99.6%', status: '5 Stars' },\n      { region: 'Zero-Lockin Ownership', val: '98.8%', status: '5 Stars' },\n      { region: 'Visual Design Aesthetics', val: '99.2%', status: '5 Stars' },\n      { region: 'Documentation & Demos', val: '97.4%', status: '4.9 Stars' },\n    ],\n  },\n]\n\nconst timeframeOptions: { id: StatsTimeframe; label: string }[] = [\n  { id: 'realtime', label: 'Live P99' },\n  { id: '24h', label: '24H' },\n  { id: '7d', label: '7D' },\n  { id: '30d', label: '30D' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-stats-band, [ui-stats-band]',\n  standalone: true,\n  // Vue renders the root <section> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [LucideAngularModule, UiBadgeComponent, UiButtonComponent],\n  template: `\n    <section data-slot=\"stats-band\" [class]=\"rootClass\">\n      <!-- Top Telemetry Header Bar -->\n      <div\n        class=\"border-border bg-muted/20 flex flex-col justify-between gap-4 border-b px-6 py-4 sm:flex-row sm:items-center\"\n      >\n        <div class=\"flex items-center gap-2.5\">\n          <div class=\"bg-success flex size-2.5 rounded-full\"></div>\n          <span class=\"text-foreground font-mono text-xs font-semibold tracking-wider uppercase\">\n            Real-time Telemetry & Performance Matrix\n          </span>\n          <span\n            ui-badge\n            variant=\"outline\"\n            class=\"border-success/20 bg-success/10 text-success hidden font-mono text-xs sm:inline-flex\"\n          >\n            All Systems Operational\n          </span>\n        </div>\n\n        <div class=\"flex items-center gap-2 self-end sm:self-auto\">\n          <!-- Timeframe Selectors -->\n          <div class=\"bg-background border-border flex items-center rounded-lg border p-0.5\">\n            @for (tf of timeframeOptions; track tf.id) {\n              <button\n                type=\"button\"\n                [class]=\"timeframeButtonClass(tf.id)\"\n                (click)=\"selectedTimeframe.set(tf.id)\"\n              >\n                {{ tf.label }}\n              </button>\n            }\n          </div>\n\n          <button\n            ui-button\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"h-7 gap-1.5 px-2 font-mono text-xs\"\n            (click)=\"copyStatsPayload()\"\n          >\n            @if (copied()) {\n              <lucide-icon [img]=\"Check\" class=\"text-success size-3\" />\n            } @else {\n              <lucide-icon [img]=\"Copy\" class=\"size-3\" />\n            }\n            <span>{{ copied() ? 'Copied' : 'JSON' }}</span>\n          </button>\n        </div>\n      </div>\n\n      <!-- 4-Column KPI Metric Cards -->\n      <div class=\"divide-border grid grid-cols-1 divide-y sm:grid-cols-2 sm:divide-x sm:divide-y-0 lg:grid-cols-4\">\n        @for (item of allStats; track item.id; let idx = $index) {\n          <div\n            [class]=\"statTileClass(idx)\"\n            (click)=\"toggleStat(idx)\"\n            (keydown.enter)=\"toggleStat(idx)\"\n            tabindex=\"0\"\n            role=\"button\"\n            [attr.aria-expanded]=\"activeStatIndex() === idx\"\n            [attr.aria-label]=\"'Toggle breakdown for ' + item.label\"\n          >\n            <div class=\"flex items-start justify-between\">\n              <p class=\"text-muted-foreground font-mono text-xs tracking-wider uppercase\">{{ item.label }}</p>\n              <lucide-icon\n                [img]=\"item.icon\"\n                class=\"text-muted-foreground group-hover:text-primary size-4 transition-colors\"\n              />\n            </div>\n\n            <div class=\"mt-3 flex items-baseline gap-2\">\n              <span class=\"text-foreground font-mono text-3xl font-bold tracking-tight\">\n                {{ item.values[selectedTimeframe()].main }}\n              </span>\n            </div>\n\n            <p class=\"text-muted-foreground mt-1 line-clamp-1 text-xs\">\n              {{ item.subtitle }}\n            </p>\n\n            <div class=\"border-border/60 mt-4 flex items-center justify-between border-t pt-3\">\n              <span class=\"text-success inline-flex items-center gap-1 font-mono text-xs font-medium\">\n                <lucide-icon [img]=\"TrendingUp\" class=\"size-3\" />\n                {{ item.values[selectedTimeframe()].change }}\n              </span>\n              <span class=\"text-muted-foreground font-mono text-xs\">\n                {{ item.values[selectedTimeframe()].note }}\n              </span>\n            </div>\n          </div>\n        }\n      </div>\n\n      <!-- Telemetry Regional Drilldown Drawer when a card is selected -->\n      @if (activeStat(); as active) {\n        <div class=\"bg-muted/20 border-border space-y-4 border-t p-6\">\n          <div class=\"flex items-center justify-between\">\n            <div class=\"flex items-center gap-2\">\n              <lucide-icon [img]=\"Globe\" class=\"text-primary size-4\" />\n              <span class=\"text-foreground text-xs font-semibold\">\n                Regional Telemetry & Infrastructure Breakdown: {{ active.label }}\n              </span>\n            </div>\n            <button ui-button variant=\"ghost\" size=\"sm\" class=\"h-6 text-xs\" (click)=\"activeStatIndex.set(null)\">\n              Close Breakdown\n            </button>\n          </div>\n\n          <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n            @for (sub of active.breakdown; track sub.region) {\n              <div\n                class=\"border-border bg-background flex items-center justify-between rounded-lg border p-3 shadow-xs\"\n              >\n                <div>\n                  <p class=\"text-foreground text-xs font-medium\">{{ sub.region }}</p>\n                  <p class=\"text-muted-foreground mt-0.5 font-mono text-xs\">{{ sub.status }}</p>\n                </div>\n                <span class=\"text-success font-mono text-xs font-bold\">{{ sub.val }}</span>\n              </div>\n            }\n          </div>\n        </div>\n      }\n    </section>\n  `,\n})\nexport class UiStatsBandComponent {\n  protected readonly Check = Check\n  protected readonly Copy = Copy\n  protected readonly Globe = Globe\n  protected readonly TrendingUp = TrendingUp\n  protected readonly timeframeOptions = timeframeOptions\n  protected readonly allStats = stats\n\n  @Input() variant: StatsVariant = 'bordered'\n  @Input('class') className?: string\n\n  readonly selectedTimeframe = signal<StatsTimeframe>('realtime')\n  readonly activeStatIndex = signal<number | null>(null)\n  readonly copied = signal(false)\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n\n  readonly activeStat = computed(() => {\n    const idx = this.activeStatIndex()\n    return idx == null ? null : (stats[idx] ?? null)\n  })\n\n  get rootClass(): string {\n    return cn(\n      'bg-card relative w-full overflow-hidden',\n      this.variant === 'bordered' ? 'border-border rounded-2xl border shadow-xs' : '',\n      this.className,\n    )\n  }\n\n  timeframeButtonClass(id: StatsTimeframe): string {\n    return cn(\n      'focus-visible:ring-ring rounded px-2.5 py-1 font-mono text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none',\n      this.selectedTimeframe() === id\n        ? 'bg-primary text-primary-foreground font-semibold shadow-xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  statTileClass(idx: number): string {\n    return cn(\n      'hover:bg-muted/30 focus-visible:ring-ring group relative cursor-pointer p-6 transition-colors focus-visible:ring-2 focus-visible:ring-inset focus-visible:outline-none',\n      this.activeStatIndex() === idx ? 'bg-muted/40 ring-primary/30 ring-1 ring-inset' : '',\n    )\n  }\n\n  toggleStat(idx: number): void {\n    this.activeStatIndex.set(this.activeStatIndex() === idx ? null : idx)\n  }\n\n  async copyStatsPayload(): Promise<void> {\n    try {\n      await navigator.clipboard.writeText(JSON.stringify(stats, null, 2))\n      this.copied.set(true)\n      clearTimeout(this.copyTimer)\n      this.copyTimer = setTimeout(() => this.copied.set(false), 2000)\n    } catch {\n      // Clipboard unavailable\n    }\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stats-band/stats-band.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/stats-band/index.ts",
      "content": "export { UiStatsBandComponent, type StatsTimeframe, type StatsVariant } from './stats-band.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/stats-band/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json"
  ],
  "description": "Interactive live telemetry and performance matrix band with multi-timeframe switching, real-time SLA verification, regional cluster drilldown, and JSON export.",
  "categories": [
    "marketing"
  ]
}