···92929393- **This is a TypeScript project** - ALL code (including scripts) must use TypeScript with proper types
9494- **Use `nix-shell -p <package>` for missing commands** - If a command isn't in PATH, use nix-shell to get it temporarily
9595+- **Prefer functional style over exceptions** - Avoid throwing errors for control flow. Use type predicates, Option/Result patterns, and early returns instead. Throwing is like GOTO—it breaks local reasoning and makes code harder to follow
9596- `src/routeTree.gen.ts` is auto-generated - never edit manually
9697- `typelex/externals.tsp` is auto-generated from lexicons folder - add external lexicon JSON to trigger regeneration
9798- Demo files (prefixed with `demo`) are safe to delete
···11+import type { ImageSize, ScryfallId } from "./scryfall-types";
22+33+/**
44+ * Reconstruct Scryfall image URI from card ID
55+ *
66+ * Pattern: https://cards.scryfall.io/{size}/front/{id[0]}/{id[1]}/{id}.jpg
77+ *
88+ * This works for 100% of sampled cards (96.5% of all cards have images).
99+ * See .claude/SCRYFALL.md for details.
1010+ */
1111+export function getImageUri(
1212+ scryfallId: ScryfallId,
1313+ size: ImageSize = "normal",
1414+): string {
1515+ return `https://cards.scryfall.io/${size}/front/${scryfallId[0]}/${scryfallId[1]}/${scryfallId}.jpg`;
1616+}