setRefreshKey((key) => key + 1)}
diff --git a/src/components/frontend/minigames/UnlockNotice.tsx b/src/components/frontend/minigames/UnlockNotice.tsx
new file mode 100644
index 0000000..32baaa1
--- /dev/null
+++ b/src/components/frontend/minigames/UnlockNotice.tsx
@@ -0,0 +1,26 @@
+import { Lock } from "lucide-react";
+
+/**
+ * Locked-state hint shown beside a minigame's custom-content link: tells the
+ * player exactly which milestones unlock authoring user-generated content and
+ * how close they are. Unlocked players see nothing (the link speaks for itself).
+ */
+export function UnlockNotice({
+ title,
+ requirement,
+ progress,
+}: {
+ title: string;
+ requirement: string;
+ progress: string;
+}) {
+ return (
+
+
+
+ Author your own {title} once {requirement}{" "}
+ ({progress})
+
+
+ );
+}
diff --git a/src/components/frontend/radio/RadioArena.tsx b/src/components/frontend/radio/RadioArena.tsx
index fa8ca0e..22110da 100644
--- a/src/components/frontend/radio/RadioArena.tsx
+++ b/src/components/frontend/radio/RadioArena.tsx
@@ -4,7 +4,13 @@ import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { Radio } from "lucide-react";
import type { RadioStats } from "@/app/(frontend)/radio/actions";
+import {
+ isRadioUnlocked,
+ SPRINT_ACCURACY_REQUIREMENT,
+ WATCH_ACCURACY_REQUIREMENT,
+} from "@/lib/custom-minigames/radio";
import { useRealtimePresence } from "@/hooks/useRealtimePresence";
+import { UnlockNotice } from "@/components/frontend/minigames/UnlockNotice";
import { RadioLeaderboard } from "./RadioLeaderboard";
import { RadioTraffic } from "./RadioTraffic";
@@ -24,6 +30,13 @@ export function RadioArena({
setPlaying(phase === "playing");
}, []);
+ const customUnlocked = isRadioUnlocked({
+ sprintBestAccuracy: initialStats.sprintBestAccuracy,
+ watchBestAccuracy: initialStats.watchBestAccuracy,
+ });
+ const sprintPercent = Math.round(initialStats.sprintBestAccuracy * 100);
+ const watchPercent = Math.round(initialStats.watchBestAccuracy * 100);
+
useEffect(() => {
const savedMode = window.localStorage.getItem("radio-traffic-mode");
if (savedMode === "sprint" || savedMode === "watch") setMode(savedMode);
@@ -43,6 +56,13 @@ export function RadioArena({
Custom radio tests
+ {!customUnlocked && (
+
+ )}