# Model Catalog Card

Model Catalog Card [#model-catalog-card]

The **Model Catalog Card** is a rich tile for a single model catalog entry (wllama / webllm / transformers / litert / mediapipe shapes): name, a size badge, an optional description, a metadata chip row (architecture, params, quantization, context), and a capability sub-row (tools / vision / embedding / reranking / reasoning) rendered conditionally from the entry's flags. It complements the Model Selector (a picker) — this is a presentation tile. It fires `onClick(id)` and supports a selected ring.

Preview [#preview]

```tsx
'use client';

import { useState } from 'react';

import { ModelCatalogCard, type CatalogEntry } from '@/components/model-catalog-card';

const ENTRIES: CatalogEntry[] = [
  {
    id: 'llama-3.2-1b',
    name: 'Llama 3.2 1B Instruct',
    size: '1.2 GB',
    description: 'Compact instruction-tuned chat model with tool calling.',
    architecture: 'llama',
    parameters: '1.2B',
    quantization: 'Q4_K_M',
    contextLength: 8192,
    tools: true,
    reasoning: true,
  },
  {
    id: 'gemma-4-e2b',
    name: 'Gemma 4 E2B',
    size: '2.4 GB',
    description: 'Multimodal model with image understanding.',
    architecture: 'gemma',
    parameters: '2B',
    contextLength: 32768,
    vision: true,
    tools: true,
  },
];

/**
 * Demo for ModelCatalogCard. Renders two catalog tiles with capability badges
 * and a selected ring driven by local state.
 */
export default function ModelCatalogCardDemo() {
  const [selected, setSelected] = useState('llama-3.2-1b');
  return (
    <div className="flex flex-wrap gap-4">
      {ENTRIES.map((e) => (
        <ModelCatalogCard
          key={e.id}
          entry={e}
          selected={selected === e.id}
          onClick={setSelected}
        />
      ))}
    </div>
  );
}
```

Installation [#installation]

```bash
npx shadcn@latest add @localmode/ui/local-first/model-catalog-card
```

Data source & dependencies [#data-source--dependencies]

**Data source:** renders the catalog entry you pass — works with any backend. Recommended producer: `useModelRecommendations` / your registry data from `@localmode/react` (on-device, optional).

* `lucide-react` — icons
* `clsx` + `tailwind-merge` — via the shared `cn()` util (installed automatically as a registry dependency)

Files installed [#files-installed]

* `model-catalog-card.tsx` — the `ModelCatalogCard` component
* `lib/utils.ts` — the `cn()` helper (if not already present)

Props [#props]

**ModelCatalogCard**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `entry` | `object` | — | **Required.** The catalog entry to render. |
| `selected` | `boolean` | — | Whether this card is the selected one (adds an accent ring). |
| `onClick` | `function` | — | Fired with the entry id when the card is clicked. |

**CatalogEntry**

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `id` | `string` | — | **Required.** Stable model id (passed to `onClick`). |
| `name` | `string` | — | **Required.** Display name. |
| `size` | `string` | — | Human-readable size (e.g. "1.2 GB"). |
| `description` | `string` | — | One-line description. |
| `architecture` | `string` | — | Architecture (e.g. "llama"). |
| `parameters` | `string` | — | Parameter count label (e.g. "1.2B"). |
| `quantization` | `string` | — | Quantization label (e.g. "Q4_K_M"). |
| `contextLength` | `number` | — | Context window in tokens. |
| `tools` | `boolean` | — | Capability flags. |
| `vision` | `boolean` | — | — |
| `embedding` | `boolean` | — | — |
| `reranking` | `boolean` | — | — |
| `reasoning` | `boolean` | — | — |

Examples [#examples]

A selectable tile [#a-selectable-tile]

```tsx
<ModelCatalogCard entry={entry} selected={entry.id === picked} onClick={setPicked} />
```

Customization [#customization]

Capability badges render only for the flags present on the entry — edit the `CAPABILITIES` array to add more (e.g. audio). The selected state adds a `ring-1 ring-primary`. Styled entirely with shadcn/ui CSS-variable utilities so it inherits your theme — because you own the copied file, every class and threshold is yours to change.