diff --git a/.claude/handoffs/2026-05-19-181448-duplicate-chess-landing-card.md b/.claude/handoffs/2026-05-19-181448-duplicate-chess-landing-card.md
new file mode 100644
index 0000000..064b0d3
--- /dev/null
+++ b/.claude/handoffs/2026-05-19-181448-duplicate-chess-landing-card.md
@@ -0,0 +1,135 @@
+# Handoff: 3rd landing card linking to duplicate-chess (deployed)
+
+## Session Metadata
+- Created: 2026-05-19 18:14:48
+- Project: /home/claude/bin/blind_chess
+- Branch: main (commits pushed)
+- Session duration: ~30 minutes; the bulk of this session's substantive work
+ happened in the sibling `duplicate_chess` repo — see that repo's handoff for
+ the full deploy story.
+
+### Recent Commits (for context)
+- `33a7cef` docs: record duplicate-chess sub-app sharing the chess.sethpc.xyz origin
+- `fef6dcf` feat(client): third landing card linking to duplicate chess
+- `d95ab2a` docs: refresh handoff — promotion fix shipped, both fixes deployed
+- `c01244c` fix: promotion dialog only fires for genuine pawn promotions
+
+## Handoff Chain
+
+- **Continues from**: [2026-05-18-205736-table-fidelity-features.md](./2026-05-18-205736-table-fidelity-features.md)
+ — that handoff's state is otherwise still current; the manual browser test
+ pass on the table-fidelity batch is still pending.
+- **Cross-repo companion**: `~/bin/duplicate_chess/.claude/handoffs/2026-05-19-181212-deployed-as-chess-sethpc-xyz-duplicate.md`
+ — the full story of the deploy lives there.
+
+## Current State Summary
+
+The blind_chess landing now shows a 3rd card — "Duplicate Chess (under
+development)" — that links to `/duplicate/`. The page-level deploy on
+`chess.sethpc.xyz` is live and verified: the served bundle contains the new
+strings ("Duplicate Chess", "under development", "/duplicate/") and CSS classes
+(`.card-link`, `.badge`, `.open-cue`); curling `/duplicate/` returns the
+duplicate_chess static index from a separate `handle_path` block in the same
+Caddy site. blind_chess's server was restarted (1 in-memory game dropped per
+the pre-accepted MVP policy).
+
+State of blind_chess proper is otherwise unchanged from the table-fidelity
+handoff — the same open items (manual browser test pass, board phantom glyph
+contrast eyeball) apply.
+
+## Architecture Overview
+
+The `chess.sethpc.xyz` Caddy block on CT 600 now routes:
+
+- `/duplicate/*` → static `/var/www/duplicate-chess/` (`handle_path` strips
+ the prefix; Vite was built with `base: '/duplicate/'`).
+- Everything else → reverse_proxy to CT 690:3000 (blind_chess Fastify, as
+ before).
+
+This means duplicate_chess deploys never restart blind_chess. The blind_chess
+client just contains a link to `/duplicate/` — no SPA-level integration.
+
+## Critical Files
+
+| File | Purpose | Relevance |
+|------|---------|-----------|
+| `packages/client/src/lib/Landing.svelte` | 3rd card + `.card-link`, `.badge`, `.open-cue` CSS | The visible entry point |
+| `CLAUDE.md` (deploy line) | Notes the `/duplicate/*` Caddy block | Resume reference |
+| Caddy on CT 600 (`/etc/caddy/Caddyfile` lines ~1112–1124) | `handle_path /duplicate/*` sub-block | Backup at `/etc/caddy/Caddyfile.bak.duplicate-chess-1779228542` |
+
+## Files Modified
+
+- `packages/client/src/lib/Landing.svelte` — added a 3rd `` card under the existing two cards (friend/AI). New CSS for the link-shaped card, the "under development" pill badge, and the `Open →` cue.
+- `CLAUDE.md` — Deploy bullet extended with one sentence about the `/duplicate/*` handler.
+
+## Decisions Made
+
+| Decision | Why |
+|----------|-----|
+| 3rd card as a plain ``, not an SPA-internal route | Honest about the architecture: duplicate is a separate static app behind a Caddy `handle_path`, not a route within blind_chess. Plain anchor survives any future static-fallback rewriting. |
+| Visibly tagged "under development" | Sets Andrew's (the inventor's) expectations that duplicate isn't at parity with blind/vanilla. |
+| Drop the 1 active in-memory game on restart | Acceptable per pre-existing MVP policy in DECISIONS.md. |
+
+## Immediate Next Steps
+
+1. **The table-fidelity manual browser test pass is still pending** (from the
+ prior handoff — Step 1 there). Now an even bigger reason to do it: Andrew
+ will be looking at the landing and seeing 3 cards; if the layout breaks at
+ a phone width or the card looks broken, fix it before he tests duplicate.
+2. **Visually verify the new 3rd card** in a real browser at
+ https://chess.sethpc.xyz/ — colours, badge contrast, hover state, mobile
+ layout. Only confirmed via curl + JS/CSS string grep so far.
+3. **Decide whether chess.local should also serve duplicate.** Currently the
+ LAN-only VDJ-RIG instance is on the previous blind_chess client (no 3rd
+ card) and has no `/duplicate/*` handler. If Seth wants LAN parity, redeploy
+ blind_chess client there AND copy duplicate's dist to the rig with a Caddy
+ block of its own.
+
+## Important Context
+
+- **The bulk of the work is in `duplicate_chess`**, not here. See its handoff
+ for the deploy details (Vite base, Caddy `handle_path`, `tar`-pipe transfer,
+ Caddyfile backup name).
+- **`fef6dcf` + `33a7cef` are the only two commits this session in blind_chess.**
+ Everything else (vite.config, page title, CLAUDE.md, DECISIONS.md, handoff)
+ is in `duplicate_chess`.
+- **The table-fidelity batch state in the prior handoff is unchanged.** The
+ manual browser test pass is still in progress. The deploy on CT 690 is now
+ at the new commit `fef6dcf` (client only — server code is byte-identical
+ to `c01244c`).
+
+## Potential Gotchas
+
+- **The blind_chess server WAS restarted** even though server code didn't
+ change (Fastify-static reads `STATIC_DIR` at startup, so the new
+ `index.html` + bundle hashes only get picked up after a service restart).
+ Took uptime back to 0; the 1 in-memory game at restart was dropped.
+- **The Caddyfile edit was on CT 600 only.** chess.local on VDJ-RIG was not
+ touched and has no `/duplicate/*` route.
+
+## Assumptions Made
+
+- That "incorporate as a 3rd game mode 'under development'" meant a 3rd
+ top-level landing card (the existing "mode" was a radio inside each card
+ for Blind/Vanilla, but duplicate is 4-player so it can't fit that radio).
+- That a plain link out to `/duplicate/` was the right level of integration
+ (vs iframe or source merge).
+
+## Environment State
+
+- `caddy.service` on CT 600 — reloaded.
+- `blind-chess.service` on CT 690 — restarted (1 in-memory game dropped).
+- chess.local on VDJ-RIG — not touched.
+- No dev servers running locally.
+
+## Related Resources
+
+- Cross-repo companion handoff: `~/bin/duplicate_chess/.claude/handoffs/2026-05-19-181212-deployed-as-chess-sethpc-xyz-duplicate.md`
+- Live URLs:
+ - https://chess.sethpc.xyz/ — blind_chess landing (3rd card visible).
+ - https://chess.sethpc.xyz/duplicate/ — duplicate_chess sandbox.
+ - https://chess.sethpc.xyz/api/health — blind_chess API health.
+
+---
+
+**Security Reminder**: No credentials or secrets in this handoff.