{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "hero-developer-terminal",
  "title": "Hero Developer Terminal",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/hero-developer-terminal/hero-developer-terminal.component.ts",
      "content": "// Developer-first hero with a split value proposition and an interactive live CLI\n// terminal sandbox with preset command switching and copy controls.\n// Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, DestroyRef, Input, OnInit, computed, inject, signal } from '@angular/core'\nimport { ArrowRight, Check, Code2, Copy, LucideAngularModule, RotateCcw } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport { UiCardComponent } from '@/ui/card/card.component'\n\nexport interface DeveloperTerminalPreset {\n  id: string\n  label: string\n  command: string\n  output: string[]\n}\n\nconst presets: DeveloperTerminalPreset[] = [\n  {\n    id: 'init',\n    label: '1. Init Theme',\n    command: 'npx shadcn@latest add https://uipkge.dev/r/react/init.json',\n    output: [\n      '✔ Resolving registry dependencies...',\n      '✔ Downloaded packages/shared/styles/tailwind.css (OKLCH @theme inline)',\n      '✔ Configured cn() utility in src/lib/utils.ts',\n      '✔ Injected useTheme hook with system preference sync',\n      '✔ UIPKGE bootstrap complete in 124ms.',\n    ],\n  },\n  {\n    id: 'component',\n    label: '2. Add KPI Grid',\n    command: 'npx shadcn@latest add https://uipkge.dev/r/react/kpi-grid.json',\n    output: [\n      '✔ Fetched manifest for kpi-grid (registry:ui)',\n      '✔ Added components/ui/kpi-grid/KpiGrid.tsx',\n      '✔ Verified CVA variants in kpi-grid.variants.ts',\n      '✔ Installed transitive primitives: Card, Badge, Sparkline',\n      '✔ Zero npm bundle overhead added to node_modules.',\n    ],\n  },\n  {\n    id: 'verify',\n    label: '3. Parity Check',\n    command: 'npm run check:parity',\n    output: [\n      '✔ Checking 31 shared CVA variant definitions...',\n      '✔ Validating Vue 3.5 SFC and React 19 TSX type contracts...',\n      '✔ Token synchronization: styles/tailwind.css (100% match)',\n      '✔ PASS: Full cross-framework parity confirmed across all 300+ items.',\n    ],\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-hero-developer-terminal, [ui-hero-developer-terminal]',\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, UiButtonComponent, UiCardComponent],\n  template: `\n    <section data-slot=\"hero-developer-terminal\" [class]=\"rootClass\">\n      <div class=\"mx-auto grid max-w-7xl grid-cols-1 items-center gap-12 lg:grid-cols-12 lg:gap-8\">\n        <!-- Left Column: Value Proposition & CTAs (6 Cols) -->\n        <div class=\"space-y-6 text-left lg:col-span-6\">\n          <!-- Parity Badge -->\n          <div\n            class=\"border-border bg-muted/40 inline-flex items-center gap-2 rounded-full border px-3 py-1 font-mono text-xs shadow-xs\"\n          >\n            <span class=\"bg-success size-2 rounded-full\"></span>\n            <span class=\"text-foreground font-medium\">Dual-Framework UI Registry</span>\n            <span class=\"text-muted-foreground\">&bull;</span>\n            <span class=\"text-muted-foreground\">Vue 3.5 & React 19</span>\n          </div>\n\n          <!-- Main Headline -->\n          <h1 class=\"text-foreground text-4xl leading-[1.1] font-bold tracking-tight sm:text-5xl lg:text-6xl\">\n            The unbundled UI registry for design engineers.\n          </h1>\n\n          <!-- Subtitle -->\n          <p class=\"text-muted-foreground max-w-xl text-base leading-relaxed sm:text-lg\">\n            Own your source code. Copy production-grade components and dense workbenches directly into your project with\n            zero npm runtime lock-in.\n          </p>\n\n          <!-- CTA Buttons -->\n          <div class=\"flex flex-wrap items-center gap-3 pt-2\">\n            <a ui-button size=\"lg\" href=\"#components\" class=\"gap-2 font-semibold shadow-xs\">\n              <span>Explore 300+ Blocks</span>\n              <lucide-icon [img]=\"ArrowRight\" class=\"size-4\" />\n            </a>\n\n            <a ui-button variant=\"outline\" size=\"lg\" href=\"#spec\" class=\"gap-2 font-medium\">\n              <lucide-icon [img]=\"Code2\" class=\"text-muted-foreground size-4\" />\n              <span>Registry Spec</span>\n            </a>\n          </div>\n\n          <!-- Telemetry Metrics Strip -->\n          <div class=\"border-border/80 grid grid-cols-3 gap-4 border-t pt-6 text-left\">\n            <div>\n              <p class=\"text-foreground font-mono text-2xl font-bold\">300+</p>\n              <p class=\"text-muted-foreground mt-0.5 text-xs\">Workbenches & Primitives</p>\n            </div>\n            <div>\n              <p class=\"text-foreground font-mono text-2xl font-bold\">0 kB</p>\n              <p class=\"text-muted-foreground mt-0.5 text-xs\">Runtime Package Bloat</p>\n            </div>\n            <div>\n              <p class=\"text-foreground font-mono text-2xl font-bold\">100%</p>\n              <p class=\"text-muted-foreground mt-0.5 text-xs\">Cross-Framework Parity</p>\n            </div>\n          </div>\n        </div>\n\n        <!-- Right Column: Interactive Developer Terminal Workbench (6 Cols) -->\n        <div class=\"lg:col-span-6\">\n          <div ui-card class=\"border-border bg-card overflow-hidden rounded-xl shadow-sm\">\n            <!-- Terminal Header -->\n            <div class=\"border-border bg-muted/40 flex items-center justify-between border-b px-4 py-2.5\">\n              <!-- Window Controls & File Path -->\n              <div class=\"flex items-center gap-2\">\n                <div class=\"flex gap-1.5\">\n                  <div class=\"bg-destructive/80 size-3 rounded-full\"></div>\n                  <div class=\"bg-warning/80 size-3 rounded-full\"></div>\n                  <div class=\"bg-success/80 size-3 rounded-full\"></div>\n                </div>\n                <span class=\"text-muted-foreground ml-2 font-mono text-xs\">uipkge-cli &mdash; bash</span>\n              </div>\n\n              <!-- Action Controls -->\n              <div class=\"flex items-center gap-1.5\">\n                <!-- Speed Selector -->\n                <button\n                  type=\"button\"\n                  class=\"border-border bg-background text-muted-foreground hover:text-foreground focus-visible:ring-ring rounded border px-2 py-0.5 font-mono text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                  (click)=\"toggleSpeed()\"\n                >\n                  {{ executionSpeed() }}x speed\n                </button>\n\n                <!-- Copy Button -->\n                <button\n                  type=\"button\"\n                  class=\"border-border bg-background text-muted-foreground hover:text-foreground focus-visible:ring-ring flex items-center gap-1 rounded border px-2 py-0.5 font-mono text-xs transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                  (click)=\"copyCommand()\"\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' : 'Copy' }}</span>\n                </button>\n              </div>\n            </div>\n\n            <!-- Preset Navigation Tabs -->\n            <div class=\"border-border/80 bg-muted/20 flex items-center overflow-x-auto border-b px-2\">\n              @for (preset of presetList; track preset.id; let idx = $index) {\n                <button type=\"button\" [class]=\"presetTabClass(idx)\" (click)=\"runPreset(idx)\">\n                  {{ preset.label }}\n                </button>\n              }\n            </div>\n\n            <!-- Terminal Content Viewport -->\n            <div class=\"bg-card min-h-[220px] space-y-3 p-4 font-mono text-xs sm:p-5\">\n              <!-- Command Input Line -->\n              <div class=\"text-foreground flex items-start gap-2\">\n                <span class=\"text-primary font-bold select-none\">&gt;</span>\n                <span class=\"text-foreground font-medium break-all\">{{ currentPreset().command }}</span>\n              </div>\n\n              <!-- Output Lines -->\n              <div class=\"space-y-1.5 pt-1\">\n                @for (line of displayedLines(); track $index) {\n                  <div class=\"text-muted-foreground flex items-center gap-2 transition-colors duration-150\">\n                    <span class=\"text-success shrink-0 font-bold select-none\">✓</span>\n                    <span class=\"text-xs\">{{ stripCheck(line) }}</span>\n                  </div>\n                }\n\n                <!-- Typing / Loading Cursor -->\n                @if (isExecuting()) {\n                  <div class=\"text-muted-foreground flex items-center gap-2 pt-1\">\n                    <span class=\"bg-primary size-1.5 rounded-full\"></span>\n                    <span class=\"text-muted-foreground text-xs italic\">Streaming AST payload...</span>\n                  </div>\n                }\n              </div>\n            </div>\n\n            <!-- Terminal Footer Status Bar -->\n            <div\n              class=\"border-border bg-muted/30 text-muted-foreground flex items-center justify-between border-t px-4 py-2 font-mono text-xs\"\n            >\n              <div class=\"flex items-center gap-2\">\n                <span class=\"bg-success size-2 rounded-full\"></span>\n                <span>Registry v2.4.0 (OKLCH)</span>\n              </div>\n              <button\n                type=\"button\"\n                class=\"text-primary focus-visible:ring-ring inline-flex items-center gap-1 rounded-xs hover:underline focus-visible:ring-2 focus-visible:outline-none\"\n                (click)=\"runPreset(activePresetIndex())\"\n              >\n                <lucide-icon [img]=\"RotateCcw\" class=\"size-3\" />\n                <span>Re-run</span>\n              </button>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiHeroDeveloperTerminalComponent implements OnInit {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Check = Check\n  protected readonly Code2 = Code2\n  protected readonly Copy = Copy\n  protected readonly RotateCcw = RotateCcw\n\n  protected readonly presetList = presets\n\n  @Input('class') className?: string\n\n  readonly activePresetIndex = signal(0)\n  readonly displayedLines = signal<string[]>([])\n  readonly isExecuting = signal(false)\n  readonly copied = signal(false)\n  readonly executionSpeed = signal<1 | 2>(1)\n\n  private executionTimers: ReturnType<typeof setTimeout>[] = []\n  private copyTimer: ReturnType<typeof setTimeout> | undefined\n\n  constructor() {\n    inject(DestroyRef).onDestroy(() => this.clearTimers())\n  }\n\n  ngOnInit(): void {\n    this.runPreset(0)\n  }\n\n  readonly currentPreset = computed(() => presets[this.activePresetIndex()] ?? presets[0]!)\n\n  get rootClass(): string {\n    return cn('bg-background relative overflow-hidden px-4 py-16 sm:px-6 sm:py-24 lg:px-8', this.className)\n  }\n\n  presetTabClass(idx: number): string {\n    return cn(\n      'border-b-2 px-3 py-2 font-mono text-xs whitespace-nowrap transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none',\n      this.activePresetIndex() === idx\n        ? 'border-primary text-foreground bg-background/50 font-semibold'\n        : 'text-muted-foreground hover:text-foreground border-transparent',\n    )\n  }\n\n  stripCheck(line: string): string {\n    return line.replace(/^✔\\s*/, '')\n  }\n\n  toggleSpeed(): void {\n    this.executionSpeed.update((s) => (s === 1 ? 2 : 1))\n  }\n\n  runPreset(index: number): void {\n    this.activePresetIndex.set(index)\n    this.displayedLines.set([])\n    this.isExecuting.set(true)\n    this.clearTimers()\n\n    const current = presets[index] ?? presets[0]!\n    const delay = this.executionSpeed() === 1 ? 160 : 70\n    current.output.forEach((line, i) => {\n      this.executionTimers.push(\n        setTimeout(\n          () => {\n            this.displayedLines.update((prev) => [...prev, line])\n            if (i === current.output.length - 1) this.isExecuting.set(false)\n          },\n          (i + 1) * delay,\n        ),\n      )\n    })\n  }\n\n  async copyCommand(): Promise<void> {\n    try {\n      await navigator.clipboard.writeText(this.currentPreset().command)\n      this.copied.set(true)\n      clearTimeout(this.copyTimer)\n      this.copyTimer = setTimeout(() => this.copied.set(false), 2000)\n    } catch {\n      // Clipboard unavailable (e.g. insecure context): leave the Copy label.\n    }\n  }\n\n  private clearTimers(): void {\n    this.executionTimers.forEach((t) => clearTimeout(t))\n    this.executionTimers = []\n    clearTimeout(this.copyTimer)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/hero-developer-terminal/hero-developer-terminal.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/hero-developer-terminal/index.ts",
      "content": "export { UiHeroDeveloperTerminalComponent, type DeveloperTerminalPreset } from './hero-developer-terminal.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/hero-developer-terminal/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json"
  ],
  "description": "Developer-first hero section with split value proposition and an interactive live CLI terminal sandbox with preset command switching and copy controls.",
  "categories": [
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "hero"
}