# `MishkaBlogWeb.Templates.CollectionCard`
[🔗](https://github.com/mishka-group/mishka_blog/blob/v0.0.1/lib/mishka_blog_web/templates/collection_card.ex#L5)

The collections grid: one card per collection, in as many columns as fit the screen.

Declared only by `MishkaBlog.Collection`, and it reads that record directly rather than by column
position — a card is a specific shape (a folder tile beside its actions, a title over its blurb, and a
footer weighing posts against versions) that a generic position mapping cannot describe. The
resource's columns stay the field-selection contract and the vocabulary the table view sorts by.

## The grid is intrinsic, not stepped

The design draws three columns and the prototype steps down to two, which leaves a phone showing two
cramped cards with their actions cut off. Here the track list is
`repeat(auto-fill, minmax(min(100%, 280px), 1fr))`: a card never goes below 280px unless the viewport
itself is narrower, so the count falls from three to two to one on its own, at whatever width the
content actually needs. No breakpoint to miss, and none to get wrong.

## Features
- `:filter` - the labelled filter row: search, site, status, language
- `:select` - per-card selection for bulk operations, beside the Featured-only switch
- `:bulk_actions` - bulk actions on the selected cards
- `:paginate` - the page-size picker and numbered pages under the grid

The furniture around the cards is `MishkaCmsCoreWeb.Templates.CardChrome`, shared with the document
card pages. Pairs with `MishkaCmsCoreWeb.UIAdapters.Admin`, which draws the archive switch, the view
switch and the row actions.

# `count`

```elixir
@spec count(map(), atom()) :: non_neg_integer()
```

One aggregate off the record, or 0 when it arrived unloaded.

# `icon`

The switcher draws this glyph for the card view. It is the grid of four squares the design uses, and
`MishkaGervaz.UIAdapters.Tailwind.switcher_icon_class/1` renders it inline — the runtime CSS compiler
cannot emit a mask for a name it only sees at runtime.

# `posts_path`

Where a collection's title goes: the posts page, narrowed to that collection.

`posts_filter_collection_id` is the URL contract `MishkaBlog.BlogPost`'s `url_sync` block declares
(prefix `"posts"`), decoded back into filter state on arrival — so the destination opens with the
Collection filter already applied and the admin can widen it from there. A plain string rather than
`path/2` because a template module has no socket, matching
`MishkaDocumentWeb.Templates.DocumentCard.edition_path/1`.

# `render_bulk_actions`

# `render_empty`

# `render_error`

# `render_filters`

# `render_header`

# `render_item`

One collection card.

The head row wraps rather than shrinking: on a card narrow enough that the folder tile and the three
labelled actions cannot share a line, the actions drop underneath instead of pushing "Delete" past the
edge — which is what the prototype does at phone width.

# `render_pagination`

# `render_template_switcher`

# `status_badge`

```elixir
@spec status_badge(map()) :: %{label: String.t(), chip: String.t()}
```

How a collection's status badge reads and what colour it wears.

One entry per value of the `status` attribute, falling back to `:draft` — the attribute's own default.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
