From 7c0313a7cbbdb3b42265a89c6ec003b1b5744dd2 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 21 Jul 2026 00:25:31 +0200 Subject: [PATCH] fix(web): flush card content, so a full-bleed table stops doubling its inset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `` never removed the padding it looked like it removed: tailwind-merge resolves conflicts within a variant, so `p-0` cancels `p-4` but leaves `sm:p-6` standing. Every call site that used it nests a CardHeader inside, which brings its own `sm:p-6` — so at >=640px the title sat 24px further in than its neighbours'. Visible on the Plugins page as 'Installed plugins' not lining up with 'Plugin runner'. Give CardContent a `flush` prop that omits the padding outright, and use it at the three call sites (Store, Pairing, Stats) rather than fixing the symptom three times and leaving the footgun in place. Co-Authored-By: Claude Fable 5 --- web/src/components/ui/card.tsx | 20 +++++++++++++++++--- web/src/sections/Pairing/PendingDevices.tsx | 2 +- web/src/sections/Stats/Recordings.tsx | 2 +- web/src/sections/Store/Installed.tsx | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/web/src/components/ui/card.tsx b/web/src/components/ui/card.tsx index c47cfa2b..257190a5 100644 --- a/web/src/components/ui/card.tsx +++ b/web/src/components/ui/card.tsx @@ -63,11 +63,25 @@ const CardDescription = React.forwardRef< )); CardDescription.displayName = "CardDescription"; +/** + * Card body. Pass `flush` for content that should meet the card's edges — a full-bleed table, most + * commonly — instead of trying to cancel the padding from the outside. + * + * `className="p-0"` does NOT work for that: tailwind-merge only resolves conflicts *within the same + * variant*, so `p-0` cancels `p-4` but leaves `sm:p-6` standing, and the padding silently returns at + * ≥640px. Every call site that tried it ended up with a doubled inset once a `CardHeader` (which + * brings its own `sm:p-6`) was nested inside — visible as one card whose title sits 24px further in + * than its neighbours'. + */ const CardContent = React.forwardRef< HTMLDivElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
+ React.HTMLAttributes & { flush?: boolean } +>(({ className, flush = false, ...props }, ref) => ( +
)); CardContent.displayName = "CardContent"; diff --git a/web/src/sections/Pairing/PendingDevices.tsx b/web/src/sections/Pairing/PendingDevices.tsx index 0ec15637..76dc3aea 100644 --- a/web/src/sections/Pairing/PendingDevices.tsx +++ b/web/src/sections/Pairing/PendingDevices.tsx @@ -78,7 +78,7 @@ export const PendingDevices: FC<{ return ( - +

diff --git a/web/src/sections/Stats/Recordings.tsx b/web/src/sections/Stats/Recordings.tsx index e8741325..d96852b5 100644 --- a/web/src/sections/Stats/Recordings.tsx +++ b/web/src/sections/Stats/Recordings.tsx @@ -114,7 +114,7 @@ export const RecordingsCard: FC<{ {m.stats_recordings_empty()} ) : ( - + diff --git a/web/src/sections/Store/Installed.tsx b/web/src/sections/Store/Installed.tsx index a76c8a8b..b03b39bc 100644 --- a/web/src/sections/Store/Installed.tsx +++ b/web/src/sections/Store/Installed.tsx @@ -49,7 +49,7 @@ export const InstalledList: FC<{ const rows = installed.data ?? []; return ( - + {m.store_installed_title()}