{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "logo-cloud-categorized-grid",
  "title": "Logo Cloud Categorized Grid",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/logo-cloud-categorized-grid/logo-cloud-categorized-grid.component.ts",
      "content": "// Categorized 4-industry logo & enterprise customer workbench with scale metrics,\n// category filter tabs, and a full testimonial modal inspect. Port of the\n// Vue/React block 1:1 — click a card to open its quote, filter tabs narrow the grid.\nimport { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'\nimport {\n  ArrowRight,\n  Brain,\n  Building2,\n  Cloud,\n  Globe,\n  LucideAngularModule,\n  Quote,\n  ShieldCheck,\n  Terminal,\n  X,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiCardComponent } from '@/ui/card/card.component'\n\nexport interface CategorizedCustomer {\n  id: string\n  name: string\n  category: 'cloud' | 'devtools' | 'fintech' | 'ai'\n  tier: string\n  scale: string\n  quote: string\n  author: string\n  title: string\n}\n\nexport type LogoCloudCategory = 'all' | 'cloud' | 'devtools' | 'fintech' | 'ai'\n\nconst customerList: CategorizedCustomer[] = [\n  // Infrastructure & Cloud\n  {\n    id: 'cloudflare',\n    name: 'Cloudflare',\n    category: 'cloud',\n    tier: 'Enterprise Scale',\n    scale: '300+ Edge Data Centers',\n    quote:\n      'UIPKGE allowed us to standardize our internal console UI across 40+ engineering squads with zero bundle overhead.',\n    author: 'Alex K.',\n    title: 'Principal Architect, Cloudflare Workers',\n  },\n  {\n    id: 'flyio',\n    name: 'Fly.io',\n    category: 'cloud',\n    tier: 'Core Partner',\n    scale: '50k+ Compute Machines',\n    quote: 'We copy the raw SFC components and style them directly to match our brand — no package upgrades to fight.',\n    author: 'Sam T.',\n    title: 'Lead Frontend Engineer',\n  },\n  {\n    id: 'railway',\n    name: 'Railway',\n    category: 'cloud',\n    tier: 'Growth Tier',\n    scale: '1.5M Deployed Services',\n    quote:\n      'AST-level source control gives our team complete confidence without ever fearing breaking upstream package releases.',\n    author: 'Elena R.',\n    title: 'VP of Product Experience',\n  },\n\n  // Developer Tooling\n  {\n    id: 'vercel',\n    name: 'Vercel',\n    category: 'devtools',\n    tier: 'Design Pioneer',\n    scale: '100M+ Monthly Visitors',\n    quote:\n      'The level of keyboard ergonomics, focus ring layering, and spring physics in UIPKGE meets the highest craft benchmarks.',\n    author: 'Rauno F.',\n    title: 'Design Engineering Advisor',\n  },\n  {\n    id: 'supabase',\n    name: 'Supabase',\n    category: 'devtools',\n    tier: 'Ecosystem Partner',\n    scale: '1M+ Databases Provisioned',\n    quote: 'Dual-framework parity means we can ship both Vue and React examples for our developer docs in minutes.',\n    author: 'Ant W.',\n    title: 'Co-Founder & CEO',\n  },\n  {\n    id: 'biome',\n    name: 'BiomeJS',\n    category: 'devtools',\n    tier: 'Open Source',\n    scale: '20M+ Weekly Downloads',\n    quote: 'The cleanest AST code patterns in any modern UI registry. 100% type-safe.',\n    author: 'Nico M.',\n    title: 'Core Maintainer',\n  },\n\n  // Fintech & Security\n  {\n    id: 'stripe',\n    name: 'Stripe',\n    category: 'fintech',\n    tier: 'Global Infrastructure',\n    scale: '$1T+ Payment Volume',\n    quote:\n      'Zero dependency bloat guarantees compliance with strict internal security and dependency auditing requirements.',\n    author: 'Marcus H.',\n    title: 'Staff Security Engineer',\n  },\n  {\n    id: 'ramp',\n    name: 'Ramp',\n    category: 'fintech',\n    tier: 'Scale Unicorn',\n    scale: '$10B+ Managed Spend',\n    quote: 'The dense KPI tiles and transaction workbenches are plug-and-play masterpieces.',\n    author: 'David P.',\n    title: 'Director of Frontend Engineering',\n  },\n  {\n    id: 'snyk',\n    name: 'Snyk Security',\n    category: 'fintech',\n    tier: 'Enterprise SecOps',\n    scale: '2.5M+ Repos Scanned',\n    quote: 'Owning the source code completely removes transitive dependency CVE vulnerabilities.',\n    author: 'Sarah L.',\n    title: 'Head of Developer Relations',\n  },\n\n  // AI & Machine Learning\n  {\n    id: 'replicate',\n    name: 'Replicate',\n    category: 'ai',\n    tier: 'AI Infrastructure',\n    scale: '500M+ Model Inferences',\n    quote: 'We built our interactive prompt tester in an afternoon using UIPKGE terminal and slider primitives.',\n    author: 'Ben F.',\n    title: 'Co-Founder',\n  },\n  {\n    id: 'modal',\n    name: 'Modal Labs',\n    category: 'ai',\n    tier: 'GPU Cloud',\n    scale: '10k+ GPU Clusters',\n    quote: 'The tactile feel and speed of the UI blocks matches the lightning speed of our Python container runs.',\n    author: 'Erik B.',\n    title: 'Co-Founder & CTO',\n  },\n  {\n    id: 'mistral',\n    name: 'Mistral AI',\n    category: 'ai',\n    tier: 'Frontier AI',\n    scale: 'Global Deployment',\n    quote: 'Phenomenal attention to typographic hierarchy and clean Geist font metrics.',\n    author: 'Arthur M.',\n    title: 'Co-Founder',\n  },\n]\n\ninterface CategoryOption {\n  key: LogoCloudCategory\n  label: string\n  icon: typeof Globe\n}\n\nconst categoryOptions: CategoryOption[] = [\n  { key: 'all', label: 'All Industries', icon: Globe },\n  { key: 'cloud', label: 'Cloud & Infra', icon: Cloud },\n  { key: 'devtools', label: 'DevTools & DX', icon: Terminal },\n  { key: 'fintech', label: 'Fintech & Security', icon: ShieldCheck },\n  { key: 'ai', label: 'AI & GPU Compute', icon: Brain },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-logo-cloud-categorized-grid, [ui-logo-cloud-categorized-grid]',\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, UiCardComponent],\n  template: `\n    <section data-slot=\"logo-cloud-categorized-grid\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-7xl space-y-12\">\n        <!-- Section Header -->\n        <div class=\"mx-auto max-w-3xl space-y-4 text-center\">\n          <span ui-badge variant=\"secondary\" class=\"gap-1.5 px-3 py-1 font-mono text-xs shadow-xs\">\n            <lucide-icon [img]=\"Building2\" class=\"text-primary size-3.5\" />\n            Industry Benchmark Customers\n          </span>\n          <h2 class=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">\n            Powering the world's most rigorous engineering organizations.\n          </h2>\n          <p class=\"text-muted-foreground text-base\">\n            From frontier AI labs to global payment platforms, see how top tier engineering teams build on UIPKGE.\n          </p>\n\n          <!-- Vertical Category Filter Tabs -->\n          <div class=\"flex flex-wrap items-center justify-center gap-1 pt-4\">\n            @for (option of categories; track option.key) {\n              <button type=\"button\" [class]=\"filterButtonClass(option.key)\" (click)=\"selectCategory(option.key)\">\n                <lucide-icon [img]=\"option.icon\" class=\"size-3.5\" />\n                <span>{{ option.label }}</span>\n              </button>\n            }\n          </div>\n        </div>\n\n        <!-- Categorized Customer Grid -->\n        <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 lg:grid-cols-3\">\n          @for (customer of filteredCustomers(); track customer.id) {\n            <div\n              ui-card\n              class=\"border-border bg-card/90 hover:border-primary/40 group flex cursor-pointer flex-col justify-between space-y-4 rounded-2xl p-5 shadow-sm transition-colors hover:shadow-md\"\n              (click)=\"openModal(customer)\"\n              (keydown.enter)=\"openModal(customer)\"\n              tabindex=\"0\"\n              role=\"button\"\n              [attr.aria-label]=\"'Read quote from ' + customer.name\"\n            >\n              <!-- Card Top: Name & Tier Pill -->\n              <div class=\"flex items-center justify-between\">\n                <div class=\"flex items-center gap-2.5\">\n                  <div\n                    class=\"bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg font-mono text-xs font-bold\"\n                  >\n                    {{ customer.name.charAt(0) }}\n                  </div>\n                  <div>\n                    <h3 class=\"text-foreground group-hover:text-primary font-mono text-sm font-bold transition-colors\">\n                      {{ customer.name }}\n                    </h3>\n                    <p class=\"text-muted-foreground text-xs\">{{ customer.scale }}</p>\n                  </div>\n                </div>\n                <span ui-badge variant=\"outline\" class=\"font-mono text-xs capitalize\">\n                  {{ customer.tier }}\n                </span>\n              </div>\n\n              <!-- Quote Excerpt -->\n              <p class=\"text-muted-foreground line-clamp-2 text-xs leading-relaxed italic\">\n                &ldquo;{{ customer.quote }}&rdquo;\n              </p>\n\n              <!-- Card Footer: Author & Read Case Study -->\n              <div class=\"border-border/60 flex items-center justify-between border-t pt-2 text-xs\">\n                <span class=\"text-muted-foreground font-mono text-xs\">{{ customer.author }}</span>\n                <span class=\"text-primary flex items-center gap-1 text-xs font-medium group-hover:underline\">\n                  <span>Read quote</span>\n                  <lucide-icon [img]=\"ArrowRight\" class=\"size-3\" />\n                </span>\n              </div>\n            </div>\n          }\n        </div>\n\n        <!-- Testimonial Detail Dialog Modal -->\n        @if (activeModalCustomer(); as active) {\n          <div class=\"bg-background/80 fixed inset-0 z-50 flex items-center justify-center p-4 backdrop-blur-md sm:p-6\">\n            <div\n              class=\"bg-card border-border relative w-full max-w-xl space-y-6 rounded-2xl border p-6 text-left shadow-sm sm:p-8\"\n              role=\"dialog\"\n              aria-modal=\"true\"\n              [attr.aria-label]=\"'Testimonial from ' + active.name\"\n            >\n              <div class=\"border-border flex items-center justify-between border-b pb-4\">\n                <div class=\"flex items-center gap-3\">\n                  <div\n                    class=\"bg-primary/10 text-primary flex size-10 items-center justify-center rounded-xl font-mono text-sm font-bold\"\n                  >\n                    {{ active.name.charAt(0) }}\n                  </div>\n                  <div>\n                    <h3 class=\"text-foreground font-mono text-base font-bold\">{{ active.name }}</h3>\n                    <p class=\"text-muted-foreground font-mono text-xs\">{{ active.scale }}</p>\n                  </div>\n                </div>\n                <button\n                  type=\"button\"\n                  class=\"text-muted-foreground hover:text-foreground hover:bg-muted rounded-md p-1 transition-colors\"\n                  aria-label=\"Close testimonial\"\n                  (click)=\"closeModal()\"\n                >\n                  <lucide-icon [img]=\"X\" class=\"size-4\" />\n                </button>\n              </div>\n\n              <div class=\"space-y-4\">\n                <lucide-icon [img]=\"Quote\" class=\"text-primary/40 size-6\" />\n                <p class=\"text-foreground text-sm leading-relaxed sm:text-base\">&ldquo;{{ active.quote }}&rdquo;</p>\n              </div>\n\n              <div\n                class=\"border-border bg-muted/20 -mx-6 -mb-6 flex items-center justify-between rounded-b-2xl border-t p-4 px-6 pt-4 sm:-mx-8 sm:-mb-8 sm:px-8\"\n              >\n                <div>\n                  <p class=\"text-foreground text-xs font-bold\">{{ active.author }}</p>\n                  <p class=\"text-muted-foreground font-mono text-xs\">{{ active.title }}</p>\n                </div>\n                <span ui-badge variant=\"outline\" class=\"border-success/20 bg-success/10 text-success font-mono text-xs\">\n                  Verified Production Customer\n                </span>\n              </div>\n            </div>\n          </div>\n        }\n      </div>\n    </section>\n  `,\n})\nexport class UiLogoCloudCategorizedGridComponent {\n  protected readonly ArrowRight = ArrowRight\n  protected readonly Building2 = Building2\n  protected readonly Quote = Quote\n  protected readonly X = X\n\n  protected readonly categories = categoryOptions\n\n  @Input('class') className?: string\n  @Input() set initialCategory(v: LogoCloudCategory | undefined) {\n    if (v) this.selectedCategory.set(v)\n  }\n\n  readonly selectedCategory = signal<LogoCloudCategory>('all')\n  readonly activeModalCustomer = signal<CategorizedCustomer | null>(null)\n\n  readonly filteredCustomers = computed(() => {\n    const selected = this.selectedCategory()\n    if (selected === 'all') return customerList\n    return customerList.filter((c) => c.category === selected)\n  })\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  filterButtonClass(key: LogoCloudCategory): string {\n    return cn(\n      'flex items-center gap-1.5 rounded-lg border px-3 py-1.5 font-mono text-xs transition-colors',\n      this.selectedCategory() === key\n        ? 'border-primary bg-primary text-primary-foreground font-semibold shadow-xs'\n        : 'border-border bg-card/60 text-muted-foreground hover:text-foreground hover:bg-muted',\n    )\n  }\n\n  selectCategory(key: LogoCloudCategory): void {\n    this.selectedCategory.set(key)\n  }\n\n  openModal(customer: CategorizedCustomer): void {\n    this.activeModalCustomer.set(customer)\n  }\n\n  closeModal(): void {\n    this.activeModalCustomer.set(null)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/logo-cloud-categorized-grid/logo-cloud-categorized-grid.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/logo-cloud-categorized-grid/index.ts",
      "content": "export {\n  UiLogoCloudCategorizedGridComponent,\n  type CategorizedCustomer,\n  type LogoCloudCategory,\n} from './logo-cloud-categorized-grid.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/logo-cloud-categorized-grid/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/card.json"
  ],
  "description": "Categorized 4-industry logo & enterprise customer workbench with scale metrics, category filter tabs, and full testimonial modal inspect.",
  "categories": [
    "marketing"
  ],
  "deprecated": true,
  "replacedBy": "logos"
}