Cards primitive for pa.gf.cx — SHIPPED 2026-05-24 at assets.gf.cx/cards
DARE.CO.UK · PARKED SKETCH · 2026-05-31
Mirrored from ~/.claude/.../memory/parked_sketch_cards_primitive_2026-05-24.md. This is a design sketch parked for future build — read for context, not as a current deliverable.
SHIPPED. cards.css v0.1.0 lives at https://assets.gf.cx/cards/cards.css with 3 variants (–system, –stat, –tile) + .card-grid layout + CSS-custom-property theming. README at /cards/README.md. Migration of 4-6 existing surfaces (pa landing, expenses, status, vehicles, contractors) is the remaining work — tackle each one incrementally as the surface gets edited.
STATUS: SHIPPED 2026-05-24
Built and deployed:
- ~/Code/toolkit/web-assets/cards/cards.css — 3 variants (--system, --stat, --tile) + .card-grid layout
- ~/Code/toolkit/web-assets/cards/README.md — usage docs
- ~/Code/toolkit/web-assets/index.html — assets.gf.cx landing updated to advertise cards as a primitive
- Live at: https://assets.gf.cx/cards/cards.css
Architecture choices made during the build:
- BEM-style naming: .card, .card--variant, .card__element
- CSS custom properties for theming — reads portfolio’s existing --bg-card / --accent / --line-strong with fallbacks, so cards.css works on bare HTML AND on portfolio-themed pages
- No hover transform (Dan’s “1px shift jarring” feedback respected)
- Grayscale-thumb-to-color hover baked in for .card--system
- Print rules included (flatten + page-break-inside avoid)
- Anchor cards (a.card) shift border-color to accent on hover; non-anchor cards opt-in via .card--hoverable
Remaining work — migration: Each portfolio surface still uses its own
.system / .stat / .cell classes. Migrating to canonical .card classes
is incremental — do it when next editing the surface, not as a big-bang sweep.
Surfaces to migrate (priority):
1. pa/index.html — .system cards → .card--system
2. pa/equipment/index.html — .item cards → .card--system
3. pa/contractors/index.html — .item cards → .card--system
4. pa/household/index.html — .item cards → .card--system
5. Status pages — .stat → .card--stat (would need pa_job_status_render.py update)
6. Harvest landing — .cell → .card--tile
Dan 2026-05-24: “Lets schedule time to build ‘cards’ for pa.gf.cx, it’s handy sharing with audrey now that it’s taking shape.”
Why now
Five surfaces already use card-grid layouts with hand-rolled CSS that’s similar-but-not-identical:
| Surface | Card pattern | Renderer |
|---|---|---|
pa.gf.cx/ New Hope landing |
.system cards (13 cards, photo/emblem thumb + body) |
hand-written pa/index.html |
pa.gf.cx/properties/new-hope/expenses/ |
.cell cards (60 category tiles) |
pa_harvest_render.py |
pa.gf.cx/vehicles/*.html |
various sections — TCO stat cards, receipt grid tiles | hand-written + Python inject |
pa.gf.cx/amazon/_status/ |
.stat cards (6 stat tiles) |
pa_job_status_render.py |
pa.gf.cx/contractors/*.html |
signal-axis cards | hand-written |
Plus future: vehicles index, expense year pages, claim cockpit, every per-substrate landing.
Recipe
- Create
~/Code/toolkit/web-assets/cards/cards.css— the canonical primitive - Define three card variants:
-
.card--system— thumb + body (matches pa landing today) -.card--stat— label + big serif value + sub (matches status today) -.card--tile— square tile with title + meta (matches category landing today) - Add layout primitive:
.card-grid—display:grid; grid-template-columns:repeat(auto-fill, minmax(220px, 1fr)); gap:18px - Each surface imports via
<link rel="stylesheet" href="https://assets.gf.cx/cards/cards.css"> - Replace hand-rolled CSS in each renderer with the shared classes
- Update
web-assets/index.htmlto list the new primitive
Generic Amazon card (per Dan’s note)
For Amazon specifically — a single generic “Amazon section” card sits on the pa.gf.cx New Hope landing, links to /amazon/ (which is its own surface with subpages). Same shape as the existing system cards. No per-order card needed on the landing; the orders.html master table handles browsing.
“Easy programmatically for any page” — honest answer
| Surface | Programmatic? |
|---|---|
| Status pages, expense pages, per-order pages | ✓ Yes (already rendered by Python scripts; just import the CSS + rename classes) |
| pa landing, vehicle records, contractor records | ✗ Hand-written; each needs a manual edit pass |
So lift-and-shift is mixed: programmatic renderers convert in ~10 min each; hand-written surfaces are case-by-case CSS migration.
Cost
| Step | Effort |
|---|---|
| Author cards.css + deploy assets.gf.cx | 45 min |
| Migrate 4 programmatic renderers | 40 min (10 each) |
| Migrate 4-6 hand-written surfaces | 60-90 min |
| Document in web-assets/cards/README.md | 15 min |
| Total | ~3-4 hours |
Build trigger
Build when ANY: - Dan dedicates a focused session - Audrey first looks at pa.gf.cx and asks “why does this card look different from that one?” - Card grid pattern gets reused on a 6th surface (forcing the migration) - Adding a new portfolio surface (would otherwise spawn yet another card CSS variant)
Cross-references
feedback_xlab_co_toolkit_web_assets_home.md— primitive home rulefeedback_grayscale_thumb_hover_pattern.md— folds in as default thumb behaviorfeedback_media_sizing_primitive.md— same architecture pattern (one CSS, all surfaces)parked_sketch_d3_comparison_primitives_2026-05-24.md— sibling chart-primitive parkingfeedback_declarative_pages_for_infra_subdomains.md— landings would benefit from consistent card layout
The aphorism
The portfolio earns its visual coherence when the cards aren’t trying — they just are.