Problem
The playstyle detail page shows all filter options (all 6 inks, all 9 costs, all 5 card types, all keywords/classifications/sets) regardless of which values actually exist in that playstyle's card pool.
For example, if a playstyle only contains Amber, Amethyst, and Ruby cards costing 2-7, the filter UI still shows Steel, Sapphire, Emerald inks and costs 1, 8, 9 — none of which would match any cards.
Proposed Solution
Derive available filter options at runtime from the playstyle's card array:
const availableInks = useMemo(() => new Set(cards.flatMap(c => c.inkColor?.split('-') ?? [])), [cards]);
const availableCosts = useMemo(() => new Set(cards.map(c => c.cost)), [cards]);
const availableTypes = useMemo(() => new Set(cards.map(c => c.type)), [cards]);
Then pass these sets to the filter components to hide or disable options with zero matches.
Performance: Playstyle card pools are small (19-92 cards). A single array pass is microseconds — no build-time precomputation needed.
Scope
Affects all filter categories on the playstyle detail page:
- Ink colors (hardcoded
ALL_INKS)
- Ink costs (hardcoded
COST_BUTTONS)
- Card types (hardcoded
CARD_TYPE_FILTERS)
- Keywords (currently derived from all cards, not playstyle-scoped)
- Classifications (same — global, not scoped)
- Sets (same — global, not scoped)
Design Decision
Hide unavailable options entirely vs. show them as disabled/greyed out? Hiding is simpler and reduces visual noise; disabled state communicates "this exists but not here." Worth deciding during implementation.
Problem
The playstyle detail page shows all filter options (all 6 inks, all 9 costs, all 5 card types, all keywords/classifications/sets) regardless of which values actually exist in that playstyle's card pool.
For example, if a playstyle only contains Amber, Amethyst, and Ruby cards costing 2-7, the filter UI still shows Steel, Sapphire, Emerald inks and costs 1, 8, 9 — none of which would match any cards.
Proposed Solution
Derive available filter options at runtime from the playstyle's card array:
Then pass these sets to the filter components to hide or disable options with zero matches.
Performance: Playstyle card pools are small (19-92 cards). A single array pass is microseconds — no build-time precomputation needed.
Scope
Affects all filter categories on the playstyle detail page:
ALL_INKS)COST_BUTTONS)CARD_TYPE_FILTERS)Design Decision
Hide unavailable options entirely vs. show them as disabled/greyed out? Hiding is simpler and reduces visual noise; disabled state communicates "this exists but not here." Worth deciding during implementation.