diff --git a/src/client/components/GearImage.tsx b/src/client/components/GearImage.tsx
new file mode 100644
index 0000000..76f1221
--- /dev/null
+++ b/src/client/components/GearImage.tsx
@@ -0,0 +1,65 @@
+interface GearImageProps {
+ src: string;
+ alt: string;
+ dominantColor?: string | null;
+ cropZoom?: number | null;
+ cropX?: number | null;
+ cropY?: number | null;
+ className?: string;
+ cover?: boolean;
+}
+
+export function GearImage({
+ src,
+ alt,
+ dominantColor,
+ cropZoom,
+ cropX,
+ cropY,
+ className = "",
+ cover = false,
+}: GearImageProps) {
+ const hasCrop = cropZoom != null && cropZoom > 1;
+
+ if (cover) {
+ return (
+
+ );
+ }
+
+ if (hasCrop) {
+ return (
+
+ );
+ }
+
+ return (
+
+ );
+}
+
+/**
+ * Returns the background color for an image container.
+ * Uses the dominant color if available, otherwise a neutral fallback.
+ */
+export function imageContainerBg(
+ dominantColor?: string | null,
+): string | undefined {
+ return dominantColor || "#f3f4f6";
+}