# Forums as cards, and forum covers

*5 August 2026*

A category can show its forums as the row list it shows now, or as a grid of
cards with a picture on each. And a forum can be given a cover image.

## Why both, and why they are one piece of work

They arrived as two requests and they are one feature: a grid of cards without
images is a row list with more whitespace and less information, which is worse
at everything. The picture is the reason the grid is worth having, so the card
mode and the cover belong in the same change or neither is any good.

## Rows or cards is the operator's call, per category

Not a site-wide setting and not a member preference.

**Not site-wide**, because a community usually has both kinds of section. A
support category is a list of rooms you scan for the right one — rows, dense,
countable. A showcase or a games category is a set of destinations you browse —
cards, pictures, wider spacing. Forcing one shape on both makes one of them
worse.

**Not a member preference**, because it is not a comfort setting like dark
mode. It is a claim about what the section is for, and the operator is the
person who knows.

So it lives on the category, as `display_mode`, and applies to the forums
inside it. A forum can override it for its own sub-forums, because a category
of ordinary forums can still contain one that is a gallery.

## What a card is

- the cover, or a generated stand-in when there is none
- the title, and the description under it
- the counts, and the last post as a face and a time

That is the same information the row carries, arranged for a different scan.
Nothing is *only* available in one mode: a person who cannot see the picture,
or has images turned off, loses no fact.

**A card with no cover still works.** It gets a deterministic gradient derived
from the forum's name, in the theme's own hue family — the same technique the
avatars use, and for the same reason: stable, so a section's colour never
changes and the grid stays recognisable. An operator who never uploads anything
gets a grid that looks intended rather than a grid of grey boxes waiting to be
filled.

## The cover

**One image, one focal point, every size.** `cover_path` and `cover_focus`
on the forum, exactly as the profile design does it: the crop is
`object-position: 50% N%` in CSS, so the card, the forum header and any future
size all render from one uploaded file and there is no second crop to keep in
step. Repositioning is the same control, and it is the same JavaScript.

**Resized on upload, not on request.** A cover is decoded to at most 1600px
wide and stored as one file. Convoro is not going to grow an image pipeline
with variants and a cache directory to invalidate; a 1600px JPEG is about
200KB, it is served with long cache headers, and it is the same file for the
card and the banner.

**Sniffed, not trusted.** MIME comes from the file's own bytes and the
extension on disk comes from the sniff — the discipline the attachment store
established and the avatar store follows. SVG is not allowed and must not be
added without a sanitiser: it can carry script, and a forum cover is served to
everybody who visits the front page.

## Why not per-forum "featured" or ordering rules

Because that is a different feature wearing this one's clothes. A grid invites
"make this one bigger", then "pin three to the top", then a layout editor. The
grid orders forums by the position the operator already set, and that is all it
does. If the ask comes back with a real case behind it, it is its own note.

## What this does not do

**No masonry, no varying card sizes.** Equal cards in a plain grid. Varying
sizes encode importance the data does not have, and masonry makes the reading
order stop matching the DOM order.

**No cover on categories themselves.** A category is a heading, not a place.
Giving it a picture makes the page a stack of pictures with nothing under them.

**No cropping tool.** A focal point is not a crop, and it is deliberately the
weaker control: it cannot produce a wrong aspect ratio, it cannot be got wrong
on a screen size the operator did not test, and it is one integer.

---

## Bigger and more polished — 2026-08-08

Ernest, seeing them full of real imported content for the first time: the cards
should be **bigger and more polished**. Real content is what exposed it — the
original sizes were set against seed data with short titles and no covers, and
at that size a card was a row with a picture on top rather than something worth
choosing a grid for.

What changed, and why each one:

- **Wider cards.** `290px` → `340px` minimum. The old width put two-line titles
  in almost every card at typical desktop widths, and a wrapped title makes a
  grid look accidental. Fewer, larger cards is also the honest layout: an index
  has eight to twenty forums, not a hundred.
- **A taller cover, 16/7 → 16/9.** The original ratio was chosen so four cards
  fit above the fold. With real covers loaded that reads as a letterbox strip
  rather than a picture, and the fold argument was weaker than it looked — the
  first row is what matters, not the fourth.
- **The picture gets a scrim.** A gradient at the top of the cover, only when
  there is a cover. "New posts" sat directly on the image and was unreadable on
  anything pale. This is legibility, not decoration, and it is why the scrim is
  absent on the generated-colour placeholder, which already has known contrast.
- **Counts became chips.** They were two grey clauses that read as part of the
  description. As bordered chips they are obviously data, and the numbers keep
  the tabular figures so a column of cards does not jitter.
- **More room.** Body and foot padding both up. The card had less breathing
  space than the panels around it, which is what made it feel unfinished
  rather than small.
- **Unread is a ring, not a border colour.** `is-unread` set `border-color`,
  which the "hover, quietly" rule further down the file overrode on hover — so
  hovering an unread forum silently cleared its only unread signal. A ring
  drawn with `box-shadow` does not participate in that fight.

🚨 **A dead line was removed while in here.** `.forum-card:hover` set
`border-color: var(--c-primary)`, and the later "hover, quietly" block resets
exactly that property back to `--c-border` for rows and cards together. The
accent frame has never rendered. The later rule is the deliberate one — an
accent border on hover is louder than the thing it points at — so the dead
declaration went rather than the rule overriding it.

**Still not doing** any of the things the section above rules out: no masonry,
no varying sizes, no featured cards. Bigger is a size change, not a licence to
start encoding importance.
