diff --git a/apps/web/public/icons/adobe.svg b/apps/web/public/icons/adobe.svg new file mode 100644 index 0000000000..122fe18f64 --- /dev/null +++ b/apps/web/public/icons/adobe.svg @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/amazon.svg b/apps/web/public/icons/amazon.svg new file mode 100644 index 0000000000..665c8b4540 --- /dev/null +++ b/apps/web/public/icons/amazon.svg @@ -0,0 +1,18 @@ + + + + + + + image/svg+xml + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/apple.svg b/apps/web/public/icons/apple.svg new file mode 100644 index 0000000000..42daa2b16f --- /dev/null +++ b/apps/web/public/icons/apple.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/bain.svg b/apps/web/public/icons/bain.svg new file mode 100644 index 0000000000..2ada9a3cf9 --- /dev/null +++ b/apps/web/public/icons/bain.svg @@ -0,0 +1,58 @@ + + + + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/databricks.svg b/apps/web/public/icons/databricks.svg new file mode 100644 index 0000000000..b61e33b93d --- /dev/null +++ b/apps/web/public/icons/databricks.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/disney.svg b/apps/web/public/icons/disney.svg new file mode 100644 index 0000000000..9733a6e8fc --- /dev/null +++ b/apps/web/public/icons/disney.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/meta.svg b/apps/web/public/icons/meta.svg new file mode 100644 index 0000000000..0716d708b7 --- /dev/null +++ b/apps/web/public/icons/meta.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/web/public/icons/palantir.svg b/apps/web/public/icons/palantir.svg new file mode 100644 index 0000000000..ab1814ba7d --- /dev/null +++ b/apps/web/public/icons/palantir.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/richmond_american.svg b/apps/web/public/icons/richmond_american.svg new file mode 100644 index 0000000000..2536cf77b7 --- /dev/null +++ b/apps/web/public/icons/richmond_american.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/web/public/icons/wayfair.svg b/apps/web/public/icons/wayfair.svg new file mode 100644 index 0000000000..7323bfc361 --- /dev/null +++ b/apps/web/public/icons/wayfair.svg @@ -0,0 +1 @@ +Wayfair \ No newline at end of file diff --git a/apps/web/src/components/download-button.tsx b/apps/web/src/components/download-button.tsx new file mode 100644 index 0000000000..939cb81c57 --- /dev/null +++ b/apps/web/src/components/download-button.tsx @@ -0,0 +1,32 @@ +import { cn } from "@hypr/utils"; +import { Link } from "@tanstack/react-router"; + +export function DownloadButton() { + return ( + + Download now + + + + + ); +} diff --git a/apps/web/src/components/github-stars.tsx b/apps/web/src/components/github-stars.tsx new file mode 100644 index 0000000000..c245f32d58 --- /dev/null +++ b/apps/web/src/components/github-stars.tsx @@ -0,0 +1,35 @@ +import { cn } from "@hypr/utils"; +import { Icon } from "@iconify-icon/react"; +import { useQuery } from "@tanstack/react-query"; + +export function GithubStars() { + const LAST_SEEN = 6400; + const ORG_REPO = "fastrepl/hyprnote"; + + const star = useQuery({ + queryKey: ["github-stars"], + queryFn: async () => { + const response = await fetch(`https://api.github.com/repos/${ORG_REPO}`); + const data = await response.json(); + return data.stargazers_count ?? LAST_SEEN; + }, + }); + + const render = (n: number) => n > 1000 ? `${(n / 1000).toFixed(1)}k` : n; + + return ( + + + + ); +} diff --git a/apps/web/src/components/logo-cloud.tsx b/apps/web/src/components/logo-cloud.tsx new file mode 100644 index 0000000000..c6859fc9bd --- /dev/null +++ b/apps/web/src/components/logo-cloud.tsx @@ -0,0 +1,123 @@ +import { cn } from "@hypr/utils"; + +export type Logo = { + src: string; + alt: string; + width?: number; + height?: number; +}; + +type LogoCardProps = React.ComponentProps<"div"> & { + logo: Logo; +}; + +function LogoCard({ logo, className, children, ...props }: LogoCardProps) { + return ( +
+ {logo.alt} + {children} +
+ ); +} + +export function LogoCloud() { + return ( +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+ ); +} diff --git a/apps/web/src/components/social-card.tsx b/apps/web/src/components/social-card.tsx new file mode 100644 index 0000000000..9ba2592380 --- /dev/null +++ b/apps/web/src/components/social-card.tsx @@ -0,0 +1,82 @@ +import { cn } from "@hypr/utils"; + +export type SocialPlatform = "reddit" | "linkedin" | "twitter"; + +export interface SocialCardProps { + platform: SocialPlatform; + author: string; + body: string; + url: string; + className?: string; + // Platform-specific metadata + username?: string; // for Twitter + subreddit?: string; // for Reddit + role?: string; // for LinkedIn + company?: string; // for LinkedIn +} + +export function SocialCard({ + platform, + author, + body, + url, + className, + username, + subreddit, + role, + company, +}: SocialCardProps) { + const platformConfig = { + reddit: { + iconColor: "text-orange-600", + iconPath: + "M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z", + userPrefix: "u/", + subtitle: subreddit ? `r/${subreddit}` : "", + }, + linkedin: { + iconColor: "text-blue-700", + iconPath: + "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z", + userPrefix: "", + subtitle: role && company ? `${role} at ${company}` : "", + }, + twitter: { + iconColor: "text-neutral-900", + iconPath: + "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z", + userPrefix: "@", + subtitle: username || "", + }, + }; + + const config = platformConfig[platform]; + + return ( + +
+
+
+

+ {config.userPrefix} + {author} +

+ {config.subtitle &&

{config.subtitle}

} +
+ + + +
+

{body}

+
+
+ ); +} diff --git a/apps/web/src/components/testimonial-card.tsx b/apps/web/src/components/testimonial-card.tsx new file mode 100644 index 0000000000..585156fa21 --- /dev/null +++ b/apps/web/src/components/testimonial-card.tsx @@ -0,0 +1,22 @@ +export type TestimonialCardProps = { + quote: string; + author: string; + role: string; + company: string; +}; + +export function TestimonialCard({ quote, author, role, company }: TestimonialCardProps) { + return ( +
+
+

"{quote}"

+
+

{author}

+

+ {role} at {company} +

+
+
+
+ ); +} diff --git a/apps/web/src/routes/_view/index.tsx b/apps/web/src/routes/_view/index.tsx index 01d0f746cd..5f6e761f40 100644 --- a/apps/web/src/routes/_view/index.tsx +++ b/apps/web/src/routes/_view/index.tsx @@ -1,9 +1,10 @@ -import { Typewriter } from "@hypr/ui/components/ui/typewriter"; -import { cn } from "@hypr/utils"; - import { Icon } from "@iconify-icon/react"; -import { useQuery } from "@tanstack/react-query"; -import { createFileRoute, Link } from "@tanstack/react-router"; +import { createFileRoute } from "@tanstack/react-router"; + +import { DownloadButton } from "@/components/download-button"; +import { GithubStars } from "@/components/github-stars"; +import { LogoCloud } from "@/components/logo-cloud"; +import { SocialCard } from "@/components/social-card"; export const Route = createFileRoute("/_view/")({ component: Component, @@ -12,30 +13,28 @@ export const Route = createFileRoute("/_view/")({ function Component() { return (
-
+
-
-
-
-

- The AI notepad for{" "} - -

-

- Hyprnote is a notetaking app that listens and summarizes the world around you -

-
+
+
+
+
+

+ The AI notepad for
private meetings +

+

+ Hyprnote listens and summarizes your meetings{" "} +
without sending any voice to remote servers +

+
+ + {/* CTAs */} + -
+
-
+ {/* Video - Mobile First */} +
@@ -53,10 +53,228 @@ function Component() {
+ + {/* Feature Cards Row */} +
+
+
+

Private

+

+ Your notes stay local by default. Sync to a cloud only when you choose. +

+
+
+

Effortless

+

+ A simple notepad that just works—fast, minimal, and distraction-free. +

+
+
+

Flexible

+

+ Use any STT or LLM. Local or cloud. No lock-ins, no forced stack. +

+
+
+ + {/* Video - Desktop (no gap) */} +
+
+
+ +

Demo video coming soon

+
+
+
+
+
+
+ + {/* Social Proof Section */} +
+
+

+ Loved by professionals at +

+ + + + {/* Testimonials - New Grid Layout */} +
+ {/* Mobile: Horizontal scrollable layout */} +
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ + {/* Desktop: Custom grid layout with big and small cards */} +
+ {/* Left column - Big card (row-span-2) */} +
+ +
+ + {/* Middle column - Big card (row-span-2) */} +
+ +
+ + {/* Right column - Small card (top) */} +
+ +
+ + {/* Right column - Small card (bottom) */} +
+ +
+
+
-
+

Built for developers @@ -70,10 +288,10 @@ function Component() { ].map((item, index) => (
@@ -92,11 +310,11 @@ function Component() {
-

- Ready to get started? +

+ Where conversations stay yours

-

- Download Hyprnote today and experience note-taking reimagined. +

+ Start using Hyprnote today and bring clarity to your back-to-back meetings

@@ -109,65 +327,3 @@ function Component() {
); } - -function DownloadButton() { - return ( - - Download now - - - - - ); -} - -function GithubStars() { - const LAST_SEEN = 6400; - const ORG_REPO = "fastrepl/hyprnote"; - - const star = useQuery({ - queryKey: ["github-stars"], - queryFn: async () => { - const response = await fetch(`https://api.github.com/repos/${ORG_REPO}`); - const data = await response.json(); - return data.stargazers_count ?? LAST_SEEN; - }, - }); - - const render = (n: number) => n > 1000 ? `${(n / 1000).toFixed(1)}k` : n; - - return ( - - - - ); -} diff --git a/apps/web/src/routes/_view/route.tsx b/apps/web/src/routes/_view/route.tsx index a087b0a40c..d57667d7fd 100644 --- a/apps/web/src/routes/_view/route.tsx +++ b/apps/web/src/routes/_view/route.tsx @@ -23,23 +23,20 @@ function Component() { function Header() { return (
-
+
-
- H -
- Hyprnote + Hyprnote