Files
punktfunk/web/src
enricobuehler 0b252403cd
ci / bun-nix (pull_request) Successful in 51s
ci / docs-site (pull_request) Successful in 1m35s
ci / web (pull_request) Successful in 2m30s
ci / rust-arm64 (pull_request) Successful in 3m16s
ci / rust (pull_request) Failing after 9m12s
nix / flake (pull_request) Failing after 19m50s
fix(web): fix the card inset at the root, not at the call sites
The broken inset on the Displays configuration card was the symptom. The cause is
structural, and it had already been diagnosed at least twice in-tree without being fixed.

Two faults, both in components/ui/card.tsx:

1. The padding was a RESPONSIVE COMPOUND: `p-4 pt-0 sm:p-6 sm:pt-0`. tailwind-merge
   resolves conflicts only within a variant, so any call-site override won at the base
   and lost at `sm:` — correct on a phone, wrong on every desktop. Measured on the
   Displays card before this change: padding-top 24px at 500px, 0px at 1440px.

2. `pt-0` encoded an assumption about a SIBLING that nothing enforced — "a CardHeader is
   above me and supplies the top inset". Delete the header, which is exactly what tabbing
   a page does since the tab label replaces the card title, and the top inset silently
   vanishes at ≥640px.

Fix:

- One single-variant utility, `p-padding-card` — the same `--spacing-padding-card` token
  @unom/ui's own Card uses, so nested cards finally agree on their inset. A single
  variant cannot half-lose an override.
- Top inset is now self-correcting: `[&:not(:first-child)]:pt-0`. Ask the DOM instead of
  the author. A headerless CardContent keeps its inset with nothing to remember.

Seven call sites had grown their own compensation in five dialects — `p-6`,
`p-card pt-card sm:pt-card` (×3), `p-4 sm:pt-6` (×3), `pt-4 sm:pt-6`, and my own `pt-6`
from the tabs commit. All removed; they are the symptom-fixes this replaces. LogsCard
even carried a six-line comment correctly describing the trap and working around it
locally — that comment is now three lines saying it no longer needs saying.

`flush` stays: full-bleed content is a real intent, expressed as a prop the component
honours rather than a utility that has to out-argue the one already there.

Guarded by UI/Card → "Inset with and without header", a headered/headerless pair that has
to look identical on every side. It must be checked at BOTH widths — a single width
cannot show this class of bug, which is why it kept surviving.

Verified by measuring computed padding at 500px and 1440px: first child 20px on all four
sides, after-a-header 0px top and 20px elsewhere, identical at both widths. tsc clean,
biome clean on every touched file, 9/9 server tests, build + i18n clean, 32/32 screenshots.
2026-08-09 17:23:09 +02:00
..