diff --git a/web/src/lib/components/champion-search.svelte b/web/src/lib/components/champion-search.svelte
new file mode 100644
index 0000000..59a69ba
--- /dev/null
+++ b/web/src/lib/components/champion-search.svelte
@@ -0,0 +1,122 @@
+
+
+
+
= 0
+ ? `champion-option-${activeIndex}`
+ : undefined}
+ bind:value={query}
+ oninput={() => {
+ activeIndex = -1;
+ isOpen = true;
+ }}
+ onkeydown={handleKeyDown}
+ {disabled}
+ placeholder={disabled ? "Game over" : "Type a champion name..."}
+ autocomplete="off"
+ class="w-full px-4 py-3 rounded-lg bg-[var(--color-input-bg)] border-2 border-[var(--color-input-border)] text-[var(--color-text)] text-base outline-none transition-colors focus:border-[var(--color-accent)] disabled:opacity-50 disabled:cursor-not-allowed placeholder:text-[var(--color-text-muted)]"
+ />
+
+ {#if isVisible}
+
+ {/if}
+
diff --git a/web/src/lib/components/game-board.svelte b/web/src/lib/components/game-board.svelte
new file mode 100644
index 0000000..c5989cd
--- /dev/null
+++ b/web/src/lib/components/game-board.svelte
@@ -0,0 +1,147 @@
+
+
+{#if loading}
+
+ Failed to load champion data. Please refresh.
+
+{:else if game}
+
+
+ {game.maxGuesses > 0
+ ? `${game.guesses.length} / ${game.maxGuesses} guesses`
+ : `${game.guesses.length} guess${game.guesses.length !== 1 ? "es" : ""}`}
+
+
+
+
+ {isWon ? "You got it!" : "Game Over"}
+
+
+ {#if isWon}
+
+ You found {target.name} in
+ {guessCount}
+ guess{guessCount > 1 ? "es" : ""}!
+
+ {:else}
+
+ The champion was {target.name}
+
+
})
+ {/if}
+
+ {#if onNewGame}
+
+ {/if}
+
diff --git a/web/src/lib/components/guess-grid.svelte b/web/src/lib/components/guess-grid.svelte
new file mode 100644
index 0000000..bd5a112
--- /dev/null
+++ b/web/src/lib/components/guess-grid.svelte
@@ -0,0 +1,28 @@
+
+
+
+
+
+
})
+
{champion.name}
+
+
+
+ {#each results as r, i (r.key)}
+
+ {r.guessValue}
+ {#if r.direction}
+
+ {r.direction === "up" ? " ↑" : " ↓"}
+
+ {/if}
+
+ {/each}
+
diff --git a/web/src/lib/components/stats-display.svelte b/web/src/lib/components/stats-display.svelte
new file mode 100644
index 0000000..51ff7c4
--- /dev/null
+++ b/web/src/lib/components/stats-display.svelte
@@ -0,0 +1,29 @@
+
+
+{#if stats && stats.gamesPlayed > 0}
+