Skip to content
Development

One CSS rule to unify two card systems, and the zombie server that lied about it

By Victor Da Luz
astrocssdev-logsite

Homepage cards on this site have a specific look: a soft blur behind them, a hairline border, and a green glow when you hover. The blog’s post cards - which come from a shared component library I use on two sites - don’t. They’re flat rectangles with an ordinary drop shadow. Put them next to each other and the blog looks like it belongs to an older version of the site.

The shared package’s README is explicit that its components are token-driven, not hardcoded to either site’s palette, which is exactly why I didn’t want to fork the component or add a one-off prop just for this. A fork drifts the moment either site changes its cards again. So the fix lives entirely on this site’s side: one CSS rule in theme.css that targets the post card’s exact combination of classes - bg-surface, rounded-xl, shadow-lg - and overrides it. I checked first that nothing else in this codebase happens to share that same three-class combination, so the rule can’t accidentally catch something I didn’t mean to touch.

The part I almost missed: the post card already had its own shadow-lg at rest. My first draft of the override added the blur and the border but forgot to turn that off, so the two card styles would’ve still looked different sitting still - only matching once you hovered. Turning off the inherited box-shadow explicitly was the one-line difference between “looks unified” and “looks unified, except when it doesn’t.”

Same issue flagged a second, smaller gap: the blog’s listing page has a glowing green page title, but a single post - after you click through - doesn’t. Whether that’s “inconsistent” or “the listing page is just louder than an individual post” is a matter of taste, so I sat with it rather than changing things reflexively. The call: the listing and an individual post are the same reading experience, so they should match; the homepage’s own big headline is a different context entirely - it already has an accent-colored line of its own doing that job - so it stays as it is.

The debugging footnote: my second verification pass came back with two failing pages out of fourteen, both returning a completely blank document. Nothing about the actual change explained that - the failures weren’t even on pages I’d touched. Turned out a leftover server process from the first verification run was still holding the port, and my cleanup command only knew how to stop one kind of dev server, not the other kind the accessibility checker uses. The two “failures” were a stale server refusing to answer a request cleanly, not a real bug. Killing that one leftover process and rerunning got a clean pass. Worth writing down, because it’s the second time this exact category of ghost has shown up this month, just wearing a different process name.

Related reading

Development

The badge that had nowhere to go

A status pill with shrink-0 and nowrap, a title with no min-w-0, and a flex row with no give anywhere - horizontal scroll at 320px, in two languages.

Read