/** * InputHalo landing page — net-new marketing page for inputhalo.freno.me. * * InputHalo is a polished macOS menu bar app that visualizes mouse and * keyboard input on screen: keyboard indicators, cursor halos, click ripples, * scroll indicators, and sensitive-input detection. It is built with SwiftUI * and distributed via direct DMG (Sparkle auto-updates) with a paid App Store * variant planned. * * The download orchestration stays in the testable pure `./download.ts` module; * this component is a thin wrapper around it plus the landing-page UX. */ import { For, createSignal } from "solid-js"; import { A } from "@solidjs/router"; import { PageHead } from "~/components/PageHead"; import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders"; import SubdomainHeader from "~/components/SubdomainHeader"; import Button from "~/components/ui/Button"; import DownloadOnAppStoreDark from "~/components/icons/DownloadOnAppStoreDark"; import { useDarkMode } from "~/context/darkMode"; import { useSite } from "~/context/SiteContext"; import { api } from "~/lib/api"; import { INPUTHALO_APP_STORE_URL, INPUTHALO_ICON_DARK, INPUTHALO_ICON_DEFAULT, INPUTHALO_MIN_SYSTEM_VERSION, performInputHaloDownload } from "./download"; const FEATURES = [ { title: "Keyboard indicator overlay", body: "Display the keys you press in a clean, configurable on-screen overlay — perfect for demos and tutorials." }, { title: "Mouse halo & click ripples", body: "Add a subtle halo around your cursor and visual click feedback so viewers never lose track of your pointer." }, { title: "Scroll indicators", body: "Show scroll direction and intensity in real time, useful for screencasts and accessibility demos." }, { title: "Sensitive input detection", body: "InputHalo automatically hides visual feedback when you type into password or secure fields." }, { title: "Fully customizable", body: "Choose colors, sizes, animations, position, and behavior to match your setup and brand." }, { title: "Native macOS menu bar app", body: "Built with SwiftUI, runs quietly in the menu bar, and uses system accessibility APIs responsibly." } ] as const; const USE_CASES = [ { title: "Streamers & creators", body: "Let your audience see exactly what you're clicking and typing without cluttering your scene." }, { title: "Presenters & educators", body: "Make keyboard shortcuts and cursor movement crystal clear during demos and recordings." }, { title: "Developers", body: "Show input interactions in bug reports, design reviews, and pair-programming sessions." }, { title: "Accessibility", body: "Visualize inputs to make workflows easier to follow for users who benefit from clear feedback." } ] as const; export default function InputHaloLanding() { const site = useSite(); const { isDark } = useDarkMode(); const [loading, setLoading] = createSignal(false); const download = () => { if (loading()) return; setLoading(true); performInputHaloDownload( (input) => api.downloads.getDownloadUrl.query(input), (url) => { window.location.href = url; }, () => { alert("Failed to initiate download. Please try again."); } ).finally(() => setLoading(false)); }; const iconSrc = () => isDark() ? INPUTHALO_ICON_DARK : INPUTHALO_ICON_DEFAULT; const brandColor = () => site().brandColor; return ( <>
{/* Soft pink halos in the background */}
); }