Cards assemble from discrete blocks. Blocks are interchangeable and order-independent. Add what you need, omit what you don't: header, image, data grid, list, actions, body.
All spacing derives from a single 8px unit. Padding is 2u. Gaps are 1px. Type steps at 10, 12, 14, 15. No magic numbers. Every measurement traces to the base unit.
The root card is a CSS Grid with row-gap: 1px over a foreground-colored background. Children fill with the background color. The gap reveals the line. One mechanism, zero border doubling.
Two values: foreground and background. Lines, text, and loading states use foreground. Surfaces use background. Swap two CSS custom properties and every element follows.
Download sys.card.css and include it in your document head with <link rel="stylesheet" href="sys.card.css">
Cards are responsive by default via container queries. Columns collapse, horizontal cards stack, and typography scales — all driven by the card's own
width, not the viewport. Add .sc-fluid to remove the default max-width constraint.
.sc Root vertical card.sc-fluid Remove max-width.sc-h Root horizontal card.sc-h-fluid Fluid horizontal.sc-cols-2 2-column row.sc-cols-3 3-column row.sc-cols-4 4-column row.sc-list Vertical list.sc-pad Padded content.sc-header Space-between flex.sc-img-wrap Image container.sc-img Grayscale image.sc-actions Split action bar.sc-action Action button/link.sc-action-full Full-width action.sc-link Inline text link.t-lg 15px title.t-md 12px body.t-sm 10px label.t-label Muted label.t-value 14px data.ld-img Image area skeleton.ld-block Block-level skeleton.ld-inline Inline skeleton rect.w-100 100% width.w-80 80% width.w-60 60% width.w-40 40% width.w-20 20% width.flex-grow Fill remaining.h-full Full height.max-w-none Remove max-width--c-fg Foreground--c-bg Background--c-mute Muted text--c-surface Raised surface--c-line Subtle dividers--u Base unit (8px)