{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "hero-split-device-mockup",
  "title": "Hero Split Device Mockup",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/hero-split-device-mockup/hero-split-device-mockup.component.ts",
      "content": "// Dual viewport device mockup hero with interactive viewport controls (desktop /\n// tablet / mobile), dark-frame toggle, inner app tabs, KPI grid and a telemetry\n// sparkline. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport { ArrowRight, LucideAngularModule, Monitor, Moon, Smartphone, Sun, Tablet } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent, UiCardContentComponent } from '@/ui/card/card.component'\n\nexport type HeroSplitDeviceMode = 'desktop' | 'tablet' | 'mobile'\nexport type HeroSplitDeviceTab = 'overview' | 'analytics' | 'activity'\n\ninterface HeroSplitKpi {\n  label: string\n  value: string\n  change: string\n  status: string\n}\n\nconst mockKpis: HeroSplitKpi[] = [\n  { label: 'Active Sessions', value: '24,892', change: '+14.2%', status: 'up' },\n  { label: 'Conversion Rate', value: '4.82%', change: '+0.6%', status: 'up' },\n  { label: 'Avg TTFB', value: '18ms', change: '-4ms', status: 'optimal' },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-hero-split-device-mockup, [ui-hero-split-device-mockup]',\n  standalone: true,\n  // React 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, UiCardComponent, UiCardContentComponent],\n  template: `\n    <section data-slot=\"hero-split-device-mockup\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n        <!-- Top Title & Badge Area -->\n        <div class=\"mx-auto max-w-3xl space-y-4 text-center\">\n          <a\n            href=\"#device-preview\"\n            class=\"group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors\"\n          >\n            <lucide-icon [img]=\"Smartphone\" class=\"text-primary size-3.5\" />\n            <span>Fluid Container Queries &bull; Tailwind v4 Ready</span>\n            <lucide-icon\n              [img]=\"ArrowRight\"\n              class=\"text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5\"\n            />\n          </a>\n\n          <h1 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl\">\n            {{ title }}\n          </h1>\n\n          <p class=\"text-muted-foreground text-base sm:text-lg\">\n            {{ description }}\n          </p>\n\n          <!-- Viewport Controls & Interactive Triggers -->\n          <div class=\"flex flex-wrap items-center justify-center gap-2 pt-2\">\n            <div class=\"border-border bg-muted/50 inline-flex rounded-lg border p-1 shadow-2xs\">\n              <button type=\"button\" [class]=\"modeClass('desktop')\" (click)=\"activeMode.set('desktop')\">\n                <lucide-icon [img]=\"Monitor\" class=\"size-3.5\" />\n                <span>Desktop (1440px)</span>\n              </button>\n              <button type=\"button\" [class]=\"modeClass('tablet')\" (click)=\"activeMode.set('tablet')\">\n                <lucide-icon [img]=\"Tablet\" class=\"size-3.5\" />\n                <span>Tablet (768px)</span>\n              </button>\n              <button type=\"button\" [class]=\"modeClass('mobile')\" (click)=\"activeMode.set('mobile')\">\n                <lucide-icon [img]=\"Smartphone\" class=\"size-3.5\" />\n                <span>Mobile (375px)</span>\n              </button>\n            </div>\n\n            <button\n              ui-button\n              variant=\"outline\"\n              size=\"sm\"\n              class=\"border-border gap-1.5 text-xs\"\n              (click)=\"toggleDarkMode()\"\n            >\n              @if (isDarkMode()) {\n                <lucide-icon [img]=\"Sun\" class=\"size-3.5\" />\n              } @else {\n                <lucide-icon [img]=\"Moon\" class=\"size-3.5\" />\n              }\n              <span>{{ isDarkMode() ? 'Dark Frame' : 'Light Frame' }}</span>\n            </button>\n          </div>\n        </div>\n\n        <!-- Split Device Mockup Canvas -->\n        <div class=\"mt-12 flex justify-center\">\n          <div [class]=\"frameClass\">\n            <!-- Browser / Device Chrome Header -->\n            <div class=\"border-border/80 flex items-center justify-between border-b px-2 pt-1 pb-2.5\">\n              <div class=\"flex items-center gap-1.5\">\n                <span class=\"bg-destructive/80 size-2.5 rounded-full\"></span>\n                <span class=\"bg-warning/80 size-2.5 rounded-full\"></span>\n                <span class=\"bg-success/80 size-2.5 rounded-full\"></span>\n              </div>\n\n              <!-- URL Bar -->\n              <div\n                class=\"border-border/60 bg-muted/60 text-muted-foreground mx-auto flex h-6 w-1/2 items-center justify-center truncate rounded-md border px-2 font-mono text-xs\"\n              >\n                https://uipkge.dev/demo/dashboard-kpis\n              </div>\n\n              <div class=\"text-muted-foreground flex items-center gap-1\">\n                <span class=\"bg-success size-2 rounded-full\"></span>\n                <span class=\"font-mono text-xs\">LIVE</span>\n              </div>\n            </div>\n\n            <!-- Inside Interactive Device Application -->\n            <div class=\"bg-background space-y-4 rounded-lg p-4 pt-4\">\n              <!-- App Header Inside Frame -->\n              <div class=\"border-border flex items-center justify-between border-b pb-3\">\n                <div class=\"flex items-center gap-2\">\n                  <div\n                    class=\"bg-primary text-primary-foreground flex size-7 items-center justify-center rounded-md text-xs font-bold\"\n                  >\n                    UI\n                  </div>\n                  <div>\n                    <div class=\"text-foreground text-xs font-semibold\">Platform Metrics</div>\n                    <div class=\"text-muted-foreground text-xs\">Production Cluster (us-east-1)</div>\n                  </div>\n                </div>\n\n                <!-- Inner App Tabs -->\n                <div class=\"border-border bg-muted/40 flex gap-1 rounded-md border p-0.5\">\n                  <button type=\"button\" [class]=\"tabClass('overview')\" (click)=\"activeTab.set('overview')\">\n                    Overview\n                  </button>\n                  <button type=\"button\" [class]=\"tabClass('analytics')\" (click)=\"activeTab.set('analytics')\">\n                    Analytics\n                  </button>\n                </div>\n              </div>\n\n              <!-- KPI Metric Grid in Frame -->\n              <div [class]=\"kpiGridClass\">\n                @for (kpi of kpis; track kpi.label) {\n                  <div ui-card class=\"border-border bg-card/60 shadow-2xs\">\n                    <div ui-card-content class=\"space-y-1 p-3\">\n                      <div class=\"text-muted-foreground text-xs font-medium\">{{ kpi.label }}</div>\n                      <div class=\"text-foreground text-lg font-bold tracking-tight\">{{ kpi.value }}</div>\n                      <div class=\"text-success flex items-center gap-1 text-xs font-medium\">\n                        <span>{{ kpi.change }}</span>\n                        <span class=\"text-muted-foreground\">&bull; vs last week</span>\n                      </div>\n                    </div>\n                  </div>\n                }\n              </div>\n\n              <!-- Interactive Wave / Chart Preview -->\n              <div class=\"border-border/80 bg-muted/20 space-y-2 rounded-lg border p-3\">\n                <div class=\"flex items-center justify-between text-xs\">\n                  <span class=\"text-foreground font-medium\">Real-time Telemetry Stream</span>\n                  <span ui-badge variant=\"outline\" class=\"border-border text-success font-mono text-xs\">\n                    Synced: 0.2ms\n                  </span>\n                </div>\n\n                <!-- SVG Mock Sparkline Chart -->\n                <svg\n                  class=\"stroke-primary fill-primary/10 h-16 w-full\"\n                  viewBox=\"0 0 300 60\"\n                  preserveAspectRatio=\"none\"\n                  aria-hidden=\"true\"\n                >\n                  <path d=\"M0 45 Q 25 20, 50 35 T 100 25 T 150 15 T 200 30 T 250 10 T 300 20 L 300 60 L 0 60 Z\" />\n                  <path\n                    d=\"M0 45 Q 25 20, 50 35 T 100 25 T 150 15 T 200 30 T 250 10 T 300 20\"\n                    fill=\"none\"\n                    stroke-width=\"2\"\n                  />\n                </svg>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiHeroSplitDeviceMockupComponent {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Monitor = Monitor\n  protected readonly Moon = Moon\n  protected readonly Smartphone = Smartphone\n  protected readonly Sun = Sun\n  protected readonly Tablet = Tablet\n\n  protected readonly kpis = mockKpis\n\n  @Input() title = 'Responsive components with identical fidelity on every device.'\n  @Input() description =\n    'Every primitive and block is engineered with fluid container queries and zero layout shift across desktop, tablet, and mobile displays.'\n  @Input('class') className?: string\n\n  readonly activeMode = signal<HeroSplitDeviceMode>('desktop')\n  readonly isDarkMode = signal(true)\n  readonly activeTab = signal<HeroSplitDeviceTab>('overview')\n\n  readonly viewportWidthClass = computed(() => {\n    const mode = this.activeMode()\n    if (mode === 'desktop') return 'w-full max-w-2xl'\n    if (mode === 'tablet') return 'w-full max-w-md'\n    return 'w-full max-w-[320px]'\n  })\n\n  get rootClass(): string {\n    return cn('bg-background relative overflow-hidden py-16 sm:py-24 lg:py-28', this.className)\n  }\n\n  get frameClass(): string {\n    return cn(\n      'border-border bg-card rounded-xl border p-2 shadow-md transition-colors duration-300 ease-out sm:p-3',\n      this.viewportWidthClass(),\n      this.isDarkMode() ? 'dark' : '',\n    )\n  }\n\n  get kpiGridClass(): string {\n    return cn('grid gap-2.5', this.activeMode() === 'mobile' ? 'grid-cols-1' : 'grid-cols-3')\n  }\n\n  modeClass(mode: HeroSplitDeviceMode): string {\n    return cn(\n      'flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none',\n      this.activeMode() === mode\n        ? 'bg-background text-foreground shadow-2xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  tabClass(tab: HeroSplitDeviceTab): string {\n    return cn(\n      'rounded px-2 py-0.5 text-xs font-medium transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none',\n      this.activeTab() === tab\n        ? 'bg-background text-foreground shadow-2xs'\n        : 'text-muted-foreground hover:text-foreground',\n    )\n  }\n\n  toggleDarkMode(): void {\n    this.isDarkMode.update((v) => !v)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/hero-split-device-mockup/hero-split-device-mockup.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/hero-split-device-mockup/index.ts",
      "content": "export {\n  UiHeroSplitDeviceMockupComponent,\n  type HeroSplitDeviceMode,\n  type HeroSplitDeviceTab,\n} from './hero-split-device-mockup.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/hero-split-device-mockup/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json"
  ],
  "description": "Dual viewport device mockup hero with interactive viewport controls and real-time state synchronization.",
  "categories": [
    "hero",
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "hero"
}