Portfolio web primitives
Portable frontend components for the gf.cx portfolio's properties (home.gf.cx · dare.co.uk · audreyinc.com · dogwood.house) — across domains, not just gf.cx. Lift once, import everywhere — no inline-duplication across properties.
→ Live inventory with examples: assets.gf.cx/inventory — every primitive rendered live with imports, demos, and pattern-library cross-references.
Available primitives
dropzone · v0.1.0
Drag-and-drop file capture with localStorage persistence + JSON export. Pure client-side; no server roundtrip.
<link rel="stylesheet" href="https://assets.gf.cx/dropzone/dropzone.css"><script src="https://assets.gf.cx/dropzone/dropzone.js" defer></script>
media · v0.1.0
Portfolio-wide sizing defaults for inline <video> / <img> / <audio> inside article. One place to tune the visual proportion across every surface.
<link rel="stylesheet" href="https://assets.gf.cx/media/media.css">
cards · v0.1.0
Three card variants (--system, --stat, --tile) + .card-grid layout. Replaces hand-rolled .system / .stat / .cell CSS across portfolio surfaces with one canonical primitive. Grayscale-thumb-to-color hover baked in. CSS-custom-property theming.
<link rel="stylesheet" href="https://assets.gf.cx/cards/cards.css">
status-pill · v0.1.0
Lifecycle-state badge (--neutral, --alert, --resolved, --service) that sits under a record title. Optionally driven from one JSON state-vocabulary — add a state once, not per row. Themed from the active design-system palette; the demo page carries a live colour swatch reference.
<link rel="stylesheet" href="https://assets.gf.cx/status-pill/status-pill.css"><script src="https://assets.gf.cx/status-pill/status-pill.js" defer></script>
made-with · v0.1.0
The shared "Built with — how this page ships" provenance footer, rendered from a placeholder. One import, the wording + styling live in one file — change it once and every page across the portfolio updates. Ends hand-copied-footer drift (the favicon-control-plane model applied to provenance).
<script src="https://assets.gf.cx/made-with/made-with.js" defer></script>
nav · v0.1.0
Shared cross-surface header breadcrumb that links the connected gf.cx surfaces together. Destinations live in one ITEMS array — change them here, every surface updates. Drop the placeholder as the first child of the content wrapper; data-current orients the reader (both destinations always render as links).
<div data-site-nav data-current="status"></div><script src="https://assets.gf.cx/nav/nav.js" defer></script>
back-to-top · v0.1.0
A neat ↑ top jump affordance, injected at the bottom (above the made-with footer when one is present). Self-injecting: shows only on long pages at runtime (≥ 2.2× viewport & ≥ 1400px), so it's safe to drop into every page. No markup, no per-page CSS — themes off local CSS vars.
<script src="https://assets.gf.cx/back-to-top/back-to-top.js" defer></script>
modal · v0.1.0
A thumbnail that earns a click opens one shared enlargement modal (lightbox) — image or inline <svg> — with a caption, closable by ×, backdrop, or Escape. The overlay DOM injects itself on demand, so there's no per-page markup to paste; mark a thumbnail data-modal and it's keyboard-native. Themes off local CSS vars. Lifted from the bespoke modal on srvc.gf.cx/transit/.
<link rel="stylesheet" href="https://assets.gf.cx/modal/modal.css"><script src="https://assets.gf.cx/modal/modal.js" defer></script>
map-dossier · v0.1.0
The "good-map" pattern for placing a facility in a location dossier — a three-beat sequence: aerial → close-up hover → street-view. Three composable primitives: .rollimg (mouse-over reveal — for maps, start on the close-up and hover out to the wider context), .svfacade (click-to-load embed facade — defer the third-party until intent), and .embed3d (always-on inline embed when the embed is the point). The hover image must be the exact pixel dimensions of the base so the overlay lands pixel-perfect. Themes off local CSS vars. Lifted from srvc.gf.cx/transit/.
<link rel="stylesheet" href="https://assets.gf.cx/map-dossier/map-dossier.css"><script src="https://assets.gf.cx/map-dossier/map-dossier.js" defer></script>
Live demo · map-dossier
hover · zoom out
Live demo · modal
Live demo · dropzone
Architecture
Source lives at xlab-nyc/toolkit. Deployed to Cloudflare Pages project assets-gf-cx on push to main (or via wrangler pages deploy). Custom domain assets.gf.cx bound at CF zone level.
Portfolio surfaces import via CDN URL (https://assets.gf.cx/<primitive>/<file>) — cross-origin JS/CSS load, no CORS required for static assets. Cached at CF edge.
Coming primitives
- date-counter — runtime widget showing relative ("116d left") + absolute ("Aug 8 2026") for any data-attributed date
- signal-bar — 6-axis weighted score bar lifted from contractor records
- master-toggle — binary collapse-all/expand-all generator for any container of
<details> - grayscale-thumb — CSS-only hover-to-color pattern
Build trigger for each: first concrete portfolio use.