Skip to main content

Cards

A content card in two styles that share one colour system. The base l-ui-card is bordered; add l-ui-card--gradient to paint a soft tint fill behind the same border. Colour comes from a separate, reusable tint slot, so the style and colour axes compose independently. Toggle the theme to see both adapt.

The tint slots (l-ui-tint-1 to l-ui-tint-5) are a decorative palette shared across components, independent of the brand --accent (which drives interactive things like primary buttons and active tabs). The slot numbers are palette positions, not fixed hues - the gem ships sensible defaults (teal, green, amber, rose, purple) and you re-skin any slot once in your overrides file without the class name ever going stale. A card with no tint slot falls back to the neutral border and foreground colours.

Bordered cards

The default style: a tint-coloured border and title over the plain surface. Pair the title with an optional l-ui-card__icon (painted in the tint colour) and a l-ui-card__body.

Start

Begin from a template or bring your existing codebase.

Build

Complete features with AI assistance and best practice as standard.

Deploy

Review and ship to your own servers or cloud infrastructure.

Run

Run smoothly with autonomous monitoring, alerts, and updates.

<div class="l-ui-card l-ui-tint-1">
  <h3 class="l-ui-card__title">
    <span class="l-ui-card__icon" style="--l-ui-icon-src: url('icon.svg')" aria-hidden="true"></span>
    <span>Start</span>
  </h3>
  <p class="l-ui-card__body">Begin from a template or bring your existing codebase.</p>
</div>

Gradient cards

Add l-ui-card--gradient to paint a soft 135° tint fill behind the same border and title. The fill colours come from the same tint slot, so only the extra modifier changes.

Start

Begin from a template or bring your existing codebase.

Build

Complete features with AI assistance and best practice as standard.

Deploy

Review and ship to your own servers or cloud infrastructure.

Run

Run smoothly with autonomous monitoring, alerts, and updates.

<div class="l-ui-card l-ui-card--gradient l-ui-tint-1">
  <h3 class="l-ui-card__title">Start</h3>
  <p class="l-ui-card__body">Begin from a template or bring your existing codebase.</p>
</div>

Eyebrow

Add a l-ui-card__eyebrow above the title for a small uppercase label - useful for pricing tiers or categories.

Free

Self-hosted

Run it yourself on your own infrastructure.

SaaS

Hosted

We host and manage it for you.

Managed

Your cloud

Managed by us, running in your cloud account.

Enterprise

Bespoke

Tailored deployment, support, and SLAs.

<div class="l-ui-card l-ui-tint-1">
  <p class="l-ui-card__eyebrow">Free</p>
  <h3 class="l-ui-card__title">Self-hosted</h3>
  <p class="l-ui-card__body">Run it yourself on your own infrastructure.</p>
</div>

One-off custom colour

For a colour outside the shipped palette, set the four --l-ui-tint-* role variables yourself instead of adding a tint slot. The shipped slots carry separate light and dark values, so a single set of values is theme-fixed: for full dark-mode support supply both, with a .dark rule (or prefers-color-scheme), as the magenta card below does. To re-skin a slot everywhere instead, override its --l-ui-tint-N-* tokens in your overrides file. You can also reach the brand accent on demand by pointing the role variables at var(--accent) - it already adapts to the theme, so no extra rule is needed.

Custom magenta

Light and dark values keep the card readable in both themes.

Brand accent

Points the tint role variables at var(--accent) to use the brand colour.

<%# Define light + dark values so the card adapts when the theme is toggled %>
<style>
  .tint-magenta {
    --l-ui-tint-border:     oklch(0.6 0.13 320);
    --l-ui-tint-foreground: oklch(0.45 0.16 320);
    --l-ui-tint-from:       oklch(0.95 0.05 320);
    --l-ui-tint-to:         oklch(0.88 0.09 320);
  }

  .dark .tint-magenta {
    --l-ui-tint-border:     oklch(0.55 0.15 320);
    --l-ui-tint-foreground: oklch(0.78 0.15 320);
    --l-ui-tint-from:       oklch(0.28 0.06 320);
    --l-ui-tint-to:         oklch(0.22 0.07 320);
  }
</style>

<div class="l-ui-card l-ui-card--gradient tint-magenta">
  <h3 class="l-ui-card__title">Custom magenta</h3>
  <p class="l-ui-card__body">Your content here.</p>
</div>

<%# A one-off light-only card can set the variables inline instead - just note %>
<%# that inline values are theme-fixed and will not adapt in dark mode. %>

<%# Or reuse the brand accent - it already adapts to the theme, no rule needed %>
<div class="l-ui-card"
     style="--l-ui-tint-border: var(--accent);
            --l-ui-tint-foreground: var(--accent);">
  <h3 class="l-ui-card__title">Brand accent</h3>
</div>

CSS classes

Card CSS classes
Class Description
l-ui-card Base card; bordered, on the surface background
l-ui-card--gradient Adds the soft tint fill behind the border
l-ui-tint-1l-ui-tint-5 Shared tint slot (defaults: teal, green, amber, rose, purple); usable on any control, not just cards
l-ui-card__eyebrow Small uppercase label above the title
l-ui-card__title Card heading, coloured by the active tint
l-ui-card__icon Optional icon in the title, painted in the tint colour (set --l-ui-icon-src)
l-ui-card__body Body copy in the muted foreground colour

Each tint slot exposes four role variables that any control can read - --l-ui-tint-border, --l-ui-tint-foreground, --l-ui-tint-from, and --l-ui-tint-to. The shipped palette is defined by the --l-ui-tint-N-* tokens (light and dark); override those in your overrides file to re-skin a slot everywhere, or set the role variables inline for a single element. The slot numbers are palette positions, so changing a slot's hue never makes a class name misleading. Because l-ui-tint-* only sets these variables, the same class works on any control that reads them - not just cards.