User Preferences β
Per-user settings for language, units, currency, theme, and UI customization.
Features β
Language β
- English (en): Default
- French (fr): Full UI translation + card localization
Affects:
- UI labels, buttons, validation messages
- API error responses (i18n)
- Date/time formatting
- Card names and oracle text (see card-search.md for details)
- Card search results display localized names (e.g., "Γclair" instead of "Lightning Bolt")
- Deck lists show cards in selected language
- Collection displays use localized card data
- Fallback: If translation unavailable, displays English name
Multi-Language Card Support: Decksmith stores card data in multiple languages locally (English + French) and displays cards based on the user's language preference. This affects:
- Card autocomplete search results
- Deck card lists
- Collection views
- Any UI component displaying card names or oracle text
Example:
- User with
language: 'fr'sees "Γclair" when searching for Lightning Bolt - User with
language: 'en'sees "Lightning Bolt" - If French translation missing, both users see "Lightning Bolt" (English fallback)
Units β
- Metric (mm/cm): Default for card dimensions, PDF margins
- Imperial (inches): Converts display only (backend stores mm)
Affects:
- PDF configuration UI
- Card dimension displays (63Γ88mm vs 2.5Γ3.5in)
Currency β
- USD (TCGplayer): Default
- EUR (Cardmarket): Converted via exchange rate API
Affects:
- Price displays in collection/decks
- Collection valuation dashboard
Default Print Selection β
- Latest edition: Default to newest printing by release date (default)
- Cheapest available: Default to lowest price in user's currency
- Original edition: Default to first printing (Alpha/Beta for old cards)
Affects:
- Which print is automatically selected when adding a card to deck/collection
- Avoids interrupting build flow with print selection modal
- User can change print anytime by clicking set icon next to card
Theme β
- Light
- Dark
- System: Auto-detect OS preference
Implementation: CSS custom properties + prefers-color-scheme media query
Collection View Config (JSONB) β
Stored in UserPreferences.collection_view_config:
{
"view_mode": "grid",
"visible_columns": ["image", "name", "set", "quantity", "price"],
"sort_field": "name",
"sort_order": "asc"
}Notification Preferences (JSONB) β
{
"pdf_ready_email": true,
"feature_announcements": false
}Business Rules β
Created automatically on signup with defaults:
language: 'en'units: 'mm'default_currency: 'usd'default_print_selection: 'latest'theme: 'system'
Language affects API responses:
- Validation errors translated server-side
- Example:
"Quantity must be β₯ 1"β"La quantitΓ© doit Γͺtre β₯ 1" - Card data localized based on user preference
- Example:
/api/cards/search?q=boltreturns{ name: "Γclair" }for French users,{ name: "Lightning Bolt" }for English users
Units only affect display:
- Backend always stores mm
- Frontend converts on read:
63mm β 2.5in
Collection view config saved automatically:
- No "Save" button
- Updates on column reorder/hide
API Endpoints β
GET /api/preferences β
Returns current user preferences.
PATCH /api/preferences β
Update preferences.
Request Body:
{
"language": "fr",
"units": "inches",
"default_currency": "eur",
"theme": "dark"
}UI Patterns β
Settings Page Structure:
ββββββββββββββββββββββββββββββββ
β Settings β
ββββββββββββββββββββββββββββββββ€
β Language & Region β
β β English β French β
β β Metric (mm) β Imperial β
β β USD β EUR β
ββββββββββββββββββββββββββββββββ
β Card Preferences β
β Default Print Selection: β
β β Latest edition β
β β Cheapest available β
β β Original edition β
ββββββββββββββββββββββββββββββββ
β Display β
β Theme: [System βΎ] β
ββββββββββββββββββββββββββββββββ
β Notifications β
β β Email when PDF ready β
β β Feature announcements β
ββββββββββββββββββββββββββββββββLive preview:
- Changing theme applies immediately (no save button)
- Language switch triggers page reload
Mobile Considerations β
Mobile Web (320-767px) β
Settings UI:
- Grouped sections: Collapsible sections (Language, Appearance, Defaults, Units)
- Full-screen page: Settings take full screen (not sidebar)
- Large toggles: Theme toggle, units toggle (44px touch targets)
- Dropdowns: Language, currency, print selection (56px row height)
Touch Interactions:
- All toggle switches: 44px minimum
- Dropdown menus: Large touch targets
- Swipe down to refresh (reloads preferences from API)
Theme Toggle:
- Instant apply: Theme changes immediately (no save button)
- Persistence: Saved to
UserPreferencestable (syncs across devices)
Language Picker:
- Tap to change: Opens bottom sheet with language options
- Page reload: After selection (language affects UI strings)
Performance Targets:
- Settings load: < 200ms
- Preference update: < 300ms (API save)
- Theme switch: < 100ms (CSS variable swap)
Tablet (768-1023px) β
Sidebar + main content: Settings sidebar with content area (like desktop)
Future Native Mobile β
Platform Features:
- System preferences: Sync with device theme (light/dark)
- Local storage: Preferences cached locally, sync when online
- Notifications settings: Push notification preferences (in-app)
Domain Logic Reuse:
- Preference validation in
packages/domain(e.g., validate units, currency)
Related ADRs β
- ADR-0008: Mobile-First Web Design Principles β Touch targets
- ADR-0009: Responsive Feature Strategy β Settings layout
Related Specs β
- Data Model β UserPreferences schema
- Collection β Collection view config
- PDF Generation β Units in PDF config