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.
Media
A tinted preview panel above the content.
flush + raised; hover darkens the border.Selectable
Chosen from a set. Border widens; the fill never changes.
Says what the absence means, never just "no data".
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
18 Ironbark Road
L3 SP221704 · 1,204 m²Five-lot subdivision tested. Frontage and rear access both clear; one easement crosses lot 4.
220 Wattle Road
L1 RP44201 · 607 m²Rear deck under 10 m² and below 1 m — exempt. Nothing to lodge.
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
Rear lot keeps the jacaranda; the handle costs 3.5 m of frontage.
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
Code
<GdCard>Rest</GdCard>
<GdCard interactive>Hover me</GdCard>
<GdCard selected>Selected</GdCard>
<GdCard elevation="raised">Raised</GdCard>API
GdCard
Props
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
defaultThe card's contents. Buttons and links inside stay clickable above the stretched link.
GdCardMedia
Props
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.
heightnumber110Panel 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%".
plaquenumber60The 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
defaultOne glyph, centred in the plaque. With no slot content the plaque is not rendered at all.
GdMetricCard
Props
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
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`.
previewHeightnumber126The preview zone's height in pixels: the design's working size.
Slots
previewThe option at working size, on the sunken survey grid — usually an SVG plan.
defaultOne sentence on the trade-off this option makes.
footerUnder 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
toorhrefwithlinkLabelwhen 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
flushwithGdCardMediaand 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.