diff --git a/README.md b/README.md index 9206f12..3c1d141 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,10 @@ bun run check Feature flags and self-hosting environment variables are documented in `.env.example` and `.env.docker.example`. +## License + +OpenFrame is Fair Source, licensed under the [Functional Source License](https://fsl.software/) (FSL-1.1-ALv2). The full source code is publicly available, you can self-host it, and every release automatically becomes Apache 2.0 open source two years after its publication. See [LICENCE](LICENCE) for the full terms. + ## Contributing Contributions are welcome. @@ -215,3 +219,4 @@ Contributions are welcome. - Read [CONTRIBUTING.md](CONTRIBUTING.md) for workflow, conventions, and PR requirements. - Use [SECURITY.md](SECURITY.md) for responsible vulnerability reporting. - Follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) in all project interactions. +- Contact: [info@open-frame.net](mailto:info@open-frame.net) diff --git a/app/api/settings/notifications/route.ts b/app/api/settings/notifications/route.ts index 5021c9b..0fbb918 100644 --- a/app/api/settings/notifications/route.ts +++ b/app/api/settings/notifications/route.ts @@ -193,7 +193,7 @@ export async function POST(request: NextRequest) { const fromAddress = process.env.SMTP_FROM || process.env.EMAIL_FROM || - 'OpenFrame '; + 'OpenFrame '; try { await transporter.sendMail({ diff --git a/app/terms/page.tsx b/app/terms/page.tsx index 9679515..b276b49 100644 --- a/app/terms/page.tsx +++ b/app/terms/page.tsx @@ -150,7 +150,8 @@ export default function TermsOfServicePage() {
  • Interfere with or disrupt the integrity or performance of the Service.
  • Reverse engineer, decompile, or attempt to extract the source code of the Service - (except where permitted by applicable open-source licenses). + (except where permitted by the applicable source license, such as the Functional + Source License covering the platform code).
  • Use the Service to send spam or unsolicited communications.
  • @@ -174,8 +175,11 @@ export default function TermsOfServicePage() { intellectual property laws.

    - The core platform code is made available as open-source software; please refer to the - applicable license in the GitHub repository for details on permitted use. + The core platform code is made available under the Functional Source License + (FSL-1.1-ALv2): the source code is publicly available and may be self-hosted, and + each release becomes available under the Apache 2.0 license two years after its + publication. Please refer to the license in the GitHub repository for details on + permitted use.

    diff --git a/components/LandingPage.tsx b/components/LandingPage.tsx index b97b21b..9757239 100644 --- a/components/LandingPage.tsx +++ b/components/LandingPage.tsx @@ -234,14 +234,14 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) { - Open Source Video Review + Fair Source Video Review

    - Cut Video Approval Time in Half.
    + Get Client Sign-off From One Link.
    Stop Chasing Timecodes.

    @@ -249,27 +249,35 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) { data-hero-copy className="mx-auto max-w-2xl text-base text-muted-foreground md:text-xl" > - OpenFrame puts comments, voice notes, and annotations on a single timeline so clients - say "yes" faster and your team stops guessing. + Hosted video review for editors, agencies, and small studios. Comments, voice notes, + and annotations land on one timeline — clients review in the browser, no account + needed.

    - Start free + Start free trial +

    + 7-day free trial · Flat $10/mo — no per-seat fees · No client accounts +

    + - Prefer self-hosting? + Prefer self-hosting? View on GitHub{' '} +
    @@ -644,70 +652,33 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) { className="text-3xl font-semibold md:text-5xl text-foreground" style={{ fontFamily: 'monospace', letterSpacing: '-0.02em' }} > - Deploy it yourself - or let us run it for you. + Let us run it for you - or deploy it yourself.
    - {/* Card 1: Open Source */} -
    -
    -

    - Open Source (Self-hosted) -

    -
    - -
    - Free -
    -

    - For teams who want full control and can run their own infrastructure. -

    - -
      -
    • - - Full codebase access -
    • -
    • - - Self-hosted infrastructure control -
    • -
    • - - Manual update cadence -
    • -
    - - - View on GitHub - -
    - - {/* Card 2: Hosted Cloud */} + {/* Card 1: Hosted Cloud (recommended) */}
    + + Recommended +

    - Best for teams who want zero setup. + Zero setup. Flat pricing, no per-seat fees.

    Hosted Cloud

    -
    +
    $10 / month
    +

    + Starts with a 7-day free trial. Cancel anytime. +

    • @@ -751,10 +722,63 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) { href={hostedCtaHref} className="mt-auto group relative isolate inline-flex h-12 w-full items-center justify-center overflow-hidden bg-[#06b6d4] font-medium text-black transition-colors hover:bg-[#06b6d4]/90 text-sm" > - Start free + Start free trial
    + {/* Card 2: Fair Source (Self-hosted) */} +
    +
    +

    + Fair Source (Self-hosted) +

    +
    + +
    + Free +
    +

    + For teams who want full control and can run their own infrastructure. Licensed + under the{' '} + + Functional Source License + + . +

    + +
      +
    • + + Full source code — read it, audit it +
    • +
    • + + Self-host on your own infrastructure +
    • +
    • + + Every release becomes Apache 2.0 open source after two years +
    • +
    + + + View on GitHub + +
    + {/* Card 3: Studio & Agency */}
    Contact us @@ -823,7 +847,15 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) { }, { q: 'Can I self-host?', - a: 'Yes. The core is open-source and self-hostable. Hosted Cloud is for teams who want zero setup.', + a: 'Yes. The full source code is public and ships with a Docker setup for self-hosting. Hosted Cloud is for teams who want zero setup.', + }, + { + q: 'Is OpenFrame open source?', + a: 'OpenFrame is Fair Source, licensed under the Functional Source License (FSL). You can read and audit the full source code and self-host it, and every release automatically becomes Apache 2.0 open source two years after publication.', + }, + { + q: 'Is there a free trial?', + a: 'Yes. Hosted Cloud starts with a 7-day free trial. After that it is a flat $10/mo — no per-seat or per-client fees.', }, { q: 'How is this different from sending a Google Drive link?', @@ -874,7 +906,7 @@ export function LandingPage({ isLoggedIn }: LandingPageProps) { href={hostedCtaHref} className="group relative isolate inline-flex h-12 min-w-max items-center justify-center overflow-hidden border border-primary bg-primary px-10 text-sm font-medium whitespace-nowrap text-primary-foreground transition-transform duration-300 hover:scale-[1.02] md:min-w-[240px]" > - Start free + Start free trial
    diff --git a/lib/email-verification.ts b/lib/email-verification.ts index 1944afb..9c0d5b1 100644 --- a/lib/email-verification.ts +++ b/lib/email-verification.ts @@ -111,7 +111,7 @@ export async function sendVerificationEmail(email: string, token: string): Promi const verifyUrl = `${baseUrl}/api/auth/verify-email?token=${encodeURIComponent(token)}`; const from = - process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame '; + process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame '; const html = brandedEmailTemplate( ` diff --git a/lib/invitations.ts b/lib/invitations.ts index 05df144..d35ebdc 100644 --- a/lib/invitations.ts +++ b/lib/invitations.ts @@ -68,7 +68,7 @@ export async function sendInvitationEmail(input: { } const fromAddress = - process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame '; + process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame '; const subject = `[OpenFrame] You were invited to a ${scopeLabel(input.scope)}: ${input.targetName}`; const html = invitationEmailTemplate({ inviterName: input.inviterName, diff --git a/lib/marketing/comparison-pages.ts b/lib/marketing/comparison-pages.ts index a94cd6e..22d5927 100644 --- a/lib/marketing/comparison-pages.ts +++ b/lib/marketing/comparison-pages.ts @@ -202,7 +202,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [ title: 'Frame.io Alternative for Small Teams', metaDescription: 'Compare OpenFrame vs Frame.io for freelancers and small teams. Get timestamped review, approvals, guest links, and self-hosting without per-seat enterprise pricing.', - keywords: ['frame.io alternative', 'frame io alternative', 'open source frame.io alternative'], + keywords: ['frame.io alternative', 'frame io alternative', 'fair source frame.io alternative'], headline: 'Frame.io power without the enterprise bill', subheadline: 'Frame.io is the industry standard for large post teams. OpenFrame gives freelancers and small studios the review workflow they actually need: one link, one timeline, clear approvals, and optional self-hosting.', @@ -249,7 +249,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [ keywords: [ 'self hosted frame.io alternative', 'self-hosted video review', - 'open source video review', + 'fair source video review', ], eyebrow: 'Self-hosted review', headline: 'Keep client footage on your infrastructure', @@ -270,7 +270,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [ bestForOpenFrame: [ 'Teams with Docker ops capacity', 'Privacy-sensitive client work', - 'Studios comparing Frame.io to open/fair-source options', + 'Studios comparing Frame.io to fair-source options', ], bestForCompetitor: [ 'Teams needing Adobe enterprise integrations out of the box', @@ -297,7 +297,7 @@ export const comparisonPages: ComparisonPageDefinition[] = [ { label: 'Version compare', openframe: 'yes', competitor: 'yes' }, { label: 'Enterprise DRM / SSO', openframe: 'no', competitor: 'yes' }, { label: 'Adobe NLE integrations', openframe: 'no', competitor: 'yes' }, - { label: 'Open/fair-source codebase', openframe: 'yes', competitor: 'no' }, + { label: 'Fair-source codebase', openframe: 'yes', competitor: 'no' }, ], pricingRows: [ { label: 'Self-hosted software cost', openframe: 'Free', competitor: 'Not available' }, diff --git a/lib/marketing/comparison-sources.ts b/lib/marketing/comparison-sources.ts index 5078930..bab4a65 100644 --- a/lib/marketing/comparison-sources.ts +++ b/lib/marketing/comparison-sources.ts @@ -565,7 +565,7 @@ export const openFrameProfile = { ], bestFor: [ 'Freelancers and small teams shipping client cuts', - 'Studios that want open/fair-source and optional self-hosting', + 'Studios that want fair-source licensing and optional self-hosting', 'Teams tired of vague email and WhatsApp feedback', ], }; diff --git a/lib/notifications.ts b/lib/notifications.ts index b305cdb..2f270a4 100644 --- a/lib/notifications.ts +++ b/lib/notifications.ts @@ -84,7 +84,7 @@ function createSmtpTransport() { async function sendEmail(to: string, subject: string, html: string): Promise { const transporter = createSmtpTransport(); const fromAddress = - process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame '; + process.env.SMTP_FROM || process.env.EMAIL_FROM || 'OpenFrame '; if (!transporter) { console.warn('SMTP not configured — skipping email notification'); diff --git a/lib/seo.ts b/lib/seo.ts index df5b137..026cbe6 100644 --- a/lib/seo.ts +++ b/lib/seo.ts @@ -1,4 +1,4 @@ -const FALLBACK_SITE_URL = 'https://openframe.net'; +const FALLBACK_SITE_URL = 'https://open-frame.net'; function normalizeSiteUrl(rawUrl: string | undefined): string { if (!rawUrl) { @@ -26,11 +26,12 @@ export function getSiteUrl(): string { export const seoConfig = { name: 'OpenFrame', - title: 'Open Source Video Review Platform', + title: 'Fair Source Video Review Platform', description: - 'OpenFrame is an open source video review platform for collecting timestamped feedback with text and voice comments.', + 'OpenFrame is a fair source video review platform for collecting timestamped feedback with text and voice comments.', keywords: [ - 'open source video review platform', + 'fair source video review platform', + 'video review platform', 'video review tool', 'timestamped video feedback', 'video collaboration',