diff --git a/src/components/ApiCard.tsx b/src/components/ApiCard.tsx
index 71ad9f3..6d6eda1 100644
--- a/src/components/ApiCard.tsx
+++ b/src/components/ApiCard.tsx
@@ -15,6 +15,7 @@ import type { APIItem } from "../data/mockApis";
import RatingHistogram from "./RatingHistogram";
import { useCompareStore, compareStore } from "../state/compareStore";
import Sparkline from "./Sparkline";
+import WhyApi from "./WhyApi";
// ─── Skeleton ────────────────────────────────────────────────────────────────
@@ -506,6 +507,9 @@ export default function ApiCard({
))}
+ {/* "Why this API?" rationale — hidden in compact rows to keep them dense. */}
+ {!isCompact && }
+
= 4.5) {
+ reasons.push(`Highly rated by developers (${api.rating.toFixed(1)} / 5)`);
+ }
+ if (api.uptimePercent !== undefined && api.uptimePercent >= 99.9) {
+ reasons.push(`Reliable uptime (${api.uptimePercent.toFixed(2)}%)`);
+ }
+ if (api.avgLatencyMs !== undefined && api.avgLatencyMs <= 150) {
+ reasons.push(`Fast responses (~${api.avgLatencyMs} ms average latency)`);
+ }
+
+ const price = api.pricePerCall ?? api.pricePerRequest;
+ if (price !== undefined && price <= 0.005) {
+ reasons.push("Cost-effective pricing per call");
+ }
+ if (api.category) {
+ reasons.push(`Popular choice in ${api.category}`);
+ }
+
+ // Always provide at least one reason so the affordance is never empty.
+ if (reasons.length === 0) {
+ reasons.push("Matches your search and category filters");
+ }
+ return reasons;
+}
+
+interface WhyApiProps {
+ api: APIItem;
+}
+
+export default function WhyApi({ api }: WhyApiProps) {
+ const [open, setOpen] = useState(false);
+ const regionId = useId();
+ const reasons = buildReasons(api);
+
+ return (
+
e.stopPropagation()}
+ style={{ marginTop: 4 }}
+ >
+
+
+ {open && (
+
+ {reasons.map((reason, i) => (
+ -
+
+ ✓
+
+ {reason}
+
+ ))}
+
+ )}
+
+ );
+}