Skip to content
Components

Cards

A container for one subject you could act on — a parcel, a project, a plan, a metric — with a horizontal form and a specimen form for comparing options.

Variants

Basic

Title and body only. The default — reach for this before anything else.

Container + header + body. No media, no actions.

Media

A tinted preview panel above the content.

Marketing and pickers. flush + raised; hover darkens the border.
Lot area
812m²
Surveyed · RP80432
Metric. Caps eyebrow, tabular figures, unit never inside the number.

Selectable

Chosen from a set. Border widens; the fill never changes.

Project pickers, plan comparison. Behaves as a radio or checkbox.
LinkedWhole card is the target
Open the list row docs
One destination, no buttons. The chevron signals it; hover darkens the border.
Empty

Says what the absence means, never just "no data".

Composed at the call site — a dashed rule on the sunken surface. There is no dashed prop on GdCard.
Code
<GdCard>
  <h3>Basic</h3>
  <p>Title and body only.</p>
</GdCard>

<GdCard flush interactive elevation="raised">
  <GdCardMedia tint="green" :height="88" :plaque="52">
    <GdIcon :d="shed" :size="30" :stroke="1.8" />
  </GdCardMedia>
  <div class="body">…</div>
</GdCard>

<GdMetricCard label="Lot area" value="812" unit="m²" sub="Surveyed · RP80432" />

<GdCard selected>…</GdCard>

<GdCard to="/projects/42-jarrah" link-label="Open 42 Jarrah Street">…</GdCard>

Horizontal

Split — media 50%

18 Ironbark Road

L3 SP221704 · 1,204 m²

Five-lot subdivision tested. Frontage and rear access both clear; one easement crosses lot 4.

Standard — media 132px

220 Wattle Road

L1 RP44201 · 607 m²

Rear deck under 10 m² and below 1 m — exempt. Nothing to lodge.

Compact — glyph tile only
In-ground poolNeeds a building approval and a compliant barrier. Setbacks are the usual sticking point.
Code
<GdCard flush class="row-card">   <!-- .row-card { display:flex } -->
  <GdCardMedia horizontal size="132px" tint="green" :plaque="56">
    <GdIcon :d="deck" :size="32" :stroke="1.8" />
  </GdCardMedia>
  <div class="body">…title, lot/plan, sentence, actions…</div>
</GdCard>

Specimen card

Lots2Min area405 m²Frontage10 m
ABattle-axe

Rear lot keeps the jacaranda; the handle costs 3.5 m of frontage.

Lots3Min area380 m²Frontage12.5 m
BThree across

Even frontages, but lot 2 falls 20 m² under the minimum — needs a variation.

Code
<GdSpecimenCard
  title="Battle-axe"
  badge="A"
  :stats="[
    { label: 'Lots', value: '2' },
    { label: 'Min area', value: '405 m²' },
    { label: 'Frontage', value: '10 m' }
  ]"
  selected
>
  <template #preview><svg …the plan at working size…/></template>
  Rear lot keeps the jacaranda; the handle costs 3.5 m of frontage.
  <template #footer>
    <GdApprovalStack inline :required="['building', 'council']" />
  </template>
</GdSpecimenCard>

States

Rest
Hover me
Selected
Raised
Code
<GdCard>Rest</GdCard>
<GdCard interactive>Hover me</GdCard>
<GdCard selected>Selected</GdCard>
<GdCard elevation="raised">Raised</GdCard>

API

GdCard

Props

PropTypeDefault
elevation"sunken" | "flat" | "raised" | "overlay" | "modal""flat"

Pairs a surface with a shadow — never mixed. `sunken` swaps the ground and drops the border; the other three add a shadow only.

selectedboolean—

Chosen from a set. The border widens to `--gd-border-width-selected` and the padding shrinks by the same pixel, so nothing moves. Also sets `aria-current`.

interactiveboolean—

Pointer feedback for a card that does something: the cursor, and a darker border on hover. `to` and `href` turn it on by themselves.

flushboolean—

Drops the padding and clips overflow — for a card whose first child is a full-bleed `GdCardMedia`.

tostring—

Internal route. Renders a stretched NuxtLink over the whole card.

hrefstring—

External URL. Renders a stretched `<a>` over the whole card.

linkLabelstring—

The accessible name of that stretched link. Without it the link is announced with whatever text happens to fall inside it.

Slots

default

The card's contents. Buttons and links inside stay clickable above the stretched link.

GdCardMedia

Props

PropTypeDefault
tint"accent" | "green" | "none""accent"

Decoration, not a status claim. `green` reuses the success wash rather than introducing a new green; `none` is the subtle surface.

heightnumber110

Panel height in pixels, vertical mode only. The design uses 88–126.

horizontalboolean—

Side-column mode: the panel stretches to the card's height and the rule moves to its right edge.

sizestring"132px"

The width in horizontal mode. The design's two are "132px" and "50%".

plaquenumber60

The white plaque's box size in pixels. The glyph inside should be about 0.55 of it.

bareboolean—

Put the slot directly on the panel, no plaque. For media that IS a drawing — a GdIllustration — rather than a glyph that needs a tile under it.

Slots

default

One glyph, centred in the plaque. With no slot content the plaque is not rendered at all.

GdMetricCard

Props

PropTypeDefault
labelrequiredstring—

The caps eyebrow above the number.

valuerequiredstring | number—

The figure itself, drawn in tabular numerals. Without its unit.

unitstring—

The unit, beside the number and never inside it — "m²", not part of `value`.

substring—

The quiet provenance line — "Surveyed · RP80432".

deltastring—

A change since some period — "+18", "−4%". Free text; the card does not compute it.

deltaTone"success" | "danger" | "neutral""neutral"

Which way the change reads. The CALLER decides: a falling error rate is success, a falling lot count may be too.

GdSpecimenCard

Props

PropTypeDefault
titlerequiredstring—

The option's name — "Battle-axe", "Three across".

badgestring—

The letter badge — "A", "B", "C".

stats{ label: string; value: string }[][]

The divided strip. Every specimen in a set carries the same stats in the same order; the strip is not rendered when this is empty.

selectedboolean—

Follows the card rule — the border widens, the fill never changes. Also sets `aria-current`.

previewHeightnumber126

The preview zone's height in pixels: the design's working size.

Slots

preview

The option at working size, on the sunken survey grid — usually an SVG plan.

default

One sentence on the trade-off this option makes.

footer

Under the sentence — usually an inline approval stack.

Usage Guidelines

  • Use a card for under about eight items, each needing two or more lines and its own actions, where the user is choosing between them.
  • Use a list row for a long or unbounded set of same-shaped things where the job is to find one. Rows scan; cards don't.
  • Use a banner when the thing is a message about the view rather than a subject in it.
  • Use to or href with linkLabel when the whole card has one destination — and put no buttons in it.
  • Use buttons in the footer row when the card has more than one thing you could do: one primary leading, secondary beside it, a "⋯" menu past two.
  • Pair flush with GdCardMedia and nothing else. A flush card with padded content has no padding to give it.
  • Give every specimen in a set the same stats in the same order. The strip is a comparison instrument.
  • Reach for GdSpecimenCard, never more than four across, when the drawn thing is the argument.

Behavior & Anatomy

Card, row or banner

If the thing is one of many in a scannable list, it is a list row, not a card. If it is a message about the view rather than a subject in it, it is a banner. Those two questions decide almost every "which component?" argument this system will have — the design's own cut: under about eight items, each needing two or more lines and its own actions, where the user is choosing between them, cards; a long or unbounded set of same-shaped things where the job is to find one, rows. Rows scan; cards don't.

Selection and the stretched link

Selection widens the border rather than changing the fill, so it survives on any surface — a selected card on the sunken grey and a selected card on white read identically, which a tinted fill cannot manage. The padding shrinks by the same pixel the border grows, so nothing moves.

to and href make the whole card a link via a stretched pseudo-element rather than by wrapping everything in an <a>. That keeps buttons and links inside the card operable — nesting interactive elements inside an anchor is invalid and behaves differently in every browser.

The comparison instrument

Every specimen in a set carries the SAME stats in the same order. The strip is a comparison instrument, and an instrument with per-card columns measures nothing.

  • One primary action per card, leading the footer row; secondary beside it; overflow into a "⋯" menu past two.
  • A linked card carries no buttons — one destination, signalled by the chevron. Mixing the two makes every click a gamble.
  • Hover on an interactive card darkens the border. Never a lift or a scale.
  • The media tint is decoration. Nothing about the card's content may depend on which tint it got.

Navigate

Esc