diff --git a/components/firmware-card.tsx b/components/firmware-card.tsx
index 9e9d848..2e70b0e 100644
--- a/components/firmware-card.tsx
+++ b/components/firmware-card.tsx
@@ -31,7 +31,7 @@ export function FirmwareCard({
: "border-[var(--line)] bg-[rgba(0,0,0,0.22)] hover:-translate-y-0.5 hover:border-[rgba(240,197,10,0.35)] hover:bg-[rgba(240,197,10,0.04)]"
)}
>
-
+
{hasPreview && (
diff --git a/components/firmware-preview.tsx b/components/firmware-preview.tsx
index 8fed5ae..c27339c 100644
--- a/components/firmware-preview.tsx
+++ b/components/firmware-preview.tsx
@@ -1,8 +1,12 @@
"use client";
+import { useEffect, useRef, useState } from "react";
import type { FirmwareInfo } from "@/lib/firmware";
import { cn } from "@/lib/utils";
+const SCREEN_W = 320;
+const SCREEN_H = 240;
+
/** Renders HTML on-device UI mock (preferred) — never uses raster covers. */
export function FirmwarePreview({
fw,
@@ -13,16 +17,49 @@ export function FirmwarePreview({
className?: string;
title?: string;
}) {
+ const hostRef = useRef
(null);
+ const [scale, setScale] = useState(1);
+
+ useEffect(() => {
+ const el = hostRef.current;
+ if (!el) return;
+
+ const update = () => {
+ const { width, height } = el.getBoundingClientRect();
+ if (width <= 0 || height <= 0) return;
+ setScale(Math.min(width / SCREEN_W, height / SCREEN_H));
+ };
+
+ update();
+ const ro = new ResizeObserver(update);
+ ro.observe(el);
+ return () => ro.disconnect();
+ }, [fw.media.preview]);
+
if (fw.media.preview) {
return (
-
+
+
+
);
}