diff --git a/app/about/AboutPage.tsx b/app/about/AboutPage.tsx
index aa3c26ca..c4a61489 100644
--- a/app/about/AboutPage.tsx
+++ b/app/about/AboutPage.tsx
@@ -1,7 +1,9 @@
import "./about.css";
import { IBM_Plex_Serif } from "next/font/google";
import { LandingCTA, LandingCTABottom } from "./LandingCTA";
-import { Demo } from "./Demo";
+import { InteractiveAppDemo } from "./InteractiveAppDemo";
+import { InteractiveAppDemoMobile } from "./InteractiveAppDemoMobile";
+import { Media } from "components/Media";
import { Features } from "./Features";
import { Examples } from "./Examples";
import { Pricing } from "./Pricing";
@@ -45,7 +47,14 @@ export function AboutPage() {
community — whether you're writing a blog, newsletter, or secret third
thing.
- {/**/}
+
+
+
+
+
+
+
+
diff --git a/app/about/InteractiveAppDemo.tsx b/app/about/InteractiveAppDemo.tsx
new file mode 100644
index 00000000..4cb06b74
--- /dev/null
+++ b/app/about/InteractiveAppDemo.tsx
@@ -0,0 +1,80 @@
+"use client";
+import { useEffect, useState } from "react";
+
+type Page = "drafts" | "posts" | "analytics" | "settings";
+
+type Hit = {
+ id: Page;
+ label: string;
+ topPct: number;
+ leftPct: number;
+};
+
+const HIT_WIDTH_PCT = 16.33;
+const HIT_HEIGHT_PCT = 2.8;
+const AUTOPLAY_INTERVAL_MS = 5000;
+
+const PAGES: Hit[] = [
+ { id: "drafts", label: "Drafts", topPct: 14.83, leftPct: 2.28 },
+ { id: "posts", label: "Posts", topPct: 18.0, leftPct: 2.28 },
+ { id: "analytics", label: "Analytics", topPct: 23.95, leftPct: 2.28 },
+ { id: "settings", label: "Settings", topPct: 27.15, leftPct: 2.28 },
+];
+
+export function InteractiveAppDemo() {
+ let [page, setPage] = useState("drafts");
+ let [autoplay, setAutoplay] = useState(true);
+ let [animate, setAnimate] = useState(true);
+
+ useEffect(() => {
+ if (!autoplay) return;
+ const interval = setInterval(() => {
+ setAnimate(true);
+ setPage((p) => {
+ const idx = PAGES.findIndex((x) => x.id === p);
+ return PAGES[(idx + 1) % PAGES.length].id;
+ });
+ }, AUTOPLAY_INTERVAL_MS);
+ return () => clearInterval(interval);
+ }, [autoplay]);
+
+ const handleClick = (id: Page) => {
+ setAnimate(false);
+ setAutoplay(false);
+ setPage(id);
+ };
+
+ return (
+
+ {PAGES.map((p) => (
+

+ ))}
+ {PAGES.map((p) => (
+
+ );
+}
diff --git a/app/about/InteractiveAppDemoMobile.tsx b/app/about/InteractiveAppDemoMobile.tsx
new file mode 100644
index 00000000..9fc984c3
--- /dev/null
+++ b/app/about/InteractiveAppDemoMobile.tsx
@@ -0,0 +1,67 @@
+"use client";
+import { useEffect, useState } from "react";
+import { ToggleGroup } from "components/ToggleGroup";
+
+type Page = "drafts" | "posts" | "analytics" | "settings";
+
+const PAGES: { id: Page; label: string }[] = [
+ { id: "drafts", label: "Drafts" },
+ { id: "posts", label: "Posts" },
+ { id: "analytics", label: "Analytics" },
+ { id: "settings", label: "Settings" },
+];
+
+const AUTOPLAY_INTERVAL_MS = 5000;
+
+export function InteractiveAppDemoMobile() {
+ let [page, setPage] = useState("drafts");
+ let [autoplay, setAutoplay] = useState(true);
+ let [animate, setAnimate] = useState(true);
+
+ useEffect(() => {
+ if (!autoplay) return;
+ const interval = setInterval(() => {
+ setAnimate(true);
+ setPage((p) => {
+ const idx = PAGES.findIndex((x) => x.id === p);
+ return PAGES[(idx + 1) % PAGES.length].id;
+ });
+ }, AUTOPLAY_INTERVAL_MS);
+ return () => clearInterval(interval);
+ }, [autoplay]);
+
+ const handleClick = (id: Page) => {
+ setAnimate(false);
+ setAutoplay(false);
+ setPage(id);
+ };
+
+ return (
+
+
({ value: p.id, label: p.label }))}
+ />
+
+ {PAGES.map((p) => (
+

+ ))}
+
+
+ );
+}
diff --git a/public/about/landing-analytics.webp b/public/about/landing-analytics.webp
new file mode 100644
index 0000000000000000000000000000000000000000..c9a543e06e1f7caea89c587c3b5c3dd38867a4c9
GIT binary patch
literal 117410
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