Commit 8029cf9
cards demo: share a card as a link whose preview is the card (#1016)
## What changed
The cards playground gets a Share panel. The card parks in a frame on
the stage, renders to a still in the browser, and gets a link at
`cards.lightspark.com/c/{slug}` whose preview is that card.
- Share panel, in the stage under the card: Copy link, Share on X (opens
the composer with the link), Save image, Save video (a five second spin,
encoded in the browser with WebCodecs).
- Style row: Template (the card on the Figma share template, with a dot
grid in the middle column) or Hand (the card in one of five photographed
hands; a Skin row picks). Backdrops: Light, Dark, Brand (the card's
color, or the dominant color of its art), or a custom color.
- Share page at `/c/{slug}`: a live 3D card the visitor can turn, with
**Design yours** and **View in Playground** going to
`docs.lightspark.com/cards/demo`. Crawlers get `og:image` pointing at
the rendered still (2400 x 1256), and the title `{Brand} Card —
Lightspark Cards Playground`.
- Storage: Vercel Blob for the stills, video, and uploaded logo and art;
Upstash Redis for the records. Both already connected to the
`grid-cards-demo` project with per-environment prefixes
(`cards/preview/...`, `cards/production/...`). Locally the store is the
filesystem (`.shares/`, gitignored).
- API routes under `/api/shares`: create, get, patch (with an edit
token), file upload, view count, slug check. Rate limits per IP: 40
creates and 400 uploads per hour. Uploads are capped at 4 MB per file,
enforced while the body streams; JSON bodies at 64 KB. Uploaded rasters
are downscaled to 2048 px and re-encoded as WebP on the client before
upload.
- A share stores only image URLs of its own (root-relative presets, or
files in this deployment's Blob store); anything else is dropped. Assets
are set only by the upload route.
- `cards.lightspark.com/` redirects to `docs.lightspark.com/cards/demo`
(the iframe's `?embed=true` load is exempt).
- Card numbers, expiry, and CVV are generated on each issue (Luhn-valid
Visa PAN) instead of hardcoded.
- Docs embed snippet: the iframe passes `c` and `edit` through from the
docs page URL, and `allow` gains `web-share`.
Dot grid lattice math moved to `src/lib/dotLattice.ts`, shared by the
stage backdrop and the share template.
## Infra state
- `cards.lightspark.com` CNAME added by PE
([ops#4134](https://github.com/lightsparkdev/ops/pull/4134)), attached
to the `grid-cards-demo` Vercel project, certificate issued.
- Production env:
`NEXT_PUBLIC_SHARE_ORIGIN=https://cards.lightspark.com/c`. Preview
deployments link to their own host and to the matching Mintlify preview.
## Test plan
- `node scripts/share-smoke.mjs chromium|webkit <url>` against the
branch's Vercel preview: both pass (template and hand alignment, five
hand swaps, backdrops, custom color drag, poses, Save image download,
Save video start and cancel, Copy link creating a share, a flow
dismissing the panel).
- Created a share on the preview: `POST /api/shares` and both file
uploads returned 200, the files landed under `cards/preview/`, the
crawler view of `/c/{slug}` carries the correct `og:*` and `twitter:*`
tags, and the `og:image` on Blob is 2400 x 1256 WebP.
- Share page loaded on desktop Chromium and mobile WebKit with no
console errors; both buttons resolve to the docs URL with `?c={slug}`.
- Bugbot ran on the branch earlier; findings addressed. Greptile's three
findings (partial updates, late upload cap, external image URLs) fixed
in 57c579c and verified locally with curl: 413 on a 9 MB declared
length and on a streamed 5 MB body; external and data: image URLs nulled
on create and patch; an update issues GET, uploads, then PATCH last.
- Docs preview
(`ramps-pat-cards-export-share.mintlify.site/cards/demo?c=…`) loads the
shared design in the iframe (brand and color restored).
- After merge: confirm the `/` redirect on `cards.lightspark.com`,
create a share from `docs.lightspark.com/cards/demo`, and post it to X
to see the card.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>1 parent b67647e commit 8029cf9
73 files changed
Lines changed: 7237 additions & 142 deletions
File tree
- components/grid-cards-demo
- scripts
- src
- apps
- card
- app
- api
- team
- components
- AppPanel
- CardStage
- card3d
- export
- DesignPicker
- glass-gl
- data
- hooks
- lib
- mintlify/snippets/cards
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
| 16 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
33 | 47 | | |
34 | 48 | | |
35 | 49 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
22 | 35 | | |
23 | 36 | | |
24 | 37 | | |
| |||
0 commit comments