Add SEO comparison landing pages and footer compare links.

Introduces dynamic marketing comparison routes, competitor data, and Compare sections on the homepage and marketing footer.
This commit is contained in:
yusufipk
2026-06-14 16:36:26 +02:00
parent d301f3d808
commit 51257e004f
14 changed files with 2248 additions and 25 deletions
+32 -25
View File
@@ -2,6 +2,7 @@
import Image from 'next/image';
import Link from 'next/link';
import { MarketingCompareLinks } from '@/components/marketing/marketing-compare-links';
import { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import {
@@ -880,35 +881,41 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) {
</main>
<footer className="border-t border-border bg-background px-4 py-8 sm:px-6 lg:px-8">
<div className="mx-auto flex max-w-[1200px] flex-col items-center justify-between gap-4 sm:flex-row">
<div className="flex items-center gap-2">
<Video className="h-4 w-4 text-primary" />
<div className="mx-auto grid max-w-[1200px] gap-8 sm:grid-cols-2 lg:grid-cols-3">
<div className="flex items-start gap-2">
<Video className="mt-0.5 h-4 w-4 shrink-0 text-primary" />
<span className="font-mono text-xs text-muted-foreground">
© 2026 IPEK TECH LLC. All rights reserved.
</span>
</div>
<div className="flex flex-wrap justify-center gap-4">
<a
href="mailto:[email protected]"
className="text-xs text-muted-foreground hover:text-foreground"
>
info@open-frame.net
</a>
<a
href="https://github.com/yusufipk/OpenFrame"
className="text-xs text-muted-foreground hover:text-foreground"
>
GitHub
</a>
<Link href="/terms" className="text-xs text-muted-foreground hover:text-foreground">
Terms
</Link>
<Link href="/privacy" className="text-xs text-muted-foreground hover:text-foreground">
Privacy
</Link>
<Link href="/refund" className="text-xs text-muted-foreground hover:text-foreground">
Refund Policy
</Link>
<MarketingCompareLinks />
<div className="flex flex-col gap-2">
<span className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground">
Legal
</span>
<div className="flex flex-col gap-1.5">
<a
href="mailto:[email protected]"
className="text-xs text-muted-foreground hover:text-foreground"
>
info@open-frame.net
</a>
<a
href="https://github.com/yusufipk/OpenFrame"
className="text-xs text-muted-foreground hover:text-foreground"
>
GitHub
</a>
<Link href="/terms" className="text-xs text-muted-foreground hover:text-foreground">
Terms
</Link>
<Link href="/privacy" className="text-xs text-muted-foreground hover:text-foreground">
Privacy
</Link>
<Link href="/refund" className="text-xs text-muted-foreground hover:text-foreground">
Refund Policy
</Link>
</div>
</div>
</div>
</footer>
+224
View File
@@ -0,0 +1,224 @@
import Link from 'next/link';
import { ArrowRight, Github, MoveRight } from 'lucide-react';
import { FeatureComparisonTable } from '@/components/marketing/feature-comparison-table';
import { MarketingFooter } from '@/components/marketing/marketing-footer';
import { MarketingHeader } from '@/components/marketing/marketing-header';
import { PricingComparison } from '@/components/marketing/pricing-comparison';
import { ProductVisual } from '@/components/marketing/product-visual';
import type { ComparisonPageDefinition } from '@/lib/marketing/comparison-types';
import { getCompetitorName, comparisonPageMap } from '@/lib/marketing/comparison-pages';
import { seoConfig } from '@/lib/seo';
interface ComparisonPageProps {
page: ComparisonPageDefinition;
isLoggedIn: boolean;
}
export function ComparisonPage({ page, isLoggedIn }: ComparisonPageProps) {
const hostedCtaHref = isLoggedIn ? '/dashboard' : '/register';
const competitorName = getCompetitorName(page) ?? 'Alternatives';
const relatedSlugs = page.relatedSlugs.filter((slug) => slug in comparisonPageMap);
return (
<div className="min-h-screen bg-background text-foreground font-sans">
<MarketingHeader isLoggedIn={isLoggedIn} />
<main>
<section className="border-b border-border px-4 py-16 sm:px-6 lg:px-8 lg:py-24">
<div className="mx-auto grid w-full max-w-[1200px] gap-12 lg:grid-cols-[1.1fr_0.9fr] lg:items-center">
<div>
<p className="text-xs font-medium uppercase tracking-[0.16em] text-primary">
{page.eyebrow}
</p>
<h1 className="mt-4 text-4xl font-semibold tracking-[-0.03em] md:text-6xl">
{page.headline}
</h1>
<p className="mt-6 max-w-2xl text-base text-muted-foreground md:text-lg">
{page.subheadline}
</p>
<p className="mt-4 max-w-2xl border border-primary/30 bg-primary/5 px-4 py-3 text-sm text-foreground/90 md:text-base">
<span className="font-medium text-primary">No per-member or guest fees.</span> One
$10/month hosted plan covers your whole team and every client reviewer link.
</p>
<div className="mt-8 flex flex-col gap-3 sm:flex-row">
<Link
href={hostedCtaHref}
className="group relative isolate inline-flex h-12 items-center justify-center overflow-hidden border border-primary bg-primary px-8 text-sm font-medium text-primary-foreground transition-transform duration-300 hover:scale-[1.02]"
>
Start free trial
<MoveRight className="ml-2 h-4 w-4 transition-transform group-hover:translate-x-1" />
</Link>
<a
href={seoConfig.githubUrl}
target="_blank"
rel="noreferrer"
className="inline-flex h-12 items-center justify-center border border-border bg-background px-8 text-sm font-medium text-foreground transition-colors hover:bg-card"
>
<Github className="mr-2 h-4 w-4" />
View GitHub
</a>
</div>
</div>
<ProductVisual variant={page.visualVariant} />
</div>
</section>
<section className="border-b border-border px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
<div className="mx-auto w-full max-w-[1200px]">
<h2 className="text-3xl font-semibold tracking-[-0.02em] md:text-4xl">
{page.solutionTitle}
</h2>
<p className="mt-4 max-w-3xl text-base text-muted-foreground md:text-lg">
{page.solutionNarrative}
</p>
</div>
</section>
<section className="border-b border-border bg-background px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
<div className="mx-auto grid w-full max-w-[1200px] gap-8 lg:grid-cols-2">
<div className="border border-primary/30 bg-primary/5 p-6">
<h3 className="text-xl font-semibold">Where OpenFrame fits best</h3>
<ul className="mt-4 space-y-3 text-sm text-foreground/90 md:text-base">
{page.bestForOpenFrame.map((item) => (
<li key={item}>- {item}</li>
))}
</ul>
</div>
<div className="border border-border bg-card p-6">
<h3 className="text-xl font-semibold">Where {competitorName} may still fit</h3>
<ul className="mt-4 space-y-3 text-sm text-muted-foreground md:text-base">
{page.bestForCompetitor.map((item) => (
<li key={item}>- {item}</li>
))}
</ul>
</div>
</div>
</section>
<section className="border-b border-border bg-card/10 px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
<div className="mx-auto grid w-full max-w-[1200px] gap-8 lg:grid-cols-2">
<div>
<h3 className="text-2xl font-semibold">OpenFrame advantages</h3>
<ul className="mt-4 space-y-3 text-sm md:text-base">
{page.openframeWins.map((item) => (
<li key={item} className="border border-border bg-background p-4">
{item}
</li>
))}
</ul>
</div>
<div>
<h3 className="text-2xl font-semibold">{competitorName} advantages</h3>
<ul className="mt-4 space-y-3 text-sm text-muted-foreground md:text-base">
{page.competitorWins.map((item) => (
<li key={item} className="border border-border bg-background p-4">
{item}
</li>
))}
</ul>
</div>
</div>
</section>
<section className="border-b border-border px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
<div className="mx-auto w-full max-w-[1200px] space-y-8">
<div>
<h2 className="text-3xl font-semibold tracking-[-0.02em] md:text-4xl">
Feature comparison
</h2>
<p className="mt-3 max-w-3xl text-sm text-muted-foreground md:text-base">
Honest tradeoffs based on official product, pricing, and help documentation. Verify
current plans before buying.
</p>
</div>
<FeatureComparisonTable rows={page.featureRows} competitorName={competitorName} />
</div>
</section>
<section className="border-b border-border bg-[#0a0a0a] px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
<div className="mx-auto w-full max-w-[1200px] space-y-8">
<div>
<h2 className="text-3xl font-semibold tracking-[-0.02em] md:text-4xl">
Pricing comparison
</h2>
<p className="mt-3 max-w-3xl text-sm text-muted-foreground md:text-base">
OpenFrame is $10/month flat with a 7-day free trial. You do not pay per team member,
collaborator, or guest reviewer. Self-hosting is free with Docker.
</p>
</div>
<PricingComparison
rows={page.pricingRows}
footnote={page.pricingFootnote}
competitorName={competitorName}
/>
</div>
</section>
<section className="border-b border-border px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
<div className="mx-auto w-full max-w-[1200px]">
<h2 className="text-3xl font-semibold tracking-[-0.02em] md:text-4xl">FAQ</h2>
<div className="mt-8 space-y-4">
{page.faq.map((item) => (
<div key={item.question} className="border border-border bg-card p-6">
<h3 className="text-lg font-semibold">{item.question}</h3>
<p className="mt-2 text-sm text-muted-foreground md:text-base">{item.answer}</p>
</div>
))}
</div>
</div>
</section>
{relatedSlugs.length > 0 ? (
<section className="border-b border-border bg-card/10 px-4 py-12 sm:px-6 lg:px-8">
<div className="mx-auto w-full max-w-[1200px]">
<h2 className="text-xl font-semibold">Related comparisons</h2>
<div className="mt-4 flex flex-wrap gap-3">
{relatedSlugs.map((slug) => (
<Link
key={slug}
href={`/${slug}`}
className="inline-flex items-center gap-2 border border-border bg-background px-4 py-2 text-sm text-muted-foreground transition-colors hover:text-foreground"
>
{slug.replaceAll('-', ' ')}
<ArrowRight className="h-3.5 w-3.5" />
</Link>
))}
</div>
</div>
</section>
) : null}
<section className="px-4 py-16 sm:px-6 lg:px-8">
<div className="mx-auto flex w-full max-w-[1200px] flex-col items-center justify-between gap-4 border border-border bg-card p-8 text-center md:flex-row md:text-left">
<div>
<h2 className="text-3xl font-semibold tracking-[-0.02em] md:text-4xl">
Start your free trial
</h2>
<p className="mt-2 text-sm text-muted-foreground">
Your first client review link takes minutes.
</p>
</div>
<div className="flex flex-col gap-3 sm:flex-row">
<Link
href={hostedCtaHref}
className="inline-flex h-12 items-center justify-center border border-primary bg-primary px-8 text-sm font-medium text-primary-foreground"
>
Start free trial
</Link>
<a
href={seoConfig.githubUrl}
target="_blank"
rel="noreferrer"
className="inline-flex h-12 items-center justify-center border border-border bg-background px-8 text-sm font-medium text-foreground"
>
View GitHub
</a>
</div>
</div>
</section>
</main>
<MarketingFooter />
</div>
);
}
@@ -0,0 +1,68 @@
import { Check, Minus, X } from 'lucide-react';
import type { FeatureRow } from '@/lib/marketing/comparison-types';
function renderStatus(value: FeatureRow['openframe']) {
if (value === 'yes') {
return (
<span className="inline-flex items-center gap-1 text-emerald-400">
<Check className="h-4 w-4" />
Yes
</span>
);
}
if (value === 'no') {
return (
<span className="inline-flex items-center gap-1 text-red-400/90">
<X className="h-4 w-4" />
No
</span>
);
}
if (value === 'partial') {
return (
<span className="inline-flex items-center gap-1 text-amber-300">
<Minus className="h-4 w-4" />
Partial
</span>
);
}
return <span className="text-foreground/90">{value}</span>;
}
interface FeatureComparisonTableProps {
rows: FeatureRow[];
competitorName: string;
}
export function FeatureComparisonTable({ rows, competitorName }: FeatureComparisonTableProps) {
return (
<div className="overflow-x-auto border border-border bg-card">
<table className="min-w-full text-left text-sm">
<thead className="border-b border-border bg-background/60">
<tr>
<th className="px-4 py-3 font-medium text-muted-foreground">Feature</th>
<th className="px-4 py-3 font-medium text-primary">OpenFrame</th>
<th className="px-4 py-3 font-medium text-muted-foreground">{competitorName}</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.label} className="border-b border-border/60 last:border-b-0">
<td className="px-4 py-3 align-top">
<div className="font-medium text-foreground">{row.label}</div>
{row.note ? (
<div className="mt-1 text-xs text-muted-foreground">{row.note}</div>
) : null}
</td>
<td className="px-4 py-3 align-top">{renderStatus(row.openframe)}</td>
<td className="px-4 py-3 align-top">{renderStatus(row.competitor)}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
@@ -0,0 +1,23 @@
import Link from 'next/link';
import { compareFooterLinks } from '@/lib/marketing/comparison-pages';
export function MarketingCompareLinks() {
return (
<div className="flex flex-col gap-2">
<span className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground">
Compare
</span>
<nav className="flex flex-col gap-1.5">
{compareFooterLinks.map((link) => (
<Link
key={link.href}
href={link.href}
className="text-xs text-muted-foreground hover:text-foreground"
>
{link.label}
</Link>
))}
</nav>
</div>
);
}
+48
View File
@@ -0,0 +1,48 @@
import Link from 'next/link';
import { Video } from 'lucide-react';
import { seoConfig } from '@/lib/seo';
import { MarketingCompareLinks } from '@/components/marketing/marketing-compare-links';
export function MarketingFooter() {
return (
<footer className="border-t border-border bg-background px-4 py-8 sm:px-6 lg:px-8">
<div className="mx-auto grid max-w-[1200px] gap-8 sm:grid-cols-2 lg:grid-cols-3">
<div className="flex items-start gap-2">
<Video className="mt-0.5 h-4 w-4 shrink-0 text-primary" />
<span className="font-mono text-xs text-muted-foreground">
© 2026 IPEK TECH LLC. All rights reserved.
</span>
</div>
<MarketingCompareLinks />
<div className="flex flex-col gap-2">
<span className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground">
Legal
</span>
<div className="flex flex-col gap-1.5">
<a
href="mailto:[email protected]"
className="text-xs text-muted-foreground hover:text-foreground"
>
info@open-frame.net
</a>
<a
href={seoConfig.githubUrl}
className="text-xs text-muted-foreground hover:text-foreground"
>
GitHub
</a>
<Link href="/terms" className="text-xs text-muted-foreground hover:text-foreground">
Terms
</Link>
<Link href="/privacy" className="text-xs text-muted-foreground hover:text-foreground">
Privacy
</Link>
<Link href="/refund" className="text-xs text-muted-foreground hover:text-foreground">
Refund Policy
</Link>
</div>
</div>
</div>
</footer>
);
}
+77
View File
@@ -0,0 +1,77 @@
import Link from 'next/link';
import { MoveRight, Video } from 'lucide-react';
import { seoConfig } from '@/lib/seo';
const controlButtonClass =
'group relative isolate inline-flex h-8 items-center justify-center overflow-hidden border border-border bg-background px-2.5 text-[11px] font-medium text-foreground transition-colors duration-300 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:h-9 sm:px-4 sm:text-xs';
interface MarketingHeaderProps {
isLoggedIn: boolean;
}
export function MarketingHeader({ isLoggedIn }: MarketingHeaderProps) {
const hostedCtaHref = isLoggedIn ? '/dashboard' : '/register';
return (
<header className="border-b border-border bg-background/90 backdrop-blur-md">
<div className="mx-auto flex h-14 w-full max-w-[1200px] items-center justify-between px-4 sm:h-16 sm:px-6 lg:px-10">
<Link
href="/"
className="group relative isolate inline-flex items-center gap-2 overflow-hidden border border-border bg-background px-3 py-2"
>
<span className="pointer-events-none absolute inset-0 -translate-x-[101%] bg-primary/10 transition-transform duration-300 group-hover:translate-x-0" />
<Video className="relative z-10 h-4 w-4 text-primary" />
<span className="relative z-10 text-xs font-semibold tracking-[0.12em]">OPENFRAME</span>
</Link>
<nav className="hidden items-center gap-6 text-[11px] font-medium uppercase tracking-[0.14em] md:flex">
<Link
className="text-muted-foreground transition-colors hover:text-foreground"
href="/#features"
>
Features
</Link>
<Link
className="text-muted-foreground transition-colors hover:text-foreground"
href="/#pricing"
>
Pricing
</Link>
<a
className="text-muted-foreground transition-colors hover:text-foreground"
href={seoConfig.githubUrl}
target="_blank"
rel="noreferrer"
>
GitHub
</a>
</nav>
<div className="flex items-center gap-2">
{isLoggedIn ? (
<Link href="/dashboard" className={controlButtonClass}>
<span className="pointer-events-none absolute inset-0 -translate-x-[101%] bg-primary/10 transition-transform duration-300 group-hover:translate-x-0" />
<span className="relative z-10 inline-flex items-center gap-2">
Dashboard
<MoveRight className="h-3.5 w-3.5" />
</span>
</Link>
) : (
<>
<Link
href="/login"
className="mr-4 hidden text-xs font-medium text-muted-foreground hover:text-foreground sm:block"
>
Log in
</Link>
<Link href={hostedCtaHref} className={controlButtonClass}>
<span className="pointer-events-none absolute inset-0 -translate-x-[101%] bg-primary/10 transition-transform duration-300 group-hover:translate-x-0" />
<span className="relative z-10">Start free trial</span>
</Link>
</>
)}
</div>
</div>
</header>
);
}
@@ -0,0 +1,34 @@
import type { PricingRow } from '@/lib/marketing/comparison-types';
interface PricingComparisonProps {
rows: PricingRow[];
footnote?: string;
competitorName: string;
}
export function PricingComparison({ rows, footnote, competitorName }: PricingComparisonProps) {
return (
<div className="space-y-4">
<div className="grid gap-4 md:grid-cols-2">
{rows.map((row) => (
<div key={row.label} className="border border-border bg-card p-5">
<p className="text-xs uppercase tracking-[0.14em] text-muted-foreground">{row.label}</p>
<div className="mt-4 grid gap-3 sm:grid-cols-2">
<div>
<p className="text-[10px] uppercase tracking-[0.12em] text-primary">OpenFrame</p>
<p className="mt-1 text-sm text-foreground">{row.openframe}</p>
</div>
<div>
<p className="text-[10px] uppercase tracking-[0.12em] text-muted-foreground">
{competitorName}
</p>
<p className="mt-1 text-sm text-foreground/90">{row.competitor}</p>
</div>
</div>
</div>
))}
</div>
{footnote ? <p className="text-xs text-muted-foreground">{footnote}</p> : null}
</div>
);
}
+175
View File
@@ -0,0 +1,175 @@
import Image from 'next/image';
import { CheckCircle, Link as LinkIcon, MessageSquare, Mic, PenTool } from 'lucide-react';
import type { VisualVariant } from '@/lib/marketing/comparison-types';
interface ProductVisualProps {
variant: VisualVariant;
}
export function ProductVisual({ variant }: ProductVisualProps) {
if (variant === 'landing-compare') {
return (
<div className="relative aspect-[16/10] overflow-hidden border border-border bg-card">
<Image
src="/landing/compare-v2.webp"
alt="OpenFrame side-by-side version compare"
fill
className="object-cover object-top"
sizes="(max-width: 768px) 100vw, 540px"
priority
/>
</div>
);
}
if (variant === 'landing-dashboard') {
return (
<div className="relative aspect-[16/10] overflow-hidden border border-border bg-card">
<Image
src="/landing/deep-dive-dashboard-2.webp"
alt="OpenFrame video review dashboard"
fill
className="object-cover object-top"
sizes="(max-width: 768px) 100vw, 540px"
priority
/>
</div>
);
}
if (variant === 'version-compare') {
return (
<div className="border border-border bg-card p-4">
<div className="grid gap-3 md:grid-cols-2">
{['V2', 'V3'].map((version) => (
<div key={version} className="border border-border/60 bg-background p-3">
<div className="mb-3 flex items-center justify-between text-[10px] uppercase tracking-[0.14em] text-muted-foreground">
<span>{version}</span>
<span className="text-primary">Compare mode</span>
</div>
<div className="aspect-video bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-900" />
<div className="mt-3 space-y-2">
<div className="h-1.5 w-full rounded-full bg-border">
<div
className={`h-1.5 rounded-full bg-primary ${version === 'V2' ? 'w-1/3' : 'w-2/3'}`}
/>
</div>
<p className="font-mono text-[10px] text-muted-foreground">
{version === 'V2' ? '00:01:12 color too cool' : '00:01:12 warmed up +2'}
</p>
</div>
</div>
))}
</div>
</div>
);
}
if (variant === 'approval-workflow') {
return (
<div className="border border-border bg-card p-5">
<div className="flex items-center justify-between border-b border-border pb-4">
<div>
<p className="text-xs uppercase tracking-[0.14em] text-muted-foreground">
Client Cut V3
</p>
<p className="mt-1 text-lg font-semibold">Approval requests</p>
</div>
<span className="inline-flex items-center gap-2 border border-emerald-500/30 bg-emerald-500/10 px-3 py-1 text-xs text-emerald-300">
<CheckCircle className="h-3.5 w-3.5" />2 of 3 approved
</span>
</div>
<div className="mt-4 space-y-3">
{[
{ name: 'Client Producer', status: 'Approved', tone: 'text-emerald-300' },
{ name: 'Brand Manager', status: 'Approved', tone: 'text-emerald-300' },
{ name: 'Legal Review', status: 'Pending', tone: 'text-amber-300' },
].map((item) => (
<div
key={item.name}
className="flex items-center justify-between border border-border/60 bg-background px-4 py-3"
>
<span className="text-sm">{item.name}</span>
<span className={`text-xs uppercase tracking-[0.12em] ${item.tone}`}>
{item.status}
</span>
</div>
))}
</div>
</div>
);
}
if (variant === 'guest-review') {
return (
<div className="border border-border bg-card p-5">
<div className="flex items-start gap-3 border border-primary/30 bg-primary/5 p-4">
<LinkIcon className="mt-0.5 h-5 w-5 text-primary" />
<div>
<p className="text-sm font-medium">open-frame.net/watch/share-7f3a</p>
<p className="mt-1 text-sm text-muted-foreground">
Client opens the link, enters a name, and reviews in the browser. No account required.
</p>
</div>
</div>
<div className="mt-4 aspect-video border border-border/60 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950" />
<div className="mt-4 flex items-center gap-3 border border-border/60 bg-background p-3">
<MessageSquare className="h-4 w-4 text-primary" />
<div>
<p className="text-sm font-medium">Client note at 00:02:14</p>
<p className="text-xs text-muted-foreground">Lower the music under the VO here.</p>
</div>
</div>
</div>
);
}
if (variant === 'voice-notes') {
return (
<div className="border border-border bg-card p-5">
<div className="flex items-start justify-between">
<div className="flex items-center gap-3">
<div className="flex h-8 w-8 items-center justify-center bg-secondary font-mono text-xs">
C
</div>
<div>
<p className="font-mono text-[11px] font-medium">Client</p>
<p className="font-mono text-[10px] text-muted-foreground">00:03:45</p>
</div>
</div>
<Mic className="h-4 w-4 text-primary" />
</div>
<div className="mt-6 flex h-16 items-center gap-1 overflow-hidden">
{Array.from({ length: 36 }).map((_, index) => (
<span
key={index}
className="w-full flex-1 bg-primary/60"
style={{
height: `${[30, 80, 50, 90, 40, 70, 60, 45, 85, 55][index % 10]}%`,
}}
/>
))}
</div>
<p className="mt-4 text-sm text-muted-foreground">
Voice note pinned to the exact frameno more typing long explanations.
</p>
</div>
);
}
return (
<div className="border border-border bg-card p-5">
<div className="aspect-video border border-border/60 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950" />
<div className="relative mt-4 border border-border/60 bg-background p-4">
<div className="absolute right-4 top-4 rounded-full border border-primary/40 p-2 text-primary">
<PenTool className="h-4 w-4" />
</div>
<p className="font-mono text-[10px] text-muted-foreground">00:01:48</p>
<p className="mt-2 text-sm">Move the lower third up one line so it clears the subject.</p>
<div className="mt-4 h-1.5 w-full rounded-full bg-border">
<div className="h-1.5 w-[42%] rounded-full bg-primary" />
</div>
</div>
</div>
);
}