Skip to content

Visual Identity

Updated: 2026-06-10


Mood & Direction

Decksmith is a tool for MTG players who care about their collection. The design should feel like the hobby itself: warm, tactile, crafted — not like a corporate productivity app.

Reference points: MTG Arena (depth, card art, color identity) × Linear (clean, focused, fast).

The non-negotiable differentiator: no flat corporate SaaS palette. No pure black, no cool grey, no blue primary CTA.


What Makes This Not SaaS

  1. Warm-dark background — purple-black tint (#0f0e17), not the cool grey of GitHub or the pure black of Linear
  2. Amber brand + violet accent — amber (#e8b84b) is the brand identity color (logo, ornaments, dark mode buttons). Violet (#5b4fcf) is the light mode interactive accent. No major MTG tool uses either combination
  3. Cards with depth — subtle inner shadow + amber border glow on hover
  4. Deck cards use commander artwork as blurred background with dark gradient overlay (MTG Arena style)
  5. Mana symbols rendered as colored icons — never plain text like "2UG"
  6. Subtle grain texture on surfaces — CSS noise filter at 2–3% opacity
  7. Strong typographic hierarchy — sections breathe, not everything at the same visual weight
  8. MTG section separators─────◈───── used as section dividers

Colour Palette

Semantic Tokens

TokenDark (.dark)Light (:root)Usage
bg#0f0e17#faf9f4Page background
surface#1a1827#ffffffCards, panels
surface-raised#232135#f2f0e6Elevated surfaces
surface-hover#2a2840#ede9d8Hover state on interactive surfaces
border#2e2b47#d5d0beBorders
border-subtle#232135#e8e5d8Dividers
border-focus#e8b84b#5b4fcfFocus ring
text#f0eef8#0f0e17Primary text
text-muted#a8a2cc#524d80Secondary text
text-faint#524d80#7b75a8Decorative only — fails AA

Interactive Accent

Mode-specific. Dark mode: amber (warm, crafted feel). Light mode: violet (contrast on parchment).

TokenDarkLightUsage
accent#e8b84b#5b4fcfPrimary buttons, active states
accent-hover#c49a1a#4a3db0Button hover
accent-subtleamber @ 12%violet @ 8%Subtle tint, selected backgrounds
accent-borderamber @ 30%violet @ 25%Focused borders, hover glow
accent-text#e8b84b#3d319aAccent-colored text (WCAG AA ✓)
on-accent#0f0e17#ffffffText ON accent button

Brand Amber (decorative only)

TokenDarkLightUsage
brand#e8b84b#c49a1aLogo mark, ornaments, ─────◈───── separators

Warning: brand in light mode (#c49a1a on #faf9f4) = 3.75:1 — fails AA. Never use for readable text. Decorative and ornamental use only (same rule as text-faint).

Status Colours

TokenDarkLightUsage
success#22c55e#22c55eOwned cards, coverage
warning#f59e0b#d97706Partial coverage
error#ef4444#ef4444Missing, errors
info#5b9cf6#2563ebInformational

Each has a -subtle (tinted background) and -text (accessible text color) variant. See packages/tokens/src/semantic/colors.ts for exact values. infomtg-blue — different semantic meaning, never substitute one for the other.

MTG Colour Identity (WUBRG)

Used for: deck colour indicators, mana cost symbols, colour distribution charts, filter dots.

ColourTokenValue
White (Plains)mtg-white#f5f0d8 (dark) / #c8b96e (light)
Blue (Island)mtg-blue#1a6eb5
Black (Swamp)mtg-black#160d22
Red (Mountain)mtg-red#cc2222
Green (Forest)mtg-green#006e3c
Colorlessmtg-colorless#8fa3b0
Multicolourmtg-multi#c9a84c

MTG colours represent the game's colour identity system — not UI states. mtg-rederror.


Typography

Fonts

RoleFontUsage
font-displayOutfitHeadings, navigation, labels
font-bodyOutfitBody text (same family, consistent feel)
font-monoJetBrains MonoStats, card counts, prices, mana costs

Both fonts are self-hosted from apps/web/public/fonts/, font-display: optional (no FOUT).

Type Scale

TokenpxLine heightUsage
xs121.5Badges, metadata, labels
sm141.5Secondary body, captions
base161.6Primary body
lg181.5Lead text
xl201.4Sub-headings
2xl241.3Section headings
3xl301.2Page titles
4xl361.1Large headings

Spacing

4px base grid: 4 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 48 / 64 / 80 / 96 / 128


Border Radius

Semantic roles — use these in components

TokenValueUse cases
radius-interactive8pxButtons, inputs, selects, toggles, checkboxes
radius-surface12pxCards, panels, popovers, tooltips, dropdowns
radius-modal16pxModals, dialogs, drawers, bottom sheets
radius-badge9999pxPills, tags, avatars, mana symbol backgrounds, dots

Rule: components always use a semantic role, never a scale token directly. Exception:radius-sm (4px) for stamp/seal elements — MTG format badges, rarity chips — with an inline comment. These intentionally look crisp/printed, not rounded.

Scale — reference only

TokenValue
radius-sm4px
radius-md8px
radius-lg12px
radius-xl16px
radius-2xl24px
radius-full9999px

Shadows

Semantic roles — use these in components

TokenValue (= scale alias)Use cases
shadow-popover= shadow-smTooltips, small dropdowns, hints
shadow-card= shadow-mdCards, panels, menus
shadow-overlay= shadow-lgModals, dialogs, drawers
shadow-accentmode-specific glowHover/focus glow on interactive surfaces

Rule: components always use a semantic role — shadow-card, not shadow-md. Combining shadow-card + shadow-accent is the standard card hover state.

Scale — reference only

Violet-tinted in both modes. Light uses the accent color (#5b4fcf). Dark uses rim-light (rgba(168,162,204,X)) — drop shadows are invisible on the near-black background, so elevation is expressed via a colored rim + soft outer glow instead.

TokenLightDark
shadow-sm0 1px 6px rgba(91,79,207,0.22)0 0 0 1px rgba(168,162,204,0.45), inset 0 1px 0 rgba(168,162,204,0.10)
shadow-md0 4px 18px rgba(91,79,207,0.30)0 4px 24px rgba(168,162,204,0.18), 0 0 0 1px rgba(168,162,204,0.55), inset 0 1px 0 rgba(168,162,204,0.12)
shadow-lg0 8px 32px rgba(91,79,207,0.38), 0 0 0 1px rgba(91,79,207,0.10)0 8px 36px rgba(168,162,204,0.22), 0 0 0 1px rgba(168,162,204,0.60), inset 0 1px 0 rgba(168,162,204,0.14)

Animation

Two-mode motion system. Direction A (micro interactions): 50–200ms, ease-out. Direction B (moments clés): 300–500ms, ease-spring or ease-in-out.

TokenValue
duration-instant50ms
duration-fast100ms
duration-normal200ms
duration-slow350ms
duration-page300ms
duration-story500ms
ease-outcubic-bezier(0, 0, 0.2, 1)
ease-springcubic-bezier(0.34, 1.56, 0.64, 1)

prefers-reduced-motion: reduce resets all durations to 0ms via a media query in tokens.css.


MTG-Specific Touches

Applied only where contextually relevant — never decorative noise.

ElementMTG touch
Colour indicatorKeyrune SVG icons {W}{U}{B}{R}{G} (official MTG symbols)
Colour tintsWUBRG tokens (mtg-blue, etc.) used for bg, text, tags, charts
Deck cardCommander artwork blurred as background + dark gradient
Mana costKeyrune SVG symbols (coloured), not plain text
Format badgeStyled stamp/seal
Coverage indicator✓ green / ⚠ amber / ✗ red — card-stamp style
Section separator─────◈─────
Foil card thumbnailCSS shimmer gradient animation
Card raritySet symbol colour (common/uncommon/rare/mythic)

Desktop

Sidebar (collapsed by default, expandable on large screens):

┌──────┬──────────────────────────────────────────────────┐
│  ◈   │  top bar: logo + search + avatar                 │
├──────┤                                                  │
│  ⊞   │                                                  │
│  🃏  │           main content                           │
│  📦  │                                                  │
│  🔍  │                                                  │
│  ─   │                                                  │
│  ⚙   │                                                  │
└──────┴──────────────────────────────────────────────────┘

⊞  Dashboard
🃏  Decks
📦  Collection
🔍  Card Search
⚙   Settings

Mobile

Bottom navigation bar (fixed):

┌─────────────────────────────────┐
│           content               │
├─────────────────────────────────┤
│  ⊞     🃏     📦     🔍     ⚙  │
└─────────────────────────────────┘

Touch targets: minimum 44px (WCAG AAA — ADR-0008).


Icons

UsageLibraryNotes
UI iconsLucide ReactConsistent with shadcn/ui, tree-shakeable
MTG mana symbolsKeyruneCSS font / SVG sprites from mana.andrewgioia.com

Built with VitePress