{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "resources-category-grid",
  "title": "Resources — Category Grid",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/resources-category-grid/resources-category-grid.component.ts",
      "content": "// Resource library grouped into categories, each card listing its three most recent\n// entries with kind and read time, over a link to the full archive. Port of the\n// React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input } from '@angular/core'\nimport { ArrowUpRight, BookOpen, FileText, GraduationCap, LucideAngularModule, Wrench } 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'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\n\ninterface ResourceEntry {\n  title: string\n  kind: string\n  read: string\n}\n\ninterface ResourceCategory {\n  icon: typeof BookOpen\n  label: string\n  blurb: string\n  entries: ResourceEntry[]\n}\n\nconst categories: ResourceCategory[] = [\n  {\n    icon: BookOpen,\n    label: 'Guides',\n    blurb: 'Step-by-step for the work you do once.',\n    entries: [\n      { title: 'A reconciliation checklist for your first close', kind: 'Guide', read: '6 min' },\n      { title: 'Connecting Snowflake with a read-only role', kind: 'Guide', read: '4 min' },\n      { title: 'Mapping SCIM groups to row-level scope', kind: 'Guide', read: '8 min' },\n    ],\n  },\n  {\n    icon: FileText,\n    label: 'Engineering',\n    blurb: 'How it is built and why it is built that way.',\n    entries: [\n      { title: 'Why we version definitions, not dashboards', kind: 'Essay', read: '9 min' },\n      { title: 'Query planning against three warehouses', kind: 'Deep dive', read: '14 min' },\n      { title: 'What our audit log actually records', kind: 'Reference', read: '5 min' },\n    ],\n  },\n  {\n    icon: GraduationCap,\n    label: 'Benchmarks',\n    blurb: 'Numbers from real rollouts, not projections.',\n    entries: [\n      { title: 'Close speed across 240 finance teams', kind: 'Benchmark', read: '11 min' },\n      { title: 'Where self-serve analytics actually fails', kind: 'Research', read: '7 min' },\n      { title: 'Warehouse cost before and after budgets', kind: 'Benchmark', read: '9 min' },\n    ],\n  },\n  {\n    icon: Wrench,\n    label: 'Operations',\n    blurb: 'Running it after the rollout finishes.',\n    entries: [\n      { title: 'Handling a restatement mid-quarter', kind: 'Runbook', read: '6 min' },\n      { title: 'Alert routing that people do not mute', kind: 'Runbook', read: '5 min' },\n      { title: 'Quarterly access review in 20 minutes', kind: 'Runbook', read: '4 min' },\n    ],\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-resources-category-grid, [ui-resources-category-grid]',\n  standalone: true,\n  // The block renders its own root <section>: keep the host out of layout.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiSeparatorComponent,\n  ],\n  template: `\n    <section data-slot=\"resources-category-grid\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-6xl px-6 py-20 lg:py-28\">\n        <div class=\"flex flex-wrap items-end justify-between gap-6\">\n          <div class=\"max-w-2xl\">\n            <span ui-badge variant=\"secondary\">Library</span>\n            <h2 class=\"mt-4 text-3xl font-semibold tracking-tight sm:text-4xl\">Everything we have written down</h2>\n          </div>\n          <button ui-button variant=\"outline\">Browse the archive</button>\n        </div>\n\n        <div class=\"mt-10 grid gap-4 sm:grid-cols-2\">\n          @for (category of categories; track category.label) {\n            <div ui-card>\n              <div ui-card-content class=\"p-6\">\n                <div class=\"flex items-center gap-3\">\n                  <span\n                    class=\"border-border text-muted-foreground flex size-9 shrink-0 items-center justify-center rounded-lg border\"\n                    aria-hidden=\"true\"\n                  >\n                    <lucide-icon [img]=\"category.icon\" class=\"size-4\" />\n                  </span>\n                  <div class=\"min-w-0\">\n                    <p class=\"text-sm font-semibold\">{{ category.label }}</p>\n                    <p class=\"text-muted-foreground truncate text-xs\">{{ category.blurb }}</p>\n                  </div>\n                </div>\n\n                <ui-separator class=\"my-4\" />\n\n                <ul class=\"space-y-1\">\n                  @for (entry of category.entries; track entry.title) {\n                    <li>\n                      <a\n                        href=\"#\"\n                        class=\"hover:bg-muted focus-visible:ring-ring group flex items-start gap-3 rounded-md p-2 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n                      >\n                        <span class=\"min-w-0 flex-1\">\n                          <span class=\"block text-sm leading-snug\">{{ entry.title }}</span>\n                          <span class=\"text-muted-foreground mt-0.5 block font-mono text-xs\">\n                            {{ entry.kind }} · {{ entry.read }}\n                          </span>\n                        </span>\n                        <lucide-icon\n                          [img]=\"ArrowUpRight\"\n                          class=\"text-muted-foreground mt-0.5 size-3.5 shrink-0 transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5\"\n                        />\n                      </a>\n                    </li>\n                  }\n                </ul>\n              </div>\n            </div>\n          }\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiResourcesCategoryGridComponent {\n  protected readonly ArrowUpRight = ArrowUpRight\n  protected readonly categories = categories\n\n  @Input('class') className?: string\n\n  get rootClass(): string {\n    return cn('bg-background', this.className)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/resources-category-grid/resources-category-grid.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/resources-category-grid/index.ts",
      "content": "export { UiResourcesCategoryGridComponent } from './resources-category-grid.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/resources-category-grid/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",
    "https://uipkge.dev/r/angular/separator.json"
  ],
  "description": "Resource library grouped into categories, each card listing its three most recent entries with kind and read time, over a link to the full archive.",
  "categories": [
    "marketing"
  ]
}