A modern web application for designing and printing custom playing cards with rich text descriptions, image support, and professional PDF export.
π Launch Application
- Rich Text Editor: Format card descriptions with bold, italic, strikethrough, and lists using TipTap
- Image Upload: Add custom images to card centers
- Title & Description: Fully customizable card content
- Live Preview: See your changes in real-time
- Multi-Card Decks: Create and manage collections of cards
- Quantity Control: Set print quantities for each card individually
- Grid View: Visual overview of your entire deck
- Hybrid Storage: Decks are saved using
localStorage, while large assets (images) are efficiently managed in IndexedDB for high performance and scalability.
- Google Drive Integration: Sync your entire library across devices using your private Google Drive storage.
- Bidirectional Sync: Automatically detects changes in the cloud and keeps your local library up to date.
- Atomic Image Storage: Images are stored as separate binary assets (blobs) rather than embedded in JSON, optimizing sync speed and memory usage.
- Conflict Resolution: Smart SHA-256 hash-based comparison avoids unnecessary prompts, while genuine conflicts are handled through a clean visual interface.
- Background Migration: Seamlessly upgrades legacy decks with embedded Base64 images to the new optimized storage format.
- Toast Notifications: Non-intrusive, real-time feedback for sync status, uploads, and system events.
- Responsive Animations: Fluid transitions and micro-interactions powered by
framer-motion. - Dark Mode: Fully supports modern dark mode with curated color palettes.
- Multi-Page Layout: Automatically generates 3x3 grid layouts (9 cards per A4 page)
- Cut Lines: Dashed guides for easy physical cutting
- High Quality: SVG-based rendering using
html-to-imagefor accurate layouts - Batch Export: Export entire decks with custom quantities in one click
- PDF Export: Multi-page, print-ready PDFs with cut lines
- SVG Export: Individual cards as scalable vector graphics
- Template Synchronization: Load standard SVG files as card templates. The application automatically detects and maps elements.
- Visual Sync: Position, rotation, scale, opacity, fonts, and colors of SVG elements are faithfully rendered in the Card Editor.
- Bi-directional Editing: Changes made in the Style Editor (e.g., moving a title or changing a font) are written back to the SVG upon export.
- Reference Mapping: Use
data-refattributes in your SVGs (e.g.,data-ref="title") to explicitly link graphical elements to card properties. These references are displayed in the editor for easy debugging.
- Node.js 18+
- npm or yarn
π For detailed setup instructions, see docs/SETUP.md
We provide automated scripts to simplify the setup process:
# Install dependencies
npm install
# Set up local environment (interactive)
npm run setup:local-env
# Set up Google Cloud resources (requires gcloud CLI)
npm run setup:cloud-env
# Configure GitHub Actions secrets (requires gh CLI)
npm run setup:github-secrets
# Start development server
npm run devIf you prefer manual setup or need more control:
-
Copy environment files:
cp apps/backend/.env.example apps/backend/.env cp apps/web/.env.example apps/web/.env
-
Configure credentials:
- See docs/SETUP.md for detailed instructions on obtaining:
- Google Cloud credentials (OAuth, API keys, service account)
- Stripe credentials (optional, for premium features)
- GitHub Actions secrets (for deployment)
- See docs/SETUP.md for detailed instructions on obtaining:
-
Start development:
npm run dev
The application will be available at http://localhost:5173/
For troubleshooting and detailed configuration options, refer to the complete setup guide.
To enable cloud synchronization, you must configure a Google OAuth Client ID:
- Go to the Google Cloud Console.
- Create a Project (e.g., "CardCraftStudio").
- Go to APIs & Services > Library and search for "Google Drive API". Click Enable.
- Go to APIs & Services > OAuth consent screen:
- Select External.
- Fill in the required App Information (App name, support email, developer email).
- Add the scope:
.../auth/drive.file(View and manage Google Drive files and folders that you have opened or created with this app).
- Go to APIs & Services > Credentials:
- Click Create Credentials > OAuth client ID.
- Select Web application as the type.
- Under Authorized JavaScript origins, add:
https://gnuton.github.iohttp://localhost:5173(for local development)
- Click Create and copy your Client ID.
For local use with full synchronization features, you need to configure both the frontend and backend environment variables.
Create a .env file in apps/backend/ (see .env.example):
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:5173/CardCraftStudio/oauth-callback.html
TOKEN_ENCRYPTION_KEY=a-random-32-char-stringCreate a .env file in apps/web/ (see .env.example):
VITE_GOOGLE_CLIENT_ID=your-client-id
VITE_API_BASE_URL=http://localhost:3001To inject credentials into your production environment, add the following secrets in GitHub (Settings > Secrets and variables > Actions):
| Secret Name | Description |
|---|---|
GCP_PROJECT_ID |
Your Google Cloud Project ID |
WIF_PROVIDER |
Workload Identity Federation Provider ID |
WIF_SERVICE_ACCOUNT |
Service Account email for Workload Identity |
GOOGLE_API_KEY |
Google API Key for Custom Search |
GOOGLE_CUSTOM_SEARCH_CX |
Google Custom Search Engine ID |
GOOGLE_CLIENT_ID |
Google OAuth Client ID |
GOOGLE_CLIENT_SECRET |
Google OAuth Client Secret |
TOKEN_ENCRYPTION_KEY |
A random 32-character string (for encrypting refresh tokens) |
JWT_SECRET |
A random string (for signing authentication tokens) |
STRIPE_SECRET_KEY |
Stripe Secret Key (for premium features) |
STRIPE_WEBHOOK_SECRET |
Stripe Webhook Signing Secret |
The CI/CD pipeline will automatically use these to provision infrastructure via Terraform and configure the Cloud Run backend.
- Start the App: Run
npm run devand openhttp://localhost:5173/ - Add a Card: Click "Add New Card" in the Deck Studio
- Design Your Card:
- Enter a title
- Add a description using the rich text editor
- Upload an image (optional)
- Save: Click "Save to Deck" to add it to your collection
- Set Quantities: In the Deck Studio, use the "Qty" input to set how many copies of each card to print
- Download: Click "Download PDF" to generate a multi-page PDF with all cards
- Print: The PDF includes cut lines for easy physical card creation
- Edit a Card: Click the edit icon on any card in the Deck Studio
- Export SVG: Click "Export SVG" to download the card as a scalable vector graphic
/
βββ apps/
β βββ web/ # Frontend Application (@cardcraft/web)
β β βββ src/
β β β βββ components/ # React components
β β β βββ services/ # Drive & Image services
β β β βββ App.tsx
β β βββ public/
β β βββ package.json
β β
β βββ backend/ # Backend Application (@cardcraft/backend)
β βββ src/
β βββ package.json
β
βββ package.json # Root workspace config
βββ .github/workflows/ # CI/CD pipelines
- React 18 - UI framework
- TypeScript - Type safety
- Vite - Build tool and dev server
- TailwindCSS - Styling
- Dexie.js - IndexedDB wrapper for local image storage
- Framer Motion - Smooth UI animations
- TipTap - Rich text editing
- html-to-image - SVG/Image generation
- jsPDF - PDF creation
- Lucide React - Icons
- Vitest - Unit testing
We use Vitest for both frontend and backend testing. You can run tests from the root or within specific workspaces.
# Run tests for both frontend and backend
npm test --workspacescd apps/backend
# Run all backend tests
npm test
# Run specific suites
npm test admin # Admin routes & logic
npm test impersonation # Impersonation flowscd apps/web
# Run all frontend tests
npm test
# Run component tests
npm test ImpersonationBannernpm test -- --coverage# Create production build
npm run build
# Preview production build
npm run preview- Dimensions: Poker-sized cards (2.5" Γ 3.5" / 63.5mm Γ 88.9mm)
- Layout: 3Γ3 grid per A4 page
- Border: 1px black border (standardized)
- Format: A4 (210mm Γ 297mm)
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
The project includes comprehensive unit tests for critical functionality:
- β Card rendering & Deck management
- β Google Drive Sync & Conflict Resolution
- β Admin Role Management: User bootstrap, grant/revoke privileges, audit logging
- β User Impersonation: Secure session start/exit, token validation, UI banner
- β PDF generation & User interactions
Run npm test --workspaces to execute the full test suite.
Copyright (c) 2026 Antonio 'GNUton' Aloisio
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- Built with Vite
- Styled with TailwindCSS
- Icons by Lucide
- Rich text editing powered by TipTap