diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8e4619a..84fecb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- Public `/download` page for the Minutia macOS companion. It resolves the latest signed DMG from GitHub Releases at request time (cached hourly) and degrades to a "watch for the release" state until the first build ships, so it never links to a 404. Includes system requirements, an open-source link, and how-it-works steps. The landing page and the in-app companion prompt both point to it.
- Minutia Retro: a free, anonymous, multiplayer retrospective board at `/retro`. Guided 7-phase ritual (Lobby, Reflect, Reveal, Theme, Vote, Discuss, Commit) with realtime presence, a synchronized card-flip Reveal, and a closure bloom. Boards are ephemeral (30-day auto-expiry) and rate-limited.
- Anonymous board operations run through `SECURITY DEFINER` Postgres RPCs (default-deny `retro_*` tables); liveness uses Supabase Realtime broadcast and presence with a snapshot reconcile.
- AI theme-clustering suggestions during the Theme phase (OpenRouter; degrades silently when unconfigured).
diff --git a/e2e/smoke.spec.ts b/e2e/smoke.spec.ts
index c5e82a6..59c4e3b 100644
--- a/e2e/smoke.spec.ts
+++ b/e2e/smoke.spec.ts
@@ -34,7 +34,7 @@ test.describe("Smoke Tests", () => {
});
test("all public routes return valid responses", async ({ request }) => {
- const routes = ["/login"];
+ const routes = ["/login", "/download"];
for (const route of routes) {
const response = await request.get(route);
diff --git a/src/app/download/page.tsx b/src/app/download/page.tsx
new file mode 100644
index 0000000..62075a7
--- /dev/null
+++ b/src/app/download/page.tsx
@@ -0,0 +1,194 @@
+import type { Metadata } from "next";
+import Link from "next/link";
+import { ArrowRight, Bell, Download, ExternalLink } from "lucide-react";
+import {
+ DESKTOP_RELEASES_URL,
+ DESKTOP_REPO_URL,
+ DESKTOP_REQUIREMENTS,
+ getDesktopRelease,
+ type DesktopRelease,
+} from "@/lib/desktop-download";
+
+export const metadata: Metadata = {
+ title: "Minutia for Mac",
+ description:
+ "Record your meetings from the menu bar. No bot joins the call. Recaps land in Minutia seconds after you hit stop.",
+};
+
+export const revalidate = 300;
+
+const steps = [
+ {
+ title: "Install and sign in",
+ description:
+ "Download the app and sign in with your Minutia account. It lives in the menu bar, out of your way.",
+ },
+ {
+ title: "Record from the menu bar",
+ description:
+ "Start a recording yourself, or let meeting detection prompt you the moment a call begins.",
+ },
+ {
+ title: "Stop and get the recap",
+ description:
+ "Hit stop and the recap opens in Minutia seconds later, complete with action items.",
+ },
+];
+
+function DownloadCta({
+ release,
+ variant,
+}: {
+ release: DesktopRelease;
+ variant: "ink" | "accent";
+}) {
+ const base =
+ "inline-flex items-center gap-2 rounded-md px-6 py-3 text-sm font-medium text-paper transition-colors";
+ const solid =
+ variant === "ink"
+ ? "bg-ink hover:bg-ink-2"
+ : "bg-accent hover:bg-accent-hover";
+
+ if (release.available) {
+ return (
+
+
+ Download for macOS
+
+ );
+ }
+
+ return (
+
+
+ Watch for the release
+
+ );
+}
+
+export default async function DownloadPage() {
+ const release = await getDesktopRelease();
+ const requirements = release.available
+ ? `${release.version} · ${DESKTOP_REQUIREMENTS}`
+ : DESKTOP_REQUIREMENTS;
+
+ return (
+
+ {/* ─── Hero ─── */}
+
+
+ Minutia for Mac
+
+
+ Record your meetings from the menu bar.
+
+
+ No bot joins the call. Minutia captures your mic and system audio
+ right from the menu bar, and the recap lands in your workspace seconds
+ after you hit stop.
+
+
+
+
+
{requirements}
+ {!release.available && (
+
+ Not shipped yet. Watch the repo and GitHub tells you the moment the
+ first signed build lands.
+