/ recent work / dnd-cards

DND Cards

Grimoire-bound campaign platform — cards for every NPC, spell, and location, lore graph, AI art, D&D Beyond import, card-native VTT, and a shared grimoire with dnd.chat.

DND Cards — preview
Year
2026
Role
Solo build
Status
live
Stack
  • Next.js 16
  • Supabase
  • Tailwind v4
  • PixiJS
  • OpenAI
  • Netlify

A grimoire-bound productivity portal for Dungeons & Dragons — every NPC, spell, item, and location becomes a card you can draw, arrange, link, and reveal at the table. We built it from scratch: boards, character sheets, compendium, lore graph, AI conjuring, and a card-native VTT that reads what’s on the card when combat starts.

The problem

Campaign prep lives in folders. Statblocks in one PDF, player sheets in D&D Beyond, initiative on a whiteboard, lore in a Google Doc nobody opens mid-session. Generic Kanban tools don’t understand DM-only lists, inline dice, or the moment you flip a card face-up for the party.

We wanted one surface where prep and play stay connected — same auth, same data, same card chrome from board to battlemap.

The approach

Everything is a card. NPCs, monsters, spells, items, locations, quests — each gets the Grimoire frame (3D tilt, portrait art, stat block on the back). Boards are Kanban with reveal controls, DM-only columns, and a Party tab that ties player cards to character sheets.

One database, two faces. Supabase holds auth, RLS, Realtime, and migrations. dnd.chat shares the same project — campaigns, characters, and members sync. Footer links to the tavern; handoff flows return imported PCs to chat with a safe redirect.

Assistive combat, not automation. The VTT layer (PixiJS battlemap at /board/play) derives action bars from 5e prose on the card. The engine suggests to-hit and damage; the DM can edit every field before committing. Combat log goes through a dedicated API so logged rolls match what actually resolved.

What we built

  • Boards & cards — drag-and-drop Kanban, list/card/glossary/table views, card links into a lore graph, map pins, consistency scans, what-if previews.
  • Character sheets — full /characters roster with builder, inventory, spell prep, system rolls panel, and grimoire-style AI portraits.
  • Imports — PDF shredder for sourcebooks; D&D Beyond monsters via pasted statblock or public URL; PCs via AcroForm PDF, bookmarklet, JSON drop, and a Chrome extension scaffold. Re-import diffing when content updates.
  • AI conjuring — prompt-to-card generation, batch column art via OpenAI, per-card regen, fill-gaps for missing fields.
  • Card-native VTT — scenes and tokens, measured 5ft grid, initiative rail, conditions, concentration, reactions, AoE placement, monster AI suggest/apply, player read-only collab view, session recap cards. GET /api/cards/:id/actions exports the same deriveActions engine dnd.chat uses for embed buttons.
  • Reference layer — SRD-aware compendium, Rules, Codex, Glossary, Materials — woven through every card.
  • Collab — live presence, shared cursors, board chat, Discord webhook bridge, share-token previews, gamification streaks, feature voting.
  • Marketing site — changelog, pricing, style guide, dynamic OG cards, hero carousel from pre-rendered Grimoire captures.

Trade-offs

We deferred fog of war and full player VTT views to the roadmap — the bet is cards-first combat that feels like the table, not racing Foundry feature-for-feature.

Character import creates board cards and sheet rows; spell and item extraction from Beyond exports is still expanding. Turbopack stays off production builds after flaky Netlify _next/static deploys — webpack is boring and shippable.

Pre-rendered hero card WebPs cost a regen step when the Grimoire chrome changes. They buy a marketing carousel without GPU compositing bugs from live 3D cards in the hero.

Recent shipping

  • Live combat: a real-time DM tracker and a combat-aware sheet strip, built on a new realtime spine and a /api/dm surface (Phase 1).
  • Cast-target autocomplete now reads the live combat state instead of stale localStorage.
  • Homebrew Forge: type-aware “Forged.” banners and a smarter in-wizard chooser for building your own cards.
  • Locked the house art style so AI-generated card art stays on-brand — user overrides can’t strip it.
  • GA4 plus the same geo-aware cookie consent we built for threesided.

Results

Live at dndcards.com. Netlify on main, Supabase migrations via linked CLI. The loop we care about: shred a PDF or import a Beyond sheet, arrange the board, drop tokens on the map, run initiative from the same deck — then hop to dnd.chat for rolls in-thread without a second login.

What’s ongoing

M3 VTT hardening (fog, movement polish), richer Beyond character extraction, Chrome extension store path, combat QA on live campaigns. Deploy when Adam says go — push to main triggers Netlify.

Recent shipping (May–June 2026)

  • dnd.chat handoff — in-board DDB import and character builder when return= is set; auto-create player cards after import; “Use in tavern” CTAs on the roster.
  • VTT combat depth — frightened LOS, expertise on saves, prone stand, Dash movement budget, skill-check chips, combat log flyout, wall blockers for line-of-sight.
  • Party & UI — consolidated board header, shared dense toolbar kit, unified card preview chrome across board, compendium, and sheet views.
  • Platform — feature_votes migration for roadmap voting, reaction RLS for dnd.chat, Turbopack build fix by decoupling PDF constants from server-only pdfjs.