diff --git a/components/DeckBuilderStatsBar.js b/components/DeckBuilderStatsBar.js
new file mode 100644
index 0000000..0d67b24
--- /dev/null
+++ b/components/DeckBuilderStatsBar.js
@@ -0,0 +1,30 @@
+/**
+ * Summary metrics row for the deck builder main panel.
+ * @param {{ stats: { totalCards: number, avgCmc: string|number, colorCounts: object, typeCounts: object } }} props
+ */
+export default function DeckBuilderStatsBar({ stats }) {
+ return (
+
@@ -351,29 +315,7 @@ export default function DeckBuilder() {
- {/* Deck Stats Bar */}
-
-
-
{stats.totalCards}/100
-
Cards
-
-
-
{stats.avgCmc}
-
Avg CMC
-
-
-
- {Object.keys(stats.colorCounts).length}
-
-
Colors
-
-
-
- {Object.keys(stats.typeCounts).length}
-
-
Types
-
-
+
{/* Deck Cards List */}
diff --git a/test/lib/deck-builder-stats.test.js b/test/lib/deck-builder-stats.test.js
new file mode 100644
index 0000000..eb40670
--- /dev/null
+++ b/test/lib/deck-builder-stats.test.js
@@ -0,0 +1,37 @@
+import { describe, it, expect } from 'vitest';
+import { computeDeckStats, isBasicLand, BASIC_LAND_NAMES } from '../../lib/deck-builder-stats.js';
+
+describe('isBasicLand', () => {
+ it('returns true for each basic land name', () => {
+ for (const name of BASIC_LAND_NAMES) {
+ expect(isBasicLand({ name })).toBe(true);
+ }
+ });
+
+ it('returns false for non-basic cards', () => {
+ expect(isBasicLand({ name: 'Lightning Bolt' })).toBe(false);
+ });
+});
+
+describe('computeDeckStats', () => {
+ it('returns zeros for an empty deck', () => {
+ expect(computeDeckStats([])).toEqual({
+ totalCards: 0,
+ avgCmc: 0,
+ colorCounts: {},
+ typeCounts: {},
+ });
+ });
+
+ it('quantity-weights CMC and parses JSON colors', () => {
+ const stats = computeDeckStats([
+ { quantity: 2, cmc: 3, colors: '["R","G"]', card_type: 'Creature — Elf' },
+ { quantity: 1, cmc: 1, colors: '["R"]', card_type: 'Instant' },
+ ]);
+ expect(stats.totalCards).toBe(3);
+ expect(stats.avgCmc).toBe('2.3');
+ expect(stats.colorCounts).toEqual({ R: 3, G: 2 });
+ expect(stats.typeCounts.Creature).toBe(2);
+ expect(stats.typeCounts.Instant).toBe(1);
+ });
+});