Context Cards

Pinned delivery for the ctx-cards script and its term packs. The Worker proxies the repository at a tagged release rather than holding copies, so cutting a tag publishes it.

What it serves

ctx-cards reads schema.org DefinedTermSet markup from a page, scans the prose for those terms, and attaches contextual cards on hover or tap. This service delivers the script and its packs from a domain I control.

There is no separate publishing step. The Worker fetches from the repository at a pinned ref on a cold cache, so the repository stays the single source of truth and a release cannot drift from what is served.

URL shape

https://cdn.jakelabate.com/context-cards/<tag>/dist/ctx.min.js
https://cdn.jakelabate.com/context-cards/<tag>/packs/<pack>.json
https://cdn.jakelabate.com/context-cards/<tag>/sites/<site>.json

The script derives its pack URLs from its own src by swapping /dist/<file> for /packs, so a pinned script tag pins its packs to the same release automatically. Nothing extra to configure, and no way for a script and its data to end up on different versions.

The script tag

<script src="https://cdn.jakelabate.com/context-cards/v0.10.0/dist/ctx.min.js"
        integrity="sha384-..."
        crossorigin="anonymous"
        data-packs="seo-core"
        data-style="paper"
        defer></script>

Subresource integrity is worth using here and costs nothing. The bytes at a tag never change, so the hash never changes, and a browser will refuse the script outright rather than execute something unexpected. The current value lives at dist/ctx.min.js.sri in the repository.

What is deliberately restricted

Two limits matter more than the proxying itself.

  • Only dist/, packs/ and sites/ are reachable. Without a directory allowlist this would serve any file in the repository from my domain under a permissive CORS header.
  • A ref must be a vN.N.N tag or main. Without it, any commit in history would be addressable, which is an open proxy with extra steps.

Paths containing .. or characters outside [\w.\-/] are rejected separately. Tagged paths are immutable and cached for a year; main is allowed for testing with a five minute TTL and is not stored in the edge cache.

Releases

Tag the repository and the new version is live at the new path immediately, because tags resolve on first request. Old tags keep working indefinitely, which is what lets a page pin a version and not be moved off it by someone else's deploy.

Card kinds

Every card shares one shell, one tail, one entrance and one dismiss behaviour. Only the body changes, set by ctx.kind on the term. Cards below are captured from the rendered component, not redrawn.

The term card kind, showing a definition, an optional expansion, and a link out.
term A definition, an optional expansion, and a link out.
The verdict card kind, showing an adjudicated claim. The badge carries the ruling; the rows carry the evidence behind it.
verdict An adjudicated claim. The badge carries the ruling; the rows carry the evidence behind it.
The verdict card kind, showing the same shell, opposite ruling. A tool that can only render agreement is not adjudicating.
verdict The same shell, opposite ruling. A tool that can only render agreement is not adjudicating.
The entity card kind, showing a product, person or organization, with an avatar and meta rows.
entity A product, person or organization, with an avatar and meta rows.
The steps card kind, showing a numbered procedure.
steps A numbered procedure.
The compare card kind, showing two columns, for the distinction a definition alone would blur.
compare Two columns, for the distinction a definition alone would blur.
The code card kind, showing a snippet with a caption. This one shows the markup the card itself was built from.
code A snippet with a caption. This one shows the markup the card itself was built from.
The quote card kind, showing a cited passage with attribution.
quote A cited passage with attribution.

Charts

Any kind can carry ctx.chart. These are sparklines rather than charts: no axes, no tooltips, nothing to interrogate. A card that disappears on mouse-out is the wrong container for a number that needs studying, so when one does, the card's job is to link out to it.

A line sparkline inside a stat card, showing a trend over continuous time.
line A trend over continuous time.
A bars sparkline inside a stat card, showing discrete periods.
bars Discrete periods.
A ring sparkline inside a stat card, showing one percentage of a whole.
ring One percentage of a whole.
A progress sparkline inside a stat card, showing completion against a target.
progress Completion against a target.
A share sparkline inside a stat card, showing composition, stacked to 100%.
share Composition, stacked to 100%.
A hbars sparkline inside a stat card, showing a ranked comparison.
hbars A ranked comparison.
A range sparkline inside a stat card, showing a position between two bounds.
range A position between two bounds.
A winloss sparkline inside a stat card, showing pass and fail runs.
winloss Pass and fail runs.

Live on this page

This page loads ctx-cards from the endpoint it documents. The terms below are marked in the prose above and throughout this page. Hover one on a desktop, or tap it on a phone, and the card is rendered from the DefinedTermSet markup in this page's own head.

  • DefinedTermSet, the schema.org type the script reads.
  • subresource integrity, the hash that pins the bytes.
  • immutable, the caching guarantee a tagged path makes.
  • edge cache, where a tagged response lives after the first request.
  • CORS, the header that decides who may read the response.

Nothing is sent anywhere to make that work. The script reads the markup already in the document, scans the prose in the browser, and no page text leaves the page. The only network requests it makes are for the script itself and any term packs, both from this CDN.

Source

The script and the delivery Worker live in the same repository, which is what keeps a release and the thing serving it from drifting apart.

Context Where Your Readers Need It

Contextual definition cards driven by the structured data already on your page. Open source, no page text leaves the browser.