shareables
Field Guide
what they are · how we brand them · how to publish

A small, private collection of self-contained web pages — plans, reports, explainers — that you hand to someone (or their agent) as a single link. Branded, visual, and live in one command.

Contents   ① What they are · ② Branding & the logo · ③ Graphs & visuals · ④ Notes over time · ⑤ Make it live · ⚡ Real-time · ⑥ Private, not walled · ⑦ Get it for yourself

① What a shareable is

One folder, one HTML file, one URL — served from a single static site, grouped by project.

Every shareable is a self-contained HTML page (its CSS, SVG, and logic inline; diagrams pulled from a CDN). There's no build step and no framework — which means it renders the same on anyone's machine, years from now, with nothing to install. Pages live at:

https://shareables.yahyatarique.dev/<project>/<slug>

They're grouped by project on the homepage (LetsGetVisa, Voxforce, Personal…), each with a searchable, auto-generated index. The page you're reading is itself a shareable in the Shareables project.

How it's wired

flowchart LR A["✍️ HTML in
~/.claude/scratchpad/"] --> P{{"publish.mjs"}} P --> M["📁 git mirror
.shareables/"] M -->|"git push"| V["▲ Vercel
(auto-deploy)"] V --> U["🔗 live URL
/<project>/<slug>"] P -. "builds" .-> IDX["index + OG cards"] IDX --> M
📁 the mirror is a real git repo — a push is the deploy 🔁 re-publishing the same slug updates the same link

② Branding & the logo

Two layers of brand: the site identity (this page), and each project's identity (its pages).

The shareables mark

The coaster-stack logo in the header — three stacked rounded cards with a “share” node-and-edges glyph — is the site's own identity. It's the favicon, the homepage mark, and the badge on every OG preview card. Gold gradient #F4A261 → #C1804D on dark navy #0b1120.

inline SVG → crisp at any size, no asset to load

Per-project branding

A page about a product wears that product's brand — its logo, its colours, its header. We detect the project's identity from its codebase (logo files, theme variables) and theme the header, accents, and even the diagrams to match.

The shortcut: copy the <head>/<style> + header from a sibling page already in that project and swap the content. E.g. LetsGetVisa pages share a navy #1B365D + gold palette.

Opt-in project logos (index + command bar)

Projects can register a logo in shareables.json under projects. Opt-in only — unregistered projects show initials on a tinted chip.

Use logo (SVG path) or emoji (single emoji character) — emoji wins if both are set. Logo/emoji icons render without a background box; initials fallback keeps the tinted chip.

{
  "projects": {
    "LetsGetVisa": { "logo": "logo.svg", "accent": "#F4A261" },
    "PPTBuilder":  { "emoji": "📑", "accent": "#F4A261" }
  },
  "items": [ … ]
}

Logo SVGs live at projects/<project-slug>/logo.svg. Run node build-index.cjs — icons appear on homepage headers, project breadcrumbs, and command-bar results (bare, no tile background).

Why self-contained? Inline CSS & SVG mean the brand travels with the file. There's no stylesheet to 404, no CDN font to vanish, no build to reproduce — the page looks right the day you ship it and the day someone opens it much later.

③ Graphs & anything visual

Diagrams via Mermaid (drawn in-page from a CDN), and data as hand-rolled inline SVG when a picture beats a paragraph.

Mermaid — architecture, sequences, flows

Include the Mermaid CDN once and write diagrams as text; they render on load, themed to the brand. The wiring diagram above is one. Here's the publish pipeline as a sequence:

sequenceDiagram participant You participant Pub as publish.mjs participant OG as generate-og.mjs participant Git participant Vercel You->>Pub: --file page.html --project --title --desc Pub->>Pub: copy in + upsert manifest + build index Pub->>OG: render card + inject og:auto meta OG-->>Pub: og image (project/slug.png) Pub->>Git: commit + push Git->>Vercel: webhook → deploy Vercel-->>You: ✅ live URL (verified 200)

Data — inline SVG charts

For real numbers, a small inline SVG bar chart drops straight in. This one is live data: pages currently published per project.

7LetsGetVisa 4baddie-one 3PPTBuilder 2Voxforce 1NetraAI 1Personal

No chart library — just rectangles and text. Update the heights, keep the file self-contained.

Other visual building blocks we use
Collapsible <details> sections (like this), copy-to-clipboard buttons, status pills (REQUIRED OPTIONAL), the timeline below, and persisted task checkboxes via localStorage. Anything that helps the reader skim — as long as it stays inline.

④ Notes over time

Each page carries a real last-updated stamp, and a page can show its own history inline.

The manifest stores an updated field per page, and the homepage cards show each page's real date/time (from the file's mtime) — so the collection reads as a living log, newest first. Inside a page, a simple timeline captures how the thing it documents evolved. Here's the shareables system's own:

⌨ Keyboard navigation

On the catalog (homepage and project listings) when logged in, and on leaf pages after login. Press ? anytime for the cheatsheet. Anonymous visitors on a public share link get the page only — no command bar or prev/next.

Command bar (⌘K / /)

Spotlight-style palette: fuzzy search over pages and projects, quick actions, and your last eight picks (pages, project listings, home, and actions — stored in localStorage). Results rank by recency when the query is empty; typing filters live. A context strip shows where you are (catalog, project, or current page).

KeyIn the command bar
↑ ↓Move selection
↵Open selection (same tab)
⌘⇧CCopy link for the selected page or project
EscClose and clear the grid filter on index pages

Scoped search: prefix the query to narrow results — lgv: / ppt: / vf: (project pages), > (actions only, e.g. > home or > theme), @ (projects only). On leaf pages, actions include Copy link to this page, go home, project index, and prev/next when the catalog is available.

Actions also include Toggle appearance (light/dark catalog theme; same preference as the header button on index pages). When you have recent visits, Clear recent history appears under Actions. On index pages, search also filters the card grid behind the palette.

Catalog & leaf shortcuts

KeyIndex (homepage / project)Leaf page (logged in)
j ↓Next cardNext page in project
k ↑Previous cardPrevious page in project
EnterOpen focused card—
⌘K /Command bar — search pages & projectsCommand bar — search, home, prev/next, copy link
[ ]—Prev / next (same as k / j)
h—Home
b—Project index
EscClose command bar / clear focus / close helpClose command bar / close help
?Shortcuts cheatsheet

Cards show the same OG image as link previews (lazy-loaded, browser-cached). Once loaded, the title hides — the image carries it — and only the page slug chip remains (project context is in the section header). Overlay UI (command bar, leaf nav bar, help sheet) mounts in an isolated shadow root so leaf-page CSS cannot break it. The searchable catalog and prev/next require login — public and private share links stay open to anyone with the URL; logged-in users get the full nav via a session check.

⑤ Make it live — one command

Write the HTML in your scratchpad, then publish. The command does everything and prints the live URL.

node ~/.claude/scratchpad/.shareables/scripts/publish.mjs \
  --file    ~/.claude/scratchpad/<page>.html \
  --project "LetsGetVisa" \
  --title   "Human Title" \
  --desc    "One-line summary for the card + link preview."
FlagMeaning
--fileREQUIREDPath to the self-contained HTML.
--projectREQUIREDGroups the page on the homepage. Never inferred — so a page can't land in the wrong group.
--titleREQUIREDShown on the card and the link preview.
--descOPTIONALOne-line summary for the card + OG description.
--slugOPTIONALURL name; defaults to the filename. Reuse the same slug to update the same link.
--privateOPTIONALRequire login to view this page (--public clears it).
--liveOPTIONALEnable the live KV store (votes/flags/counters) for this page (--static clears it).
--dry-runOPTIONALRun every local step but stop before commit/push — preview what would change.
Even easier from an agent: just say “share this” or “publish this to shareables.” The shareables skill knows this whole workflow — including not to hand-write OG meta (the generator owns it) and to ask which project if it's ambiguous.
What runs under the one command
copy into <project>/<slug>/index.html → upsert shareables.json → build-index.js (homepage + project listings) → generate-og.mjs (card + meta) → git commit + push (Vercel deploys) → poll the URL and print ✅ Live. OG images are not generated on deploy, which is exactly why the publish step runs the generator for you.

⚡ Real-time interactivity

Pages are static by default — but any page can opt into a shared key-value store for votes, flags, reactions, counters, RSVPs, or polls that update live across visitors.

The store is a Vercel Edge function (api/flags.js) backed by Upstash KV. Each live page gets a namespace of itemId → { count, mine, voters:[{ name, ts, loc }] }; a voter is keyed by sha256(email) of the signed-in account so a click toggles instead of double-counting, and coarse IP geo is captured at the edge (works on Vercel's free Hobby plan). Actions require a signed-in account (admin or a self-serve visitor account) — no anonymous voting.

① Mark the page live

Publish with --live (or set "live": true on its shareables.json entry). build-index.cjs compiles every live page into lib/live-pages.js — the store's write allowlist, so the KV stays scoped and clean. The pageId is <projectSlug>-<slug>.

② Drop in the client

lib/live-kv.js handles fetch, identity (whoami), polling, toggling, and the onAuthRequired redirect to /login. Needs Upstash env vars (KV_REST_API_URL, KV_REST_API_TOKEN) plus SHAREABLES_SESSION_SECRET for accounts — without KV the endpoint returns 501 and the rest of the site is unaffected.

import { createLiveStore } from "/lib/live-kv.js";
const store = createLiveStore({ page: "voxforce-account-triage",
  onAuthRequired: () => location.href = store.loginUrl() });   // send to /login on 401
const me = await store.whoami();              // { loggedIn, role, name, email } | null
store.subscribe((flags) => render(flags));      // live updates (polls every 8s)
await store.toggle("item-1");                 // flag/unflag for the signed-in account

The Account Triage tool is a live page built this way — masked emails, sign-in-to-vote, and a tally that updates as teammates vote. get / flag / unflag / toggle / subscribe / whoami / loginUrl are the whole API. Voters sign in with an admin or self-serve visitor account; IPs and emails are recorded server-side but never returned to clients.

⑥ Private, not walled off

These are private share links — not secret, but not meant to surface in search. So we keep them out of search-engine results with a X-Robots-Tag: noindex, noarchive header, and that's it.

We deliberately don't block crawlers or AI bots. The whole point is that you hand a teammate a link and their tools — including their coding agents — can open and read the doc. No-index, not no-access.

⑦ Get this system for yourself

Like it? Stand up your own — branded pages, OG previews, one-command publish — on your own domain in about ten minutes.

Get it for yourself → ⬇ Download starter kit (.zip)

The setup page has harness tabs for Cursor and Claude Code (/publish + skill), plus a step-by-step walkthrough (Vercel + git). The kit is genericized — your domain swapped for a placeholder, so it's yours to brand.