+
);
-};
+}
diff --git a/src/components/hero-section.tsx b/src/components/hero-section.tsx
deleted file mode 100644
index 1fa43bd..0000000
--- a/src/components/hero-section.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import { Button } from "@/components/ui/button";
-import { LandingSocialProof } from "./social-proof/landing-social-proof";
-import Link from "next/link";
-import Image from "next/image";
-import PreviewSection from "./preview-section";
-export const avatarItems = [
- {
- imageSrc: "/users/6.png",
- name: "Khang Nguyen Duy",
- },
- {
- imageSrc: "/users/3.png",
- name: "Stan Olery",
- },
- {
- imageSrc: "/users/4.jpeg",
- name: "Julio Santirachi",
- },
- {
- imageSrc: "/users/8.jpeg",
- name: "Cristian Andrei Grigore",
- },
-];
-
-export let HeroSection = () => {
- return (
-
-
-
-
-
- Reduce Mindless Browsing By 10x
-
-
- Get out of the loop and stay mindful when accessing distracting
- websites. No more wasting time for hours unconsciously.
- {/* Stop mindless browsing and take control of your time online */}
-
-
-
-
-
-
- Install Now
-
-
-
-
-
-
-
- );
-};
diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx
deleted file mode 100644
index 5809652..0000000
--- a/src/components/navbar.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-"use client";
-
-import { useState, useEffect } from "react";
-import { ChevronDown, ChevronRight } from "lucide-react";
-import { Button } from "@/components/ui/button";
-
-export const Navbar = () => {
- const [isScrolled, setIsScrolled] = useState(false);
- const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
-
- useEffect(() => {
- const handleScroll = () => {
- setIsScrolled(window.scrollY > 10);
- };
- window.addEventListener("scroll", handleScroll);
- return () => window.removeEventListener("scroll", handleScroll);
- }, []);
-
- const navItems = [{ name: "PRO Version", href: "/pro" }];
-
- return (
-
-
-
-
-
-
- {navItems.map((item) => (
-
- ))}
-
-
-
- Log in
-
- Start now
-
-
-
-
-
-
setIsMobileMenuOpen(!isMobileMenuOpen)}
- className="text-gray-600 hover:text-gray-900 focus:outline-none focus:text-gray-900"
- >
-
-
-
-
-
- {isMobileMenuOpen && (
-
- {navItems.map((item) => (
-
- {item.name}
-
- ))}
-
-
- Log in
-
-
- Start now
-
-
-
-
- )}
-
-
- );
-};
diff --git a/src/components/objections.tsx b/src/components/objections.tsx
deleted file mode 100644
index d8eda2c..0000000
--- a/src/components/objections.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import { FeaturesBento } from "./features-bento";
-import {
- PopiconsHomeLine,
- PopiconsUserCheckDuotone,
- PopiconsCirclePauseDuotone,
- PopiconsCalendarTimeDuotone,
-} from "@popicons/react";
-import Image from "next/image";
-
-const items = [
- {
- title: "Structured Breaks",
- description:
- "When you visit a distracting site, focusmode presents a calming intervention. Breathe, stretch, and decide mindfully how long you want to spend there.",
- header:
,
- className: "md:col-span-2",
- // icon:
,
- },
- {
- title: "Personalized Prompts",
- description:
- "Create your own intervention messages that resonate with you. Choose break durations that fit your workflow. focusmode adapts to you.",
- header:
,
- className: "md:col-span-1",
- // icon:
,
- },
- {
- title: "Automatic Scheduling",
- description:
- "Set focusmode to activate during your most productive hours, and turn off when it's time to unwind. Strike the perfect balance effortlessly.",
- header:
,
- className: "md:col-span-1",
- // icon:
,
- },
-];
-
-export let Objections = () => {
- return (
-
-
-
- {/*
*/}
-
-
- We know what you're thinking
-
-
- Another productivity tool that promises the world but doesn't
- deliver. focusmode is different.
-
-
- It's not about blocking sites entirely, but helping you be
- more intentional with your browsing. With customizable
- interventions and breaks, focusmode puts you back in the
- driver's seat.
-
-
-
-
-
- );
-};
diff --git a/src/components/preview-section.tsx b/src/components/preview-section.tsx
deleted file mode 100644
index 89c0b0d..0000000
--- a/src/components/preview-section.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-"use client";
-
-import dynamic from "next/dynamic";
-import { useMemo, useState } from "react";
-import Video from "next-video";
-import slideInOut from "/videos/1 Clip 2.mp4";
-import holdToComplete from "/videos/0 Clip 1.mp4";
-import pixel from "/videos/2 Clip 3.mp4";
-
-const tabs = ["Slide In Out", "Hold to Complete", "Pixel"];
-
-interface TabProps {
- text: string;
- selected: boolean;
- setSelected: (text: string) => void;
-}
-
-const Tab = ({ text, selected, setSelected }: TabProps) => {
- return (
-
setSelected(text)}
- className={`${
- selected
- ? "text-white"
- : "text-gray-500 hover:text-gray-900 dark:hover:text-gray-100"
- } relative rounded-md px-2 py-1 text-sm font-medium transition-colors`}
- >
- {text}
- {selected && (
-
- )}
-
- );
-};
-
-const ButtonShapeTabs = () => {
- const [selected, setSelected] = useState
(tabs[0]);
-
- const renderVideo = useMemo(() => {
- const videoProps = {
- autoplay: true,
- controls: false,
- muted: true,
- loop: true,
- width: 529,
- height: 298,
- quality: "auto",
- preload: "none" as const,
- };
-
- let src = "";
- let id = "";
-
- if (selected === "Slide In Out") {
- src = "slide";
- id = "slide-video";
- } else if (selected === "Hold to Complete") {
- src = "hold";
- id = "hold-video";
- } else if (selected === "Pixel") {
- src = "pixel";
- id = "pixel-video";
- }
-
- return (
-
-
-
- ;
-
-
- );
- }, [selected]);
-
- return (
-
-
- {tabs.map((tab) => (
-
- ))}
-
- {renderVideo}
-
- );
-};
-
-export default ButtonShapeTabs;
diff --git a/src/components/test-refresh.tsx b/src/components/test-refresh.tsx
deleted file mode 100644
index 5b77c41..0000000
--- a/src/components/test-refresh.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-"use client";
-
-import { useState, useEffect } from "react";
-import { useSession } from "next-auth/react";
-
-export function TestRefresh() {
- const { data: session } = useSession();
- const [accessToken, setAccessToken] = useState(null);
-
- const fetchAccessToken = async () => {
- const res = await fetch("/api/test-refresh");
- const data = await res.json();
- setAccessToken(data.accessToken);
- };
-
- useEffect(() => {
- if (session) {
- fetchAccessToken();
- const interval = setInterval(fetchAccessToken, 10000); // Fetch every 10 seconds
- return () => clearInterval(interval);
- }
- }, [session]);
-
- return (
-
-
Access Token Test
-
Current Access Token: {accessToken}
-
- );
-}
diff --git a/src/components/testimonials.tsx b/src/components/testimonials.tsx
index 1b6ab90..3bde2b8 100644
--- a/src/components/testimonials.tsx
+++ b/src/components/testimonials.tsx
@@ -1,7 +1,9 @@
+"use client";
+
import { InfiniteMovingCards } from "@/components/ui/infinite-moving-cards";
import { Button } from "./ui/button";
import Link from "next/link";
-import { ArrowBigRight, MoveRightIcon } from "lucide-react";
+import { MoveRight } from "lucide-react";
const testimonials = [
{
@@ -30,37 +32,42 @@ const testimonials = [
},
];
-export let Testimonials = () => {
+export function Testimonials() {
return (
-
-
-
-
- Don't take it from us
+
+
+
+
+ Testimonials
+
+
+ Loved by 15,000+ users
-
- See what others have to say.
+
+ See what people are saying on the Chrome Web Store.
+
+
+
+
+
+
+ More reviews
+
+
+
+
-
-
-
- More reviews
-
-
-
+
);
-};
+}
diff --git a/src/components/ui/infinite-moving-cards.tsx b/src/components/ui/infinite-moving-cards.tsx
index ab26a39..de9af46 100644
--- a/src/components/ui/infinite-moving-cards.tsx
+++ b/src/components/ui/infinite-moving-cards.tsx
@@ -87,10 +87,10 @@ export const InfiniteMovingCards = ({
>
{items.map((item, idx) => (
@@ -99,12 +99,12 @@ export const InfiniteMovingCards = ({
aria-hidden="true"
className="user-select-none -z-1 pointer-events-none absolute -left-0.5 -top-0.5 h-[calc(100%_+_4px)] w-[calc(100%_+_4px)]"
>
-
+
{item.quote}
-
+
{item.name}
diff --git a/src/components/v3/analytics-streaks.tsx b/src/components/v3/analytics-streaks.tsx
new file mode 100644
index 0000000..c37b424
--- /dev/null
+++ b/src/components/v3/analytics-streaks.tsx
@@ -0,0 +1,95 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { BarChart3, Flame, Calendar, Shield } from "lucide-react";
+
+const stats = [
+ {
+ icon: Flame,
+ label: "Current Streak",
+ description: "Track consecutive days staying within your limits",
+ },
+ {
+ icon: Calendar,
+ label: "Growth Calendar",
+ description: "Visual 7/30/90-day calendar showing mindful vs missed days",
+ },
+ {
+ icon: BarChart3,
+ label: "Usage Charts",
+ description: "Top 10 domains by time spent with detailed breakdowns",
+ },
+ {
+ icon: Shield,
+ label: "Blocks Prevented",
+ description: "Running counter of how many times FocusMode intervened",
+ },
+];
+
+export function AnalyticsStreaks() {
+ return (
+
+
+
+
+
+
+ Analytics & Streaks
+
+
+ Track your progress, build momentum
+
+
+ A built-in screen time tracker for Chrome that gamifies your
+ focus journey. Watch your streak grow, see which sites consume
+ your time, and celebrate your consistency.
+
+
+
+
+ {stats.map((stat) => (
+
+
+
+
+
+
{stat.label}
+
{stat.description}
+
+
+ ))}
+
+
+
+
+ Dashboard screenshot placeholder
+
+
+
+
+ );
+}
diff --git a/src/components/v3/competitors-section.tsx b/src/components/v3/competitors-section.tsx
new file mode 100644
index 0000000..a16bec0
--- /dev/null
+++ b/src/components/v3/competitors-section.tsx
@@ -0,0 +1,131 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { Check, X } from "lucide-react";
+
+const competitors = [
+ {
+ name: "FocusMode",
+ highlight: true,
+ price: "$20.99 one-time",
+ interventions: "4 types",
+ breaks: true,
+ streaks: true,
+ analytics: true,
+ privacy: true,
+ },
+ {
+ name: "Freedom",
+ highlight: false,
+ price: "$8.99/mo",
+ interventions: "Hard block",
+ breaks: false,
+ streaks: false,
+ analytics: false,
+ privacy: false,
+ },
+ {
+ name: "Cold Turkey",
+ highlight: false,
+ price: "$39 one-time",
+ interventions: "Hard block",
+ breaks: false,
+ streaks: false,
+ analytics: false,
+ privacy: true,
+ },
+ {
+ name: "LeechBlock",
+ highlight: false,
+ price: "Free",
+ interventions: "Block page",
+ breaks: false,
+ streaks: false,
+ analytics: false,
+ privacy: true,
+ },
+];
+
+const rows = [
+ { label: "Price", key: "price" as const },
+ { label: "Intervention types", key: "interventions" as const },
+ { label: "Break management", key: "breaks" as const },
+ { label: "Streak tracking", key: "streaks" as const },
+ { label: "Analytics dashboard", key: "analytics" as const },
+ { label: "Privacy-first", key: "privacy" as const },
+];
+
+function CellValue({ value }: { value: string | boolean }) {
+ if (typeof value === "string") return {value};
+ return value ? (
+
+ ) : (
+
+ );
+}
+
+export function CompetitorsSection() {
+ return (
+
+
+
+ Compare
+
+ Why FocusMode?
+
+
+ The only website blocker that uses mindful interventions instead of
+ brute-force blocking.
+
+
+
+
+
+
+
+ | Feature |
+ {competitors.map((c) => (
+
+ {c.name}
+ |
+ ))}
+
+
+
+ {rows.map((row) => (
+
+ | {row.label} |
+ {competitors.map((c) => (
+
+
+ |
+ ))}
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/src/components/v3/cta-section.tsx b/src/components/v3/cta-section.tsx
new file mode 100644
index 0000000..d254607
--- /dev/null
+++ b/src/components/v3/cta-section.tsx
@@ -0,0 +1,59 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { Button } from "@/components/ui/button";
+import Link from "next/link";
+import Image from "next/image";
+import { Leaf } from "lucide-react";
+
+const CHROME_STORE_URL =
+ "https://chromewebstore.google.com/detail/focus-mode-stay-focused-b/ollmdedpknmlcdmpehclmgbogpifahdc";
+const PRO_URL = "https://polar.sh/focusmode";
+
+export function CtaSection() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ Start Browsing Mindfully
+
+
+ Join 15,000+ people who've reclaimed their focus. Install
+ FocusMode for free and experience the difference gentle
+ interventions make.
+
+
+
+
+
+
+ Install Free
+
+
+
+
+ Get PRO — $20.99
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/v3/faq-section.tsx b/src/components/v3/faq-section.tsx
new file mode 100644
index 0000000..18db34c
--- /dev/null
+++ b/src/components/v3/faq-section.tsx
@@ -0,0 +1,104 @@
+"use client";
+
+import { useState } from "react";
+import { ChevronDown } from "lucide-react";
+import { cn } from "@/lib/utils";
+
+const faqs = [
+ {
+ question: "What is FocusMode?",
+ answer:
+ "FocusMode is a Chrome extension that reduces mindless browsing through calming interventions instead of hard blocks. Rather than simply preventing access to websites, it uses 4 unique mindfulness-based approaches to help you make conscious decisions about your browsing habits.",
+ },
+ {
+ question: "Is FocusMode free?",
+ answer:
+ "Yes, FocusMode has a free tier that includes 1 group and all 4 intervention types (hold, slide, pixel, and instant). The PRO version is a one-time payment of $20.99 that unlocks unlimited groups, full analytics, flexible break durations, and data export. No subscription required.",
+ },
+ {
+ question: "How is FocusMode different from other website blockers?",
+ answer:
+ "FocusMode uses 4 unique mindfulness-based interventions (hold, slide, pixel, and instant) instead of simply blocking sites. It respects user autonomy with flexible breaks and progressive escalation, encouraging mindful browsing rather than rigid restriction.",
+ },
+ {
+ question: "Does FocusMode work on all websites?",
+ answer:
+ "Yes, FocusMode uses Shadow DOM isolation to work on any website without style conflicts. This ensures the intervention overlays display correctly regardless of a website's existing CSS or JavaScript.",
+ },
+ {
+ question: "Can I use FocusMode during work hours only?",
+ answer:
+ "Yes, schedule-based triggering lets you activate blocking during specific time windows. You can configure FocusMode to only intervene during your work hours or study sessions, and browse freely outside those windows.",
+ },
+ {
+ question: "What happens when I exceed my break limit?",
+ answer:
+ "Optional escalation increases intervention duration, removes easy interventions, and shows streak warnings. This progressive approach helps reinforce mindful browsing habits without being overly punitive. You control what escalation behaviors are enabled per group.",
+ },
+ {
+ question: "Does FocusMode collect my data?",
+ answer:
+ "No, all data is stored locally in your browser. FocusMode is privacy-respecting with no external tracking. Your browsing data never leaves your device.",
+ },
+ {
+ question: "Can I block specific pages instead of entire websites?",
+ answer:
+ "Yes, FocusMode supports path-based blocking with wildcards. For example, you can block youtube.com/shorts while still allowing access to youtube.com for other content. You can also use exclusion patterns like !allowed.example.com.",
+ },
+];
+
+export function FaqSection() {
+ const [openIndex, setOpenIndex] = useState(null);
+
+ return (
+
+
+
+
+ FAQ
+
+
+ Frequently asked questions
+
+
+ Everything you need to know about FocusMode.
+
+
+
+
+ {faqs.map((faq, index) => (
+
+
+ setOpenIndex(openIndex === index ? null : index)
+ }
+ className="flex items-center justify-between w-full p-5 text-left hover:bg-muted/50 transition-colors"
+ >
+ {faq.question}
+
+
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/v3/feature-deep-dive.tsx b/src/components/v3/feature-deep-dive.tsx
new file mode 100644
index 0000000..23e9242
--- /dev/null
+++ b/src/components/v3/feature-deep-dive.tsx
@@ -0,0 +1,114 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { FolderOpen, Clock, Timer, TrendingUp, Leaf } from "lucide-react";
+
+const features = [
+ {
+ icon: FolderOpen,
+ title: "Group-Based Blocking",
+ description:
+ "Organize blocked sites into logical groups like Social Media, News, or Video. Each group gets its own intervention settings, break limits, and trigger rules. Use wildcards, path-based blocking, and exclusion patterns for granular control.",
+ highlights: [
+ "Unlimited groups with PRO",
+ "Wildcard URL matching",
+ "Path-based blocking (e.g., youtube.com/shorts)",
+ ],
+ },
+ {
+ icon: Clock,
+ title: "Smart Scheduling",
+ description:
+ "Three trigger modes let you control exactly when interventions activate. Always On for constant mindfulness, On Schedule for work-hours-only blocking, or After Usage to allow a daily time budget before interventions begin.",
+ highlights: [
+ "Always On, Scheduled, or Usage-based",
+ "Multiple schedules per group",
+ "Daily time limits in minutes",
+ ],
+ },
+ {
+ icon: Timer,
+ title: "Break Management",
+ description:
+ "When you choose to take a break, pick a duration that fits your needs \u2014 5, 10, 15, or 30 minutes. A badge countdown shows remaining time, and sites block again automatically when your break ends.",
+ highlights: [
+ "Flexible break durations (PRO)",
+ "Daily break limits per group",
+ "Badge countdown timer",
+ ],
+ },
+ {
+ icon: TrendingUp,
+ title: "Progressive Escalation",
+ description:
+ "When you exceed your limits, FocusMode can optionally make interventions harder \u2014 doubling wait times, removing easy intervention types, and showing streak warnings. Firm but encouraging, never punitive.",
+ highlights: [
+ "Opt-in per group",
+ "Double intervention duration",
+ "Streak warning banners",
+ ],
+ },
+];
+
+export function FeatureDeepDive() {
+ return (
+
+
+
+ Features
+
+ Built for real focus habits
+
+
+ A digital wellness Chrome extension with the tools you need to build
+ lasting focus habits — not just block websites.
+
+
+
+
+ {features.map((feature, index) => (
+
+
+
+
+
+
+
{feature.title}
+
+
{feature.description}
+
+ {feature.highlights.map((highlight) => (
+ -
+
+ {highlight}
+
+ ))}
+
+
+
+
+ Screenshot placeholder
+
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/v3/hero-section.tsx b/src/components/v3/hero-section.tsx
new file mode 100644
index 0000000..ed8b1ed
--- /dev/null
+++ b/src/components/v3/hero-section.tsx
@@ -0,0 +1,87 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { Button } from "@/components/ui/button";
+import { Badge } from "@/components/ui/badge";
+import Link from "next/link";
+import Image from "next/image";
+import { Star } from "lucide-react";
+
+const CHROME_STORE_URL =
+ "https://chromewebstore.google.com/detail/focus-mode-stay-focused-b/ollmdedpknmlcdmpehclmgbogpifahdc";
+
+export function HeroSection() {
+ return (
+
+
+
+
+
+
+ v3.0 — Complete Rewrite
+
+
+
+
+
+
+ Block Distracting Websites{" "}
+ Mindfully
+
+
+
+ The Chrome extension that helps you reduce screen time without going
+ cold turkey. Gentle interventions, not hard blocks — used by{" "}
+ 15,000+ people to browse with intention.
+
+
+
+
+
+
+ Install Free
+
+
+
+ See How It Works
+
+
+
+
+
+ {["/users/6.png", "/users/3.png", "/users/4.jpeg", "/users/8.jpeg"].map((src, i) => (
+
+ ))}
+
+
+ {[...Array(5)].map((_, i) => (
+
+ ))}
+
+ 4.7/5 from 15k+ users
+
+
+
+
+ );
+}
diff --git a/src/components/v3/how-it-works.tsx b/src/components/v3/how-it-works.tsx
new file mode 100644
index 0000000..457a4f3
--- /dev/null
+++ b/src/components/v3/how-it-works.tsx
@@ -0,0 +1,77 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { Leaf, Eye, Coffee } from "lucide-react";
+
+const steps = [
+ {
+ icon: Eye,
+ title: "Visit a blocked site",
+ description:
+ "When you navigate to a distracting website, FocusMode gently intervenes with a calming overlay instead of a harsh block screen.",
+ },
+ {
+ icon: Leaf,
+ title: "Complete a mindful intervention",
+ description:
+ "Choose from 4 intervention types — hold, slide, watch pixels bloom, or pause. Each one creates a moment of awareness before you proceed.",
+ },
+ {
+ icon: Coffee,
+ title: "Take a break or return to focus",
+ description:
+ "Decide mindfully: take a timed break (5-30 min) to browse, or return to what matters. Your choice, your pace.",
+ },
+];
+
+export function HowItWorks() {
+ return (
+
+
+
+
+ How It Works
+
+
+ Mindful browsing in three steps
+
+
+ FocusMode doesn't lock you out. It creates a moment of awareness so
+ you can make intentional choices about your screen time.
+
+
+
+
+ {steps.map((step, index) => (
+
+
+
+
+
+ {index + 1}
+
{step.title}
+
+ {step.description}
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/v3/intervention-types.tsx b/src/components/v3/intervention-types.tsx
new file mode 100644
index 0000000..1daa626
--- /dev/null
+++ b/src/components/v3/intervention-types.tsx
@@ -0,0 +1,99 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { Hand, Waves, Grid3X3, Pause } from "lucide-react";
+
+const interventions = [
+ {
+ icon: Pause,
+ name: "Instant Block",
+ tagline: "A moment of stillness",
+ description:
+ "A calm, immediate pause with a leaf icon and pulsing animation. Zero-friction reflection point before choosing to continue or return to focus.",
+ color: "bg-sage-50 border-sage-200 dark:bg-sage-900/30 dark:border-sage-700",
+ iconColor: "text-sage-400",
+ },
+ {
+ icon: Hand,
+ name: "Hold to Complete",
+ tagline: "Cultivate patience",
+ description:
+ "Press and hold a circular button for 3-15 seconds. Watch the SVG progress ring fill as you build the discipline to wait before browsing.",
+ color: "bg-teal-50 border-teal-200 dark:bg-teal-900/30 dark:border-teal-700",
+ iconColor: "text-teal-400",
+ },
+ {
+ icon: Waves,
+ name: "Slide to Continue",
+ tagline: "Flow with intention",
+ description:
+ "A full-screen gradient animation slides across your screen over 3-15 seconds. A meditative, passive observation experience before you proceed.",
+ color: "bg-sage-50 border-sage-200 dark:bg-sage-900/30 dark:border-sage-700",
+ iconColor: "text-sage-400",
+ },
+ {
+ icon: Grid3X3,
+ name: "Pixel Garden",
+ tagline: "Watch the garden grow",
+ description:
+ "400 pixels bloom across your screen in a randomized 20x20 grid with gradient colors. An organic visual experience that makes waiting feel creative.",
+ color: "bg-teal-50 border-teal-200 dark:bg-teal-900/30 dark:border-teal-700",
+ iconColor: "text-teal-400",
+ },
+];
+
+export function InterventionTypes() {
+ return (
+
+
+
+
+ 4 Intervention Types
+
+
+ Friction, not force
+
+
+ Each intervention uses a different psychological approach to prevent
+ habituation. Rotate between them to stay mindful.
+
+
+
+
+ {interventions.map((item) => (
+
+
+
+
+
+
+
{item.name}
+
{item.tagline}
+
+
+ {item.description}
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/v3/json-ld-schemas.tsx b/src/components/v3/json-ld-schemas.tsx
new file mode 100644
index 0000000..d94f315
--- /dev/null
+++ b/src/components/v3/json-ld-schemas.tsx
@@ -0,0 +1,220 @@
+const organizationSchema = {
+ "@context": "https://schema.org",
+ "@type": "Organization",
+ "@id": "https://focusmode.app/#organization",
+ name: "FocusMode",
+ url: "https://focusmode.app",
+ logo: {
+ "@type": "ImageObject",
+ url: "https://focusmode.app/focusmode-logo.png",
+ width: 128,
+ height: 128,
+ },
+ email: "focusmode.app@gmail.com",
+ sameAs: [
+ "https://chromewebstore.google.com/detail/focus-mode-stay-focused-b/ollmdedpknmlcdmpehclmgbogpifahdc",
+ ],
+};
+
+const websiteSchema = {
+ "@context": "https://schema.org",
+ "@type": "WebSite",
+ "@id": "https://focusmode.app/#website",
+ name: "FocusMode",
+ url: "https://focusmode.app",
+ publisher: { "@id": "https://focusmode.app/#organization" },
+ description:
+ "Reduce mindless browsing with gentle interventions. A Chrome extension for mindful, intentional browsing.",
+ inLanguage: "en-US",
+};
+
+const softwareSchema = {
+ "@context": "https://schema.org",
+ "@type": "SoftwareApplication",
+ "@id": "https://focusmode.app/#software",
+ name: "FocusMode",
+ description:
+ "A Chrome extension that reduces mindless browsing through calming interventions instead of hard blocks. 4 intervention types, break management, streak tracking, and analytics.",
+ url: "https://focusmode.app",
+ applicationCategory: "BrowserApplication",
+ operatingSystem: "Chrome",
+ browserRequirements: "Requires Google Chrome",
+ softwareVersion: "3.0",
+ installUrl:
+ "https://chromewebstore.google.com/detail/focus-mode-stay-focused-b/ollmdedpknmlcdmpehclmgbogpifahdc",
+ author: { "@id": "https://focusmode.app/#organization" },
+ aggregateRating: {
+ "@type": "AggregateRating",
+ ratingValue: "4.7",
+ bestRating: "5",
+ worstRating: "1",
+ ratingCount: "15000",
+ },
+ offers: [
+ {
+ "@type": "Offer",
+ name: "Free",
+ price: "0",
+ priceCurrency: "USD",
+ description: "1 group, all 4 intervention types, 5-min breaks",
+ availability: "https://schema.org/InStock",
+ },
+ {
+ "@type": "Offer",
+ name: "PRO Lifetime",
+ price: "20.99",
+ priceCurrency: "USD",
+ description:
+ "Unlimited groups, all break durations, full analytics, data export",
+ availability: "https://schema.org/InStock",
+ url: "https://focusmode.app/pricing",
+ },
+ ],
+ featureList: [
+ "4 mindful intervention types",
+ "Group-based website blocking",
+ "Schedule-based triggering",
+ "Usage-based triggering",
+ "Break management with escalation",
+ "Mindfulness streak tracking",
+ "Analytics dashboard",
+ "Path-based blocking with wildcards",
+ "Shadow DOM isolation",
+ "Privacy-respecting local storage",
+ ],
+};
+
+const breadcrumbSchema = {
+ "@context": "https://schema.org",
+ "@type": "BreadcrumbList",
+ itemListElement: [
+ {
+ "@type": "ListItem",
+ position: 1,
+ name: "Home",
+ item: "https://focusmode.app/",
+ },
+ {
+ "@type": "ListItem",
+ position: 2,
+ name: "Pricing",
+ item: "https://focusmode.app/pricing/",
+ },
+ {
+ "@type": "ListItem",
+ position: 3,
+ name: "FAQ",
+ item: "https://focusmode.app/faq/",
+ },
+ {
+ "@type": "ListItem",
+ position: 4,
+ name: "Changelog",
+ item: "https://focusmode.app/changelog/",
+ },
+ {
+ "@type": "ListItem",
+ position: 5,
+ name: "Privacy Policy",
+ item: "https://focusmode.app/privacy-policy/",
+ },
+ ],
+};
+
+const faqSchema = {
+ "@context": "https://schema.org",
+ "@type": "FAQPage",
+ mainEntity: [
+ {
+ "@type": "Question",
+ name: "What is FocusMode?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "FocusMode is a Chrome extension that reduces mindless browsing through calming interventions instead of hard blocks. Rather than simply preventing access to websites, it uses 4 unique mindfulness-based approaches to help you make conscious decisions about your browsing habits.",
+ },
+ },
+ {
+ "@type": "Question",
+ name: "Is FocusMode free?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "Yes, FocusMode has a free tier that includes 1 group and all 4 intervention types (hold, slide, pixel, and instant). The PRO version is a one-time payment of $20.99 that unlocks unlimited groups, full analytics, flexible break durations, and data export. No subscription required.",
+ },
+ },
+ {
+ "@type": "Question",
+ name: "How is FocusMode different from other website blockers?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "FocusMode uses 4 unique mindfulness-based interventions (hold, slide, pixel, and instant) instead of simply blocking sites. It respects user autonomy with flexible breaks and progressive escalation, encouraging mindful browsing rather than rigid restriction.",
+ },
+ },
+ {
+ "@type": "Question",
+ name: "Does FocusMode work on all websites?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "Yes, FocusMode uses Shadow DOM isolation to work on any website without style conflicts. This ensures the intervention overlays display correctly regardless of a website's existing CSS or JavaScript.",
+ },
+ },
+ {
+ "@type": "Question",
+ name: "Can I use FocusMode during work hours only?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "Yes, schedule-based triggering lets you activate blocking during specific time windows. You can configure FocusMode to only intervene during your work hours or study sessions, and browse freely outside those windows.",
+ },
+ },
+ {
+ "@type": "Question",
+ name: "What happens when I exceed my break limit?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "Optional escalation increases intervention duration, removes easy interventions, and shows streak warnings. This progressive approach helps reinforce mindful browsing habits without being overly punitive. You control what escalation behaviors are enabled per group.",
+ },
+ },
+ {
+ "@type": "Question",
+ name: "Does FocusMode collect my data?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "No, all data is stored locally in your browser. FocusMode is privacy-respecting with no external tracking. Your browsing data never leaves your device.",
+ },
+ },
+ {
+ "@type": "Question",
+ name: "Can I block specific pages instead of entire websites?",
+ acceptedAnswer: {
+ "@type": "Answer",
+ text: "Yes, FocusMode supports path-based blocking with wildcards. For example, you can block youtube.com/shorts while still allowing access to youtube.com for other content. You can also use exclusion patterns like !allowed.example.com.",
+ },
+ },
+ ],
+};
+
+export function JsonLdSchemas() {
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/v3/pricing-section.tsx b/src/components/v3/pricing-section.tsx
new file mode 100644
index 0000000..ca56f87
--- /dev/null
+++ b/src/components/v3/pricing-section.tsx
@@ -0,0 +1,130 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { Button } from "@/components/ui/button";
+import { Check, X } from "lucide-react";
+import Link from "next/link";
+import Image from "next/image";
+
+const CHROME_STORE_URL =
+ "https://chromewebstore.google.com/detail/focus-mode-stay-focused-b/ollmdedpknmlcdmpehclmgbogpifahdc";
+const PRO_URL = "https://polar.sh/focusmode";
+
+const features = [
+ { name: "Focus groups", free: "1", pro: "Unlimited" },
+ { name: "Intervention types", free: "All 4", pro: "All 4" },
+ { name: "Break durations", free: "5 min", pro: "5 / 10 / 15 / 30 min" },
+ { name: "Schedule-based triggering", free: true, pro: true },
+ { name: "Usage-based triggering", free: true, pro: true },
+ { name: "Escalation system", free: true, pro: true },
+ { name: "Streak tracking", free: true, pro: true },
+ { name: "Analytics dashboard", free: "Basic", pro: "Full" },
+ { name: "Website usage charts", free: false, pro: true },
+ { name: "Data export/import", free: false, pro: true },
+ { name: "Custom intervention messages", free: true, pro: true },
+ { name: "Dark mode", free: true, pro: true },
+];
+
+function FeatureValue({ value }: { value: boolean | string }) {
+ if (typeof value === "string") {
+ return {value};
+ }
+ return value ? (
+
+ ) : (
+
+ );
+}
+
+export function PricingSection() {
+ return (
+
+
+
+ Pricing
+
+ Free to start, one-time to unlock
+
+
+ No subscriptions. No recurring fees. Pay once, own it forever.
+
+
+
+
+ {/* Free tier */}
+
+
+
Free
+
+ $0
+ forever
+
+
+
+
+
+ Install Free
+
+
+
+ {features.map((f) => (
+ -
+ {f.name}
+
+
+ ))}
+
+
+
+ {/* PRO tier */}
+
+
+
+ LIFETIME
+
+
+
+
PRO
+
+ $20.99
+ one-time
+
+
+ Not $8.99/month — pay once, own it forever
+
+
+
+ Get PRO
+
+
+ {features.map((f) => (
+ -
+ {f.name}
+
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/src/lib/font.ts b/src/lib/font.ts
deleted file mode 100644
index 8d30878..0000000
--- a/src/lib/font.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import localFont from "next/font/local";
-
-export const eudoxusSans = localFont({
- src: [
- {
- path: "../../public/fonts/EudoxusSans-Light.woff2",
- weight: "300",
- style: "normal",
- },
- {
- path: "../../public/fonts/EudoxusSans-Regular.woff2",
- weight: "400",
- style: "normal",
- },
- {
- path: "../../public/fonts/EudoxusSans-Medium.woff2",
- weight: "500",
- style: "normal",
- },
- // Add more variations as needed
- ],
- variable: "--font-eudoxus-sans",
-});
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 84fc67b..383c7f5 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -21,6 +21,10 @@ const config = {
},
},
extend: {
+ fontFamily: {
+ sans: ["var(--font-body)", "system-ui", "sans-serif"],
+ heading: ["var(--font-heading)", "Georgia", "serif"],
+ },
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
@@ -55,6 +59,30 @@ const config = {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
+ sage: {
+ 50: "#f0f7f4",
+ 100: "#d9ede2",
+ 200: "#b5dbc8",
+ 300: "#85c2a5",
+ 400: "#4A9075",
+ 500: "#3d7a63",
+ 600: "#2f6150",
+ 700: "#274e41",
+ 800: "#213f35",
+ 900: "#1c352d",
+ },
+ teal: {
+ 50: "#f0f9fa",
+ 100: "#d4eff1",
+ 200: "#aee0e4",
+ 300: "#6AABB0",
+ 400: "#4d9499",
+ 500: "#3d7a7f",
+ 600: "#326267",
+ 700: "#2b5054",
+ 800: "#274245",
+ 900: "#24383b",
+ },
},
borderRadius: {
lg: "var(--radius)",
@@ -75,12 +103,17 @@ const config = {
transform: "translate(calc(-50% - 0.5rem))",
},
},
+ "fade-up": {
+ "0%": { opacity: "0", transform: "translateY(20px)" },
+ "100%": { opacity: "1", transform: "translateY(0)" },
+ },
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
scroll:
"scroll var(--animation-duration, 40s) var(--animation-direction, forwards) linear infinite",
+ "fade-up": "fade-up 0.5s ease-out forwards",
},
},
},
diff --git a/video.d.ts b/video.d.ts
deleted file mode 100644
index 608aa4a..0000000
--- a/video.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/videos/0 Clip 1.mp4.json b/videos/0 Clip 1.mp4.json
deleted file mode 100644
index 15f46f5..0000000
--- a/videos/0 Clip 1.mp4.json
+++ /dev/null
@@ -1 +0,0 @@
-{"status":"ready","originalFilePath":"videos/0 Clip 1.mp4","provider":"mux","providerMetadata":{"mux":{"uploadId":"72ILVMqwQv2yvEaxA100WUESjdEJXt7wSLSvW01SG13pc","assetId":"LZmq01lRoI001qjx5Ji016iBdXVQi00BuPjhZ8XA01xj9K7U","playbackId":"g94z6JgTLmF2QpHHCgeuyl2d301j00MWN4YXKydSedT01M"}},"createdAt":1729060576195,"updatedAt":1729225482967,"size":2264717,"sources":[{"src":"https://stream.mux.com/g94z6JgTLmF2QpHHCgeuyl2d301j00MWN4YXKydSedT01M.m3u8","type":"application/x-mpegURL"}],"poster":"https://image.mux.com/g94z6JgTLmF2QpHHCgeuyl2d301j00MWN4YXKydSedT01M/thumbnail.webp","blurDataURL":"data:image/webp;base64,UklGRnAAAABXRUJQVlA4IGQAAAAQAgCdASoQAAkAAQAcJZwCdAEDfbX6DgYAAP7/au2p+b2WeH/3Vsm9/7m58be5z075zGust1VvT/om79/lVpZn/BTYXphOcje674ee5aXxzRCt+xbR76Nw6n1anaJvy/RFAAAA"}
\ No newline at end of file
diff --git a/videos/1 Clip 2.mp4.json b/videos/1 Clip 2.mp4.json
deleted file mode 100644
index 4351e91..0000000
--- a/videos/1 Clip 2.mp4.json
+++ /dev/null
@@ -1 +0,0 @@
-{"status":"ready","originalFilePath":"videos/1 Clip 2.mp4","provider":"mux","providerMetadata":{"mux":{"uploadId":"wncPBGIhIvsUhCqXNDa6EzJL55zOejZbEEcErkbKvIs","assetId":"00uGt4BKbS00ptNjGZqPX00jMjkrPW6GIlobQ3usXe8mr4","playbackId":"6HPS01AK6XXyKySS6zsRVugHps3D8BKpLiDxgEsca3kk"}},"createdAt":1729060576195,"updatedAt":1729225483211,"size":2931257,"sources":[{"src":"https://stream.mux.com/6HPS01AK6XXyKySS6zsRVugHps3D8BKpLiDxgEsca3kk.m3u8","type":"application/x-mpegURL"}],"poster":"https://image.mux.com/6HPS01AK6XXyKySS6zsRVugHps3D8BKpLiDxgEsca3kk/thumbnail.webp","blurDataURL":"data:image/webp;base64,UklGRlwAAABXRUJQVlA4IFAAAAAQAgCdASoQAAkAAQAcJZwCdAD6mlPDEfCAAP7/au/RToNIytSjBNzFRtd4GnNEd/ph5X20nyd9Dm/Y9O5gaGKX3YHZMMCKAIHADIlQkAAAAA=="}
\ No newline at end of file
diff --git a/videos/2 Clip 3.mp4.json b/videos/2 Clip 3.mp4.json
deleted file mode 100644
index 063ab22..0000000
--- a/videos/2 Clip 3.mp4.json
+++ /dev/null
@@ -1 +0,0 @@
-{"status":"ready","originalFilePath":"videos/2 Clip 3.mp4","provider":"mux","providerMetadata":{"mux":{"uploadId":"UG02LmfF901wXyYfackTbu01mTYLowKlx3s3vOkHTlCs4c","assetId":"OiXYDKgNcbMoe1RvFAvRWRvMjfx1YG9UQezrEkseG024","playbackId":"XEd299MyEPtdsIRGTdGyPLGflBO8tWbfevXBy1HB31k"}},"createdAt":1729060576195,"updatedAt":1729225483028,"size":2906688,"sources":[{"src":"https://stream.mux.com/XEd299MyEPtdsIRGTdGyPLGflBO8tWbfevXBy1HB31k.m3u8","type":"application/x-mpegURL"}],"poster":"https://image.mux.com/XEd299MyEPtdsIRGTdGyPLGflBO8tWbfevXBy1HB31k/thumbnail.webp","blurDataURL":"data:image/webp;base64,UklGRlIAAABXRUJQVlA4IEYAAAAQAgCdASoQAAkAAQAcJaQC7AEQUKFcwNYAAP7/imIaUPLsviW64Lu95HvgR+pOuvvpylroYKnKaCIu1YgABocAIoMsYAAA"}
\ No newline at end of file