Merge pull request #9 from luisacevelad/feat/theme-system
feat: add theme system with swappable palettes and rebrand to NeuralCut
This commit is contained in:
commit
d65435554f
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "@opencut/web",
|
"name": "@neuralcut/web",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "bun@1.2.18",
|
"packageManager": "bun@1.2.18",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "OpenCut",
|
"name": "NeuralCut",
|
||||||
"description": "A simple but powerful video editor that gets the job done. In your browser.",
|
"description": "A simple but powerful video editor that gets the job done. In your browser.",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"start_url": "/",
|
"start_url": "/",
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ import { getPosts } from "@/lib/blog/query";
|
||||||
import type { Post } from "@/lib/blog/types";
|
import type { Post } from "@/lib/blog/types";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Blog - OpenCut",
|
title: "Blog - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Read the latest news and updates about OpenCut, the free and open-source video editor.",
|
"Read the latest news and updates about NeuralCut, the free and open-source video editor.",
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "Blog - OpenCut",
|
title: "Blog - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Read the latest news and updates about OpenCut, the free and open-source video editor.",
|
"Read the latest news and updates about NeuralCut, the free and open-source video editor.",
|
||||||
type: "website",
|
type: "website",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -24,7 +24,7 @@ export default async function BlogPage() {
|
||||||
return (
|
return (
|
||||||
<BasePage
|
<BasePage
|
||||||
title="Blog"
|
title="Blog"
|
||||||
description="Read the latest news and updates about OpenCut, the free and open-source video editor."
|
description="Read the latest news and updates about NeuralCut, the free and open-source video editor."
|
||||||
>
|
>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
{data.posts.map((post) => (
|
{data.posts.map((post) => (
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ const ASSET_SECTIONS: AssetSection[] = [
|
||||||
{
|
{
|
||||||
title: "Symbol",
|
title: "Symbol",
|
||||||
description:
|
description:
|
||||||
"Use the symbol on its own when the OpenCut name is already present nearby or space is limited.",
|
"Use the symbol on its own when the NeuralCut name is already present nearby or space is limited.",
|
||||||
cols: "2",
|
cols: "2",
|
||||||
assets: [
|
assets: [
|
||||||
{
|
{
|
||||||
|
|
@ -112,7 +112,7 @@ export default function BrandPage() {
|
||||||
title="Brand"
|
title="Brand"
|
||||||
description={
|
description={
|
||||||
<>
|
<>
|
||||||
Download OpenCut brand assets for use in your projects.{" "}
|
Download NeuralCut brand assets for use in your projects.{" "}
|
||||||
<Link
|
<Link
|
||||||
href="#guidelines"
|
href="#guidelines"
|
||||||
className="underline underline-offset-4"
|
className="underline underline-offset-4"
|
||||||
|
|
@ -173,10 +173,10 @@ export default function BrandPage() {
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<h2 className="font-semibold text-lg">Usage</h2>
|
<h2 className="font-semibold text-lg">Usage</h2>
|
||||||
<p className="text-muted-foreground text-base leading-relaxed">
|
<p className="text-muted-foreground text-base leading-relaxed">
|
||||||
OpenCut is open source — the code is free to use under its license.
|
NeuralCut is open source — the code is free to use under its license.
|
||||||
That license does not cover the name or logo. You can say you use
|
That license does not cover the name or logo. You can say you use
|
||||||
OpenCut, that your project integrates with OpenCut, or that it was
|
NeuralCut, that your project integrates with NeuralCut, or that it was
|
||||||
built on top of OpenCut. You cannot name your product OpenCut, imply
|
built on top of NeuralCut. You cannot name your product NeuralCut, imply
|
||||||
we made or endorse your product, or use the marks commercially
|
we made or endorse your product, or use the marks commercially
|
||||||
without asking first. For anything unclear, reach out at{" "}
|
without asking first. For anything unclear, reach out at{" "}
|
||||||
<Link
|
<Link
|
||||||
|
|
@ -193,8 +193,8 @@ export default function BrandPage() {
|
||||||
<h2 className="font-semibold text-lg">What's not allowed</h2>
|
<h2 className="font-semibold text-lg">What's not allowed</h2>
|
||||||
<ul className="text-muted-foreground text-base flex flex-col gap-2 leading-relaxed">
|
<ul className="text-muted-foreground text-base flex flex-col gap-2 leading-relaxed">
|
||||||
{[
|
{[
|
||||||
"Using OpenCut in the name of your product, service, or domain.",
|
"Using NeuralCut in the name of your product, service, or domain.",
|
||||||
"Implying that OpenCut made, sponsors, or endorses your work.",
|
"Implying that NeuralCut made, sponsors, or endorses your work.",
|
||||||
"Using the logo or name on merchandise or commercial marketing.",
|
"Using the logo or name on merchandise or commercial marketing.",
|
||||||
"Modifying the marks.",
|
"Modifying the marks.",
|
||||||
].map((item) => (
|
].map((item) => (
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||||
const release = getReleaseByVersion({ version });
|
const release = getReleaseByVersion({ version });
|
||||||
if (!release) return {};
|
if (!release) return {};
|
||||||
return {
|
return {
|
||||||
title: `${release.title} (${release.version}) - OpenCut Changelog`,
|
title: `${release.title} (${release.version}) - NeuralCut Changelog`,
|
||||||
description: release.description,
|
description: release.description,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,25 +14,25 @@ import {
|
||||||
} from "@/lib/changelog/components/release";
|
} from "@/lib/changelog/components/release";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Changelog - OpenCut",
|
title: "Changelog - NeuralCut",
|
||||||
description: "What's new in OpenCut",
|
description: "What's new in NeuralCut",
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "Changelog - OpenCut",
|
title: "Changelog - NeuralCut",
|
||||||
description: "Every update, improvement, and fix to OpenCut — documented.",
|
description: "Every update, improvement, and fix to NeuralCut — documented.",
|
||||||
type: "website",
|
type: "website",
|
||||||
images: [
|
images: [
|
||||||
{
|
{
|
||||||
url: "/open-graph/changlog.jpg",
|
url: "/open-graph/changlog.jpg",
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
alt: "OpenCut Changelog",
|
alt: "NeuralCut Changelog",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
card: "summary_large_image",
|
card: "summary_large_image",
|
||||||
title: "Changelog - OpenCut",
|
title: "Changelog - NeuralCut",
|
||||||
description: "What's new in OpenCut",
|
description: "What's new in NeuralCut",
|
||||||
images: ["/open-graph/changlog.jpg"],
|
images: ["/open-graph/changlog.jpg"],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -41,7 +41,7 @@ export default function ChangelogPage() {
|
||||||
const releases = getSortedReleases();
|
const releases = getSortedReleases();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BasePage title="Changelog" description="See what's new in OpenCut">
|
<BasePage title="Changelog" description="See what's new in NeuralCut">
|
||||||
<div className="mx-auto w-full max-w-3xl">
|
<div className="mx-auto w-full max-w-3xl">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ import { EXTERNAL_TOOLS } from "@/lib/site/external-tools";
|
||||||
import { BasePage } from "../base-page";
|
import { BasePage } from "../base-page";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Contributors - OpenCut",
|
title: "Contributors - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Meet the amazing people who contribute to OpenCut, the free and open-source video editor.",
|
"Meet the amazing people who contribute to NeuralCut, the free and open-source video editor.",
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "Contributors - OpenCut",
|
title: "Contributors - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Meet the amazing people who contribute to OpenCut, the free and open-source video editor.",
|
"Meet the amazing people who contribute to NeuralCut, the free and open-source video editor.",
|
||||||
type: "website",
|
type: "website",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -70,7 +70,7 @@ export default async function ContributorsPage() {
|
||||||
return (
|
return (
|
||||||
<BasePage
|
<BasePage
|
||||||
title="Contributors"
|
title="Contributors"
|
||||||
description="Meet the amazing people who contribute to OpenCut, the free and open-source video editor."
|
description="Meet the amazing people who contribute to NeuralCut, the free and open-source video editor."
|
||||||
>
|
>
|
||||||
<div className="-mt-4 flex items-center justify-center gap-8 text-sm">
|
<div className="-mt-4 flex items-center justify-center gap-8 text-sm">
|
||||||
<StatItem value={contributors.length} label="contributors" />
|
<StatItem value={contributors.length} label="contributors" />
|
||||||
|
|
@ -87,7 +87,7 @@ export default async function ContributorsPage() {
|
||||||
<ExternalToolsSection />
|
<ExternalToolsSection />
|
||||||
<GitHubContributeSection
|
<GitHubContributeSection
|
||||||
title="Join the community"
|
title="Join the community"
|
||||||
description="OpenCut is built by developers like you. Every contribution, no matter how small, helps make video editing more accessible for everyone."
|
description="NeuralCut is built by developers like you. Every contribution, no matter how small, helps make video editing more accessible for everyone."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
|
|
@ -169,7 +169,7 @@ function AllContributorsSection({
|
||||||
<div className="flex flex-col gap-2 text-center">
|
<div className="flex flex-col gap-2 text-center">
|
||||||
<h2 className="text-2xl font-semibold">All contributors</h2>
|
<h2 className="text-2xl font-semibold">All contributors</h2>
|
||||||
<p className="text-muted-foreground">
|
<p className="text-muted-foreground">
|
||||||
Everyone who makes OpenCut better
|
Everyone who makes NeuralCut better
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ function ExternalToolsSection() {
|
||||||
<div className="flex flex-col gap-10">
|
<div className="flex flex-col gap-10">
|
||||||
<div className="flex flex-col gap-2 text-center">
|
<div className="flex flex-col gap-2 text-center">
|
||||||
<h2 className="text-2xl font-semibold">External tools</h2>
|
<h2 className="text-2xl font-semibold">External tools</h2>
|
||||||
<p className="text-muted-foreground">Tools we use to build OpenCut</p>
|
<p className="text-muted-foreground">Tools we use to build NeuralCut</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx-auto grid max-w-4xl grid-cols-1 gap-6 sm:grid-cols-2">
|
<div className="mx-auto grid max-w-4xl grid-cols-1 gap-6 sm:grid-cols-2">
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ function DegradedRendererBanner() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-accent border-b h-9 flex items-center justify-center gap-2 text-xs text-muted-foreground">
|
<div className="bg-accent border-b h-9 flex items-center justify-center gap-2 text-xs text-muted-foreground">
|
||||||
<span>For the best experience, open OpenCut in Chrome.</span>
|
<span>For the best experience, open NeuralCut in Chrome.</span>
|
||||||
<Button
|
<Button
|
||||||
variant="text"
|
variant="text"
|
||||||
size="icon"
|
size="icon"
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,54 @@
|
||||||
--sidebar-border: hsl(0 0% 85.1%);
|
--sidebar-border: hsl(0 0% 85.1%);
|
||||||
--sidebar-ring: hsl(0 0% 16.9%);
|
--sidebar-ring: hsl(0 0% 16.9%);
|
||||||
--sidebar: hsl(0 0% 98%);
|
--sidebar: hsl(0 0% 98%);
|
||||||
|
--export-ring: hsl(199, 89%, 60%);
|
||||||
|
--export-gradient-from: hsl(215, 85%, 54%);
|
||||||
|
--export-gradient-to: hsl(199, 91%, 59%);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-palette="neuralcut"] {
|
||||||
|
--background: hsl(220, 20%, 97%);
|
||||||
|
--foreground: hsl(217, 23%, 14%);
|
||||||
|
--card: hsl(220, 18%, 99%);
|
||||||
|
--card-foreground: hsl(217, 23%, 14%);
|
||||||
|
--popover: hsl(220, 18%, 99%);
|
||||||
|
--popover-hover: hsl(220, 15%, 94%);
|
||||||
|
--popover-foreground: hsl(217, 23%, 14%);
|
||||||
|
--primary: hsl(342, 89%, 64%);
|
||||||
|
--primary-foreground: hsl(0, 0%, 100%);
|
||||||
|
--secondary: hsl(342, 40%, 95%);
|
||||||
|
--secondary-border: hsl(342, 40%, 90%);
|
||||||
|
--secondary-foreground: hsl(342, 80%, 45%);
|
||||||
|
--muted: hsl(220, 10%, 85%);
|
||||||
|
--muted-foreground: hsl(220, 10%, 48%);
|
||||||
|
--accent: hsl(220, 15%, 94%);
|
||||||
|
--accent-foreground: hsl(217, 23%, 14%);
|
||||||
|
--destructive: hsl(0, 83%, 50%);
|
||||||
|
--destructive-foreground: hsl(0, 0%, 100%);
|
||||||
|
--constructive: hsl(141, 71%, 48%);
|
||||||
|
--constructive-foreground: hsl(0, 0%, 100%);
|
||||||
|
--caution: hsl(38, 92%, 50%);
|
||||||
|
--caution-foreground: hsl(0, 0%, 10%);
|
||||||
|
--border: hsl(220, 12%, 90%);
|
||||||
|
--input: hsl(0, 0%, 100%);
|
||||||
|
--ring: hsl(342, 89%, 64%);
|
||||||
|
--chart-1: hsl(342 80% 55%);
|
||||||
|
--chart-2: hsl(217 40% 45%);
|
||||||
|
--chart-3: hsl(30 80% 55%);
|
||||||
|
--chart-4: hsl(308 31% 45%);
|
||||||
|
--chart-5: hsl(38 92% 55%);
|
||||||
|
--sidebar-background: hsl(220, 18%, 96%);
|
||||||
|
--sidebar-foreground: hsl(217, 23%, 14%);
|
||||||
|
--sidebar-primary: hsl(217, 23%, 14%);
|
||||||
|
--sidebar-primary-foreground: hsl(220, 12%, 90%);
|
||||||
|
--sidebar-accent: hsl(220, 10%, 90%);
|
||||||
|
--sidebar-accent-foreground: hsl(217, 23%, 14%);
|
||||||
|
--sidebar-border: hsl(220, 10%, 90%);
|
||||||
|
--sidebar-ring: hsl(217, 23%, 30%);
|
||||||
|
--sidebar: hsl(220, 20%, 98%);
|
||||||
|
--export-ring: hsl(342, 70%, 75%);
|
||||||
|
--export-gradient-from: hsl(342, 89%, 50%);
|
||||||
|
--export-gradient-to: hsl(342, 80%, 68%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
|
|
@ -97,6 +145,43 @@
|
||||||
--sidebar-border: hsl(0 0% 20%);
|
--sidebar-border: hsl(0 0% 20%);
|
||||||
--sidebar-ring: hsl(0 0% 83.1%);
|
--sidebar-ring: hsl(0 0% 83.1%);
|
||||||
--sidebar: hsl(0 0% 6%);
|
--sidebar: hsl(0 0% 6%);
|
||||||
|
--export-ring: hsl(199, 89%, 60%);
|
||||||
|
--export-gradient-from: hsl(215, 85%, 54%);
|
||||||
|
--export-gradient-to: hsl(199, 91%, 59%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark[data-palette="neuralcut"] {
|
||||||
|
--background: hsl(217, 23%, 14%);
|
||||||
|
--foreground: hsl(220, 20%, 93%);
|
||||||
|
--card: hsl(217, 20%, 17%);
|
||||||
|
--card-foreground: hsl(220, 20%, 93%);
|
||||||
|
--popover: hsl(217, 20%, 15%);
|
||||||
|
--popover-hover: hsl(217, 18%, 22%);
|
||||||
|
--popover-foreground: hsl(220, 20%, 95%);
|
||||||
|
--secondary: hsl(342, 25%, 18%);
|
||||||
|
--secondary-border: hsl(342, 25%, 23%);
|
||||||
|
--secondary-foreground: hsl(342, 80%, 72%);
|
||||||
|
--muted: hsl(217, 15%, 25%);
|
||||||
|
--muted-foreground: hsl(220, 10%, 55%);
|
||||||
|
--accent: hsl(217, 18%, 20%);
|
||||||
|
--accent-foreground: hsl(220, 20%, 93%);
|
||||||
|
--border: hsl(217, 18%, 22%);
|
||||||
|
--input: hsl(217, 20%, 16%);
|
||||||
|
--ring: hsl(342, 89%, 64%);
|
||||||
|
--caution: hsl(38, 92%, 60%);
|
||||||
|
--caution-foreground: hsl(0, 0%, 10%);
|
||||||
|
--sidebar-background: hsl(217, 22%, 11%);
|
||||||
|
--sidebar-foreground: hsl(220, 20%, 93%);
|
||||||
|
--sidebar-primary: hsl(342, 89%, 64%);
|
||||||
|
--sidebar-primary-foreground: hsl(0, 0%, 100%);
|
||||||
|
--sidebar-accent: hsl(217, 15%, 20%);
|
||||||
|
--sidebar-accent-foreground: hsl(220, 20%, 93%);
|
||||||
|
--sidebar-border: hsl(217, 15%, 20%);
|
||||||
|
--sidebar-ring: hsl(342, 89%, 64%);
|
||||||
|
--sidebar: hsl(217, 22%, 12%);
|
||||||
|
--export-ring: hsl(342, 70%, 75%);
|
||||||
|
--export-gradient-from: hsl(342, 89%, 50%);
|
||||||
|
--export-gradient-to: hsl(342, 80%, 68%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .panel {
|
.dark .panel {
|
||||||
|
|
@ -115,6 +200,42 @@
|
||||||
--ring: hsl(0, 0%, 52%);
|
--ring: hsl(0, 0%, 52%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-palette="neuralcut"] .panel {
|
||||||
|
--background: hsl(220, 18%, 95%);
|
||||||
|
--foreground: hsl(217, 23%, 14%);
|
||||||
|
--card: hsl(220, 16%, 96%);
|
||||||
|
--card-foreground: hsl(217, 23%, 14%);
|
||||||
|
--primary-foreground: hsl(0, 0%, 100%);
|
||||||
|
--secondary: hsl(342, 35%, 93%);
|
||||||
|
--secondary-border: hsl(342, 35%, 88%);
|
||||||
|
--secondary-foreground: hsl(342, 80%, 42%);
|
||||||
|
--muted: hsl(220, 10%, 83%);
|
||||||
|
--muted-foreground: hsl(220, 10%, 45%);
|
||||||
|
--accent: hsl(220, 12%, 92%);
|
||||||
|
--accent-foreground: hsl(217, 23%, 14%);
|
||||||
|
--destructive-foreground: hsl(0, 0%, 100%);
|
||||||
|
--constructive-foreground: hsl(0, 0%, 100%);
|
||||||
|
--border: hsl(220, 10%, 88%);
|
||||||
|
--input: hsl(220, 12%, 92%);
|
||||||
|
--ring: hsl(342, 89%, 64%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark[data-palette="neuralcut"] .panel {
|
||||||
|
--background: hsl(217, 20%, 18%);
|
||||||
|
--foreground: hsl(220, 18%, 90%);
|
||||||
|
--card: hsl(217, 18%, 19%);
|
||||||
|
--card-foreground: hsl(220, 18%, 90%);
|
||||||
|
--secondary: hsl(342, 30%, 15%);
|
||||||
|
--secondary-border: hsl(342, 30%, 20%);
|
||||||
|
--secondary-foreground: hsl(342, 80%, 68%);
|
||||||
|
--muted: hsl(217, 12%, 28%);
|
||||||
|
--accent: hsl(217, 15%, 22%);
|
||||||
|
--accent-foreground: hsl(220, 18%, 90%);
|
||||||
|
--border: hsl(217, 15%, 24%);
|
||||||
|
--input: hsl(217, 15%, 24%);
|
||||||
|
--ring: hsl(342, 89%, 64%);
|
||||||
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
/*
|
/*
|
||||||
The default border color has changed to `currentcolor` in Tailwind CSS v4,
|
The default border color has changed to `currentcolor` in Tailwind CSS v4,
|
||||||
|
|
@ -217,6 +338,10 @@
|
||||||
--color-sidebar-border: var(--sidebar-border);
|
--color-sidebar-border: var(--sidebar-border);
|
||||||
--color-sidebar-ring: var(--sidebar-ring);
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
|
|
||||||
|
--color-export-ring: var(--export-ring);
|
||||||
|
--color-export-gradient-from: var(--export-gradient-from);
|
||||||
|
--color-export-gradient-to: var(--export-gradient-to);
|
||||||
|
|
||||||
/* Animations */
|
/* Animations */
|
||||||
--animate-accordion-down: accordion-down 0.2s ease-out;
|
--animate-accordion-down: accordion-down 0.2s ease-out;
|
||||||
--animate-accordion-up: accordion-up 0.2s ease-out;
|
--animate-accordion-up: accordion-up 0.2s ease-out;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { ThemeProvider } from "next-themes";
|
|
||||||
import Script from "next/script";
|
import Script from "next/script";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { Toaster } from "../components/ui/sonner";
|
import { Toaster } from "../components/ui/sonner";
|
||||||
|
|
@ -8,6 +7,7 @@ import { baseMetaData } from "./metadata";
|
||||||
import { BotIdClient } from "botid/client";
|
import { BotIdClient } from "botid/client";
|
||||||
import { webEnv } from "@/lib/env/web";
|
import { webEnv } from "@/lib/env/web";
|
||||||
import { Inter } from "next/font/google";
|
import { Inter } from "next/font/google";
|
||||||
|
import { NeuralCutThemeProvider } from "@/lib/themes/theme-provider";
|
||||||
|
|
||||||
const siteFont = Inter({ subsets: ["latin"] });
|
const siteFont = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
|
|
@ -40,11 +40,7 @@ export default function RootLayout({
|
||||||
)}
|
)}
|
||||||
</head>
|
</head>
|
||||||
<body className={`${siteFont.className} font-sans antialiased`}>
|
<body className={`${siteFont.className} font-sans antialiased`}>
|
||||||
<ThemeProvider
|
<NeuralCutThemeProvider>
|
||||||
attribute="class"
|
|
||||||
defaultTheme="system"
|
|
||||||
disableTransitionOnChange={true}
|
|
||||||
>
|
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<Script
|
<Script
|
||||||
|
|
@ -61,7 +57,7 @@ export default function RootLayout({
|
||||||
/>
|
/>
|
||||||
{children}
|
{children}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ThemeProvider>
|
</NeuralCutThemeProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export const baseMetaData: Metadata = {
|
||||||
url: SITE_INFO.openGraphImage,
|
url: SITE_INFO.openGraphImage,
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
alt: "OpenCut Wordmark",
|
alt: "NeuralCut Wordmark",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
@ -25,7 +25,7 @@ export const baseMetaData: Metadata = {
|
||||||
card: "summary_large_image",
|
card: "summary_large_image",
|
||||||
title: SITE_INFO.title,
|
title: SITE_INFO.title,
|
||||||
description: SITE_INFO.description,
|
description: SITE_INFO.description,
|
||||||
creator: "@opencutapp",
|
creator: "@neuralcut",
|
||||||
images: [SITE_INFO.twitterImage],
|
images: [SITE_INFO.twitterImage],
|
||||||
},
|
},
|
||||||
pinterest: {
|
pinterest: {
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ import { Separator } from "@/components/ui/separator";
|
||||||
import { SOCIAL_LINKS } from "@/lib/site/social";
|
import { SOCIAL_LINKS } from "@/lib/site/social";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Privacy Policy - OpenCut",
|
title: "Privacy Policy - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Learn how OpenCut handles your data and privacy. Our commitment to protecting your information while you edit videos.",
|
"Learn how NeuralCut handles your data and privacy. Our commitment to protecting your information while you edit videos.",
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "Privacy Policy - OpenCut",
|
title: "Privacy Policy - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Learn how OpenCut handles your data and privacy. Our commitment to protecting your information while you edit videos.",
|
"Learn how NeuralCut handles your data and privacy. Our commitment to protecting your information while you edit videos.",
|
||||||
type: "website",
|
type: "website",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -49,7 +49,7 @@ export default function PrivacyPage() {
|
||||||
too - nothing is uploaded
|
too - nothing is uploaded
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
OpenCut does not currently require an account or login
|
NeuralCut does not currently require an account or login
|
||||||
</li>
|
</li>
|
||||||
<li>Project data stays on your device, not our servers</li>
|
<li>Project data stays on your device, not our servers</li>
|
||||||
<li>
|
<li>
|
||||||
|
|
@ -88,7 +88,7 @@ export default function PrivacyPage() {
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Accounts & Authentication</h2>
|
<h2 className="text-2xl font-semibold">Accounts & Authentication</h2>
|
||||||
<p>
|
<p>
|
||||||
OpenCut does not currently offer user accounts, login, or Google
|
NeuralCut does not currently offer user accounts, login, or Google
|
||||||
sign-in.
|
sign-in.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -139,7 +139,7 @@ export default function PrivacyPage() {
|
||||||
|
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Third-Party Services</h2>
|
<h2 className="text-2xl font-semibold">Third-Party Services</h2>
|
||||||
<p>OpenCut integrates with these services:</p>
|
<p>NeuralCut integrates with these services:</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>
|
<li>
|
||||||
<strong>Vercel:</strong> For hosting and content delivery
|
<strong>Vercel:</strong> For hosting and content delivery
|
||||||
|
|
@ -154,7 +154,7 @@ export default function PrivacyPage() {
|
||||||
<h2 className="text-2xl font-semibold">Your Rights</h2>
|
<h2 className="text-2xl font-semibold">Your Rights</h2>
|
||||||
<p>You have complete control over your data:</p>
|
<p>You have complete control over your data:</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>No account is required to use OpenCut today</li>
|
<li>No account is required to use NeuralCut today</li>
|
||||||
<li>Clear local storage to remove all saved projects</li>
|
<li>Clear local storage to remove all saved projects</li>
|
||||||
<li>Contact us with any privacy concerns</li>
|
<li>Contact us with any privacy concerns</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -163,7 +163,7 @@ export default function PrivacyPage() {
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Open Source Transparency</h2>
|
<h2 className="text-2xl font-semibold">Open Source Transparency</h2>
|
||||||
<p>
|
<p>
|
||||||
OpenCut is completely open source. You can review our code, see
|
NeuralCut is completely open source. You can review our code, see
|
||||||
exactly how we handle data, and even self-host the application if you
|
exactly how we handle data, and even self-host the application if you
|
||||||
prefer.
|
prefer.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ const roadmapItems: RoadmapItem[] = [
|
||||||
{
|
{
|
||||||
title: "Native app (mobile/desktop)",
|
title: "Native app (mobile/desktop)",
|
||||||
description:
|
description:
|
||||||
"Native OpenCut apps for Mac, Windows, Linux, and iOS/Android.",
|
"Native NeuralCut apps for Mac, Windows, Linux, and iOS/Android.",
|
||||||
status: {
|
status: {
|
||||||
text: "Not started",
|
text: "Not started",
|
||||||
type: "default",
|
type: "default",
|
||||||
|
|
@ -60,28 +60,28 @@ const roadmapItems: RoadmapItem[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Roadmap - OpenCut",
|
title: "Roadmap - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"See what's coming next for OpenCut - the free, open-source video editor that respects your privacy.",
|
"See what's coming next for NeuralCut - the free, open-source video editor that respects your privacy.",
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "OpenCut Roadmap - What's Coming Next",
|
title: "NeuralCut Roadmap - What's Coming Next",
|
||||||
description:
|
description:
|
||||||
"See what's coming next for OpenCut - the free, open-source video editor that respects your privacy.",
|
"See what's coming next for NeuralCut - the free, open-source video editor that respects your privacy.",
|
||||||
type: "website",
|
type: "website",
|
||||||
images: [
|
images: [
|
||||||
{
|
{
|
||||||
url: "/open-graph/roadmap.jpg",
|
url: "/open-graph/roadmap.jpg",
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
alt: "OpenCut Roadmap",
|
alt: "NeuralCut Roadmap",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
card: "summary_large_image",
|
card: "summary_large_image",
|
||||||
title: "OpenCut Roadmap - What's Coming Next",
|
title: "NeuralCut Roadmap - What's Coming Next",
|
||||||
description:
|
description:
|
||||||
"See what's coming next for OpenCut - the free, open-source video editor that respects your privacy.",
|
"See what's coming next for NeuralCut - the free, open-source video editor that respects your privacy.",
|
||||||
images: ["/open-graph/roadmap.jpg"],
|
images: ["/open-graph/roadmap.jpg"],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -90,7 +90,7 @@ export default function RoadmapPage() {
|
||||||
return (
|
return (
|
||||||
<BasePage
|
<BasePage
|
||||||
title="Roadmap"
|
title="Roadmap"
|
||||||
description={`What's coming next for OpenCut (last updated: ${LAST_UPDATED})`}
|
description={`What's coming next for NeuralCut (last updated: ${LAST_UPDATED})`}
|
||||||
>
|
>
|
||||||
<div className="mx-auto flex max-w-4xl flex-col gap-16">
|
<div className="mx-auto flex max-w-4xl flex-col gap-16">
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
|
|
@ -100,7 +100,7 @@ export default function RoadmapPage() {
|
||||||
</div>
|
</div>
|
||||||
<GitHubContributeSection
|
<GitHubContributeSection
|
||||||
title="Want to help?"
|
title="Want to help?"
|
||||||
description="OpenCut is open source and built by the community. Every contribution,
|
description="NeuralCut is open source and built by the community. Every contribution,
|
||||||
no matter how small, helps us build the best free video editor
|
no matter how small, helps us build the best free video editor
|
||||||
possible."
|
possible."
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@ import { LinkSquare02Icon } from "@hugeicons/core-free-icons";
|
||||||
import { cn } from "@/utils/ui";
|
import { cn } from "@/utils/ui";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Sponsors - OpenCut",
|
title: "Sponsors - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Support OpenCut and help us build the future of free and open-source video editing.",
|
"Support NeuralCut and help us build the future of free and open-source video editing.",
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "Sponsors - OpenCut",
|
title: "Sponsors - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"Support OpenCut and help us build the future of free and open-source video editing.",
|
"Support NeuralCut and help us build the future of free and open-source video editing.",
|
||||||
type: "website",
|
type: "website",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -28,7 +28,7 @@ export default function SponsorsPage() {
|
||||||
Sponsors
|
Sponsors
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-muted-foreground mx-auto max-w-2xl text-xl leading-relaxed text-pretty">
|
<p className="text-muted-foreground mx-auto max-w-2xl text-xl leading-relaxed text-pretty">
|
||||||
Support OpenCut and help us build the future of privacy-first video
|
Support NeuralCut and help us build the future of privacy-first video
|
||||||
editing.
|
editing.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ import { Separator } from "@/components/ui/separator";
|
||||||
import { SOCIAL_LINKS } from "@/lib/site/social";
|
import { SOCIAL_LINKS } from "@/lib/site/social";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Terms of Service - OpenCut",
|
title: "Terms of Service - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"OpenCut's Terms of Service. Fair, transparent terms for our free and open-source video editor.",
|
"NeuralCut's Terms of Service. Fair, transparent terms for our free and open-source video editor.",
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "Terms of Service - OpenCut",
|
title: "Terms of Service - NeuralCut",
|
||||||
description:
|
description:
|
||||||
"OpenCut's Terms of Service. Fair, transparent terms for our free and open-source video editor.",
|
"NeuralCut's Terms of Service. Fair, transparent terms for our free and open-source video editor.",
|
||||||
type: "website",
|
type: "website",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -83,7 +83,7 @@ export default function TermsPage() {
|
||||||
processing happens locally on your device. We never see, store, or
|
processing happens locally on your device. We never see, store, or
|
||||||
have access to your files. We make no claims to ownership, licensing,
|
have access to your files. We make no claims to ownership, licensing,
|
||||||
or rights over your videos, projects, or any content you create using
|
or rights over your videos, projects, or any content you create using
|
||||||
OpenCut.
|
NeuralCut.
|
||||||
</p>
|
</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>
|
<li>
|
||||||
|
|
@ -91,25 +91,25 @@ export default function TermsPage() {
|
||||||
</li>
|
</li>
|
||||||
<li>You retain all intellectual property rights to your content</li>
|
<li>You retain all intellectual property rights to your content</li>
|
||||||
<li>You can export and use your content however you choose</li>
|
<li>You can export and use your content however you choose</li>
|
||||||
<li>No watermarks, no licensing restrictions from OpenCut</li>
|
<li>No watermarks, no licensing restrictions from NeuralCut</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">How You Can Use OpenCut</h2>
|
<h2 className="text-2xl font-semibold">How You Can Use NeuralCut</h2>
|
||||||
<p>OpenCut is free for personal and commercial use. You can:</p>
|
<p>NeuralCut is free for personal and commercial use. You can:</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>
|
<li>
|
||||||
Create videos for personal, educational, or commercial purposes
|
Create videos for personal, educational, or commercial purposes
|
||||||
</li>
|
</li>
|
||||||
<li>Use OpenCut for client work and paid projects</li>
|
<li>Use NeuralCut for client work and paid projects</li>
|
||||||
<li>Share and distribute videos created with OpenCut</li>
|
<li>Share and distribute videos created with NeuralCut</li>
|
||||||
<li>
|
<li>
|
||||||
Modify and distribute the OpenCut software (under MIT license)
|
Modify and distribute the NeuralCut software (under MIT license)
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
You're responsible for how you use OpenCut and the content you create.
|
You're responsible for how you use NeuralCut and the content you create.
|
||||||
Don't use it for anything illegal in your jurisdiction.
|
Don't use it for anything illegal in your jurisdiction.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -119,14 +119,14 @@ export default function TermsPage() {
|
||||||
<p>
|
<p>
|
||||||
AI features like auto captions run entirely in your browser using
|
AI features like auto captions run entirely in your browser using
|
||||||
on-device models. No content is uploaded to any server. These features
|
on-device models. No content is uploaded to any server. These features
|
||||||
are optional - you can use OpenCut without them.
|
are optional - you can use NeuralCut without them.
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Service</h2>
|
<h2 className="text-2xl font-semibold">Service</h2>
|
||||||
<p>
|
<p>
|
||||||
OpenCut does not currently require an account. The service is provided
|
NeuralCut does not currently require an account. The service is provided
|
||||||
"as is" without warranties. While we strive for reliability, we can't
|
"as is" without warranties. While we strive for reliability, we can't
|
||||||
guarantee uninterrupted service.
|
guarantee uninterrupted service.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -134,10 +134,10 @@ export default function TermsPage() {
|
||||||
|
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Open Source Benefits</h2>
|
<h2 className="text-2xl font-semibold">Open Source Benefits</h2>
|
||||||
<p>Because OpenCut is open source, you have additional rights:</p>
|
<p>Because NeuralCut is open source, you have additional rights:</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>Review our code to see exactly how we handle your data</li>
|
<li>Review our code to see exactly how we handle your data</li>
|
||||||
<li>Self-host OpenCut on your own servers</li>
|
<li>Self-host NeuralCut on your own servers</li>
|
||||||
<li>Modify the software to suit your needs</li>
|
<li>Modify the software to suit your needs</li>
|
||||||
<li>Contribute improvements back to the community</li>
|
<li>Contribute improvements back to the community</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -158,7 +158,7 @@ export default function TermsPage() {
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Limitations and Liability</h2>
|
<h2 className="text-2xl font-semibold">Limitations and Liability</h2>
|
||||||
<p>
|
<p>
|
||||||
OpenCut is provided free of charge. To the extent permitted by law:
|
NeuralCut is provided free of charge. To the extent permitted by law:
|
||||||
</p>
|
</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>We're not liable for any loss of data or content</li>
|
<li>We're not liable for any loss of data or content</li>
|
||||||
|
|
@ -178,7 +178,7 @@ export default function TermsPage() {
|
||||||
|
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Service Changes</h2>
|
<h2 className="text-2xl font-semibold">Service Changes</h2>
|
||||||
<p>We may update OpenCut and these terms:</p>
|
<p>We may update NeuralCut and these terms:</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>We'll notify you of significant changes to these terms</li>
|
<li>We'll notify you of significant changes to these terms</li>
|
||||||
<li>Continued use means you accept any updates</li>
|
<li>Continued use means you accept any updates</li>
|
||||||
|
|
@ -189,7 +189,7 @@ export default function TermsPage() {
|
||||||
|
|
||||||
<section className="flex flex-col gap-3">
|
<section className="flex flex-col gap-3">
|
||||||
<h2 className="text-2xl font-semibold">Stopping Use</h2>
|
<h2 className="text-2xl font-semibold">Stopping Use</h2>
|
||||||
<p>You can stop using OpenCut at any time:</p>
|
<p>You can stop using NeuralCut at any time:</p>
|
||||||
<ul className="list-disc space-y-2 pl-6">
|
<ul className="list-disc space-y-2 pl-6">
|
||||||
<li>Clear your browser data to remove local projects</li>
|
<li>Clear your browser data to remove local projects</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export function StoragePersistenceDialog() {
|
||||||
runs low.
|
runs low.
|
||||||
</p>
|
</p>
|
||||||
<p className="text-base text-muted-foreground">
|
<p className="text-base text-muted-foreground">
|
||||||
Allow OpenCut to protect them?
|
Allow NeuralCut to protect them?
|
||||||
</p>
|
</p>
|
||||||
</DialogBody>
|
</DialogBody>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import { useRouter } from "next/navigation";
|
||||||
import { FaDiscord } from "react-icons/fa6";
|
import { FaDiscord } from "react-icons/fa6";
|
||||||
import { ExportButton } from "./export-button";
|
import { ExportButton } from "./export-button";
|
||||||
import { FeedbackPopover } from "@/lib/feedback/components/feedback-popover";
|
import { FeedbackPopover } from "@/lib/feedback/components/feedback-popover";
|
||||||
import { ThemeToggle } from "../theme-toggle";
|
import { PaletteSelector } from "../palette-selector";
|
||||||
import { DEFAULT_LOGO_URL } from "@/lib/site/brand";
|
import { DEFAULT_LOGO_URL } from "@/lib/site/brand";
|
||||||
import { SOCIAL_LINKS } from "@/lib/site/social";
|
import { SOCIAL_LINKS } from "@/lib/site/social";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
@ -37,7 +37,7 @@ export function EditorHeader() {
|
||||||
<nav className="flex items-center gap-2">
|
<nav className="flex items-center gap-2">
|
||||||
<FeedbackPopover />
|
<FeedbackPopover />
|
||||||
<ExportButton />
|
<ExportButton />
|
||||||
<ThemeToggle />
|
<PaletteSelector />
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export function ExportButton() {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex items-center gap-1.5 rounded-md bg-[#38BDF8] px-[0.12rem] py-[0.12rem] text-white",
|
"flex items-center gap-1.5 rounded-md bg-export-ring px-[0.12rem] py-[0.12rem] text-white",
|
||||||
hasProject ? "cursor-pointer" : "cursor-not-allowed opacity-50",
|
hasProject ? "cursor-pointer" : "cursor-not-allowed opacity-50",
|
||||||
)}
|
)}
|
||||||
onClick={hasProject ? () => setIsExportPopoverOpen(true) : undefined}
|
onClick={hasProject ? () => setIsExportPopoverOpen(true) : undefined}
|
||||||
|
|
@ -78,11 +78,11 @@ export function ExportButton() {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="relative flex items-center gap-1.5 rounded-[0.6rem] bg-linear-270 from-[#2567EC] to-[#37B6F7] px-4 py-1 shadow-[0_1px_3px_0px_rgba(0,0,0,0.65)]">
|
<div className="relative flex items-center gap-1.5 rounded-[0.6rem] bg-linear-270 from-export-gradient-from to-export-gradient-to px-4 py-1 shadow-[0_1px_3px_0px_rgba(0,0,0,0.65)]">
|
||||||
<HugeiconsIcon icon={TransitionTopIcon} className="z-50 size-3.5" />
|
<HugeiconsIcon icon={TransitionTopIcon} className="z-50 size-3.5" />
|
||||||
<span className="z-50 text-[0.875rem]">Export</span>
|
<span className="z-50 text-[0.875rem]">Export</span>
|
||||||
<div className="absolute top-0 left-0 z-10 flex size-full items-center justify-center rounded-[0.6rem] bg-linear-to-t from-white/0 to-white/50">
|
<div className="absolute top-0 left-0 z-10 flex size-full items-center justify-center rounded-[0.6rem] bg-linear-to-t from-white/0 to-white/50">
|
||||||
<div className="absolute top-[0.08rem] z-50 h-[calc(100%-2px)] w-[calc(100%-2px)] rounded-[0.6rem] bg-linear-270 from-[#2567EC] to-[#37B6F7]"></div>
|
<div className="absolute top-[0.08rem] z-50 h-[calc(100%-2px)] w-[calc(100%-2px)] rounded-[0.6rem] bg-linear-270 from-export-gradient-from to-export-gradient-to"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export function MobileGate({ children }: MobileGateProps) {
|
||||||
Desktop only (for now)
|
Desktop only (for now)
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-muted-foreground text-sm leading-relaxed">
|
<p className="text-muted-foreground text-sm leading-relaxed">
|
||||||
OpenCut isn't optimized for mobile or iPad yet. Things will break
|
NeuralCut isn't optimized for mobile or iPad yet. Things will break
|
||||||
and the layout will be a mess. Come back on a desktop for the real
|
and the layout will be a mess. Come back on a desktop for the real
|
||||||
experience.
|
experience.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,13 @@ export function Onboarding() {
|
||||||
const getStepTitle = () => {
|
const getStepTitle = () => {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 0:
|
case 0:
|
||||||
return "Welcome to OpenCut Beta! 🎉";
|
return "Welcome to NeuralCut Beta! 🎉";
|
||||||
case 1:
|
case 1:
|
||||||
return "⚠️ This is a super early beta!";
|
return "⚠️ This is a super early beta!";
|
||||||
case 2:
|
case 2:
|
||||||
return "🦋 Have fun testing!";
|
return "🦋 Have fun testing!";
|
||||||
default:
|
default:
|
||||||
return "OpenCut Onboarding";
|
return "NeuralCut Onboarding";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -44,8 +44,8 @@ export function Onboarding() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<Title title="Welcome to OpenCut Beta! 🎉" />
|
<Title title="Welcome to NeuralCut Beta! 🎉" />
|
||||||
<Description description="You're among the first to try OpenCut - the fully open source CapCut alternative." />
|
<Description description="You're among the first to try NeuralCut - the fully open source CapCut alternative." />
|
||||||
</div>
|
</div>
|
||||||
<NextButton onClick={handleNext}>Next</NextButton>
|
<NextButton onClick={handleNext}>Next</NextButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -57,7 +57,7 @@ export function Onboarding() {
|
||||||
<Title title={getStepTitle()} />
|
<Title title={getStepTitle()} />
|
||||||
<Description description="There's still a ton of things to do to make this editor amazing." />
|
<Description description="There's still a ton of things to do to make this editor amazing." />
|
||||||
<Description description="A lot of features are still missing. We're working hard to build them out!" />
|
<Description description="A lot of features are still missing. We're working hard to build them out!" />
|
||||||
<Description description="If you're curious, check out our roadmap [here](https://opencut.app/roadmap)" />
|
<Description description="If you're curious, check out our roadmap [here](https://neuralcut.app/roadmap)" />
|
||||||
</div>
|
</div>
|
||||||
<NextButton onClick={handleNext}>Next</NextButton>
|
<NextButton onClick={handleNext}>Next</NextButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -68,7 +68,7 @@ export function Onboarding() {
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<Title title={getStepTitle()} />
|
<Title title={getStepTitle()} />
|
||||||
<Description
|
<Description
|
||||||
description={`Join our [Discord](${SOCIAL_LINKS.discord}), chat with cool people and share feedback to help make OpenCut the best editor ever.`}
|
description={`Join our [Discord](${SOCIAL_LINKS.discord}), chat with cool people and share feedback to help make NeuralCut the best editor ever.`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<NextButton onClick={handleClose}>Finish</NextButton>
|
<NextButton onClick={handleClose}>Finish</NextButton>
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,12 @@ export function Footer() {
|
||||||
<div className="mb-4 flex items-center justify-start gap-2">
|
<div className="mb-4 flex items-center justify-start gap-2">
|
||||||
<Image
|
<Image
|
||||||
src={DEFAULT_LOGO_URL}
|
src={DEFAULT_LOGO_URL}
|
||||||
alt="OpenCut"
|
alt="NeuralCut"
|
||||||
width={24}
|
width={24}
|
||||||
height={24}
|
height={24}
|
||||||
className="invert dark:invert-0"
|
className="invert dark:invert-0"
|
||||||
/>
|
/>
|
||||||
<span className="text-lg font-bold">OpenCut</span>
|
<span className="text-lg font-bold">NeuralCut</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-muted-foreground mb-5 text-sm md:text-left">
|
<p className="text-muted-foreground mb-5 text-sm md:text-left">
|
||||||
The privacy-first video editor that feels simple to use.
|
The privacy-first video editor that feels simple to use.
|
||||||
|
|
@ -114,7 +114,7 @@ export function Footer() {
|
||||||
<div className="flex flex-col items-start justify-between gap-4 pt-2 md:flex-row">
|
<div className="flex flex-col items-start justify-between gap-4 pt-2 md:flex-row">
|
||||||
<div className="text-muted-foreground flex items-center gap-4 text-sm">
|
<div className="text-muted-foreground flex items-center gap-4 text-sm">
|
||||||
<span>
|
<span>
|
||||||
© {new Date().getFullYear()} OpenCut, All Rights Reserved
|
© {new Date().getFullYear()} NeuralCut, All Rights Reserved
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { motion } from "motion/react";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import { ArrowRight } from "lucide-react";
|
import { ArrowRight } from "lucide-react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { ThemeToggle } from "./theme-toggle";
|
import { PaletteSelector } from "./palette-selector";
|
||||||
import {
|
import {
|
||||||
Copy01Icon,
|
Copy01Icon,
|
||||||
Download01Icon,
|
Download01Icon,
|
||||||
|
|
@ -57,7 +57,7 @@ export function Header() {
|
||||||
<Link href="/" className="flex items-center gap-3">
|
<Link href="/" className="flex items-center gap-3">
|
||||||
<Image
|
<Image
|
||||||
src={DEFAULT_LOGO_URL}
|
src={DEFAULT_LOGO_URL}
|
||||||
alt="OpenCut Logo"
|
alt="NeuralCut Logo"
|
||||||
className="invert dark:invert-0"
|
className="invert dark:invert-0"
|
||||||
width={32}
|
width={32}
|
||||||
height={32}
|
height={32}
|
||||||
|
|
@ -79,7 +79,7 @@ export function Header() {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
a.href = DEFAULT_LOGO_URL;
|
a.href = DEFAULT_LOGO_URL;
|
||||||
a.download = "opencut-logo.svg";
|
a.download = "neuralcut-logo.svg";
|
||||||
a.click();
|
a.click();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -130,7 +130,7 @@ export function Header() {
|
||||||
<ArrowRight className="size-4" />
|
<ArrowRight className="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
<ThemeToggle />
|
<PaletteSelector />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
@ -182,13 +182,8 @@ export function Header() {
|
||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
<ThemeToggle
|
<PaletteSelector
|
||||||
className="absolute right-8 bottom-8 size-10"
|
className="absolute right-8 bottom-8 [&>button]:size-10 [&_.hugeicons-icon]:!size-[1.2rem]"
|
||||||
iconClassName="!size-[1.2rem]"
|
|
||||||
onToggle={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export function Hero() {
|
||||||
src="/landing-page-dark.png"
|
src="/landing-page-dark.png"
|
||||||
height={1903.5}
|
height={1903.5}
|
||||||
width={1269}
|
width={1269}
|
||||||
alt="OpenCut video editor landing page background"
|
alt="NeuralCut video editor landing page background"
|
||||||
/>
|
/>
|
||||||
<div className="mx-auto flex w-full max-w-3xl flex-1 flex-col justify-center">
|
<div className="mx-auto flex w-full max-w-3xl flex-1 flex-col justify-center">
|
||||||
<div className="inline-block text-4xl font-bold tracking-tighter md:text-[4rem]">
|
<div className="inline-block text-4xl font-bold tracking-tighter md:text-[4rem]">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
import { useThemeStore, PALETTES } from "@/lib/themes";
|
||||||
|
import { cn } from "@/utils/ui";
|
||||||
|
import { CheckmarkCircle01Icon } from "@hugeicons/core-free-icons";
|
||||||
|
import { HugeiconsIcon } from "@hugeicons/react";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Sun03Icon } from "@hugeicons/core-free-icons";
|
||||||
|
|
||||||
|
export function PaletteSelector({ className }: { className?: string }) {
|
||||||
|
const { theme, setTheme } = useTheme();
|
||||||
|
const { paletteId, setPalette } = useThemeStore();
|
||||||
|
const activePalette = PALETTES.find((p) => p.id === paletteId);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cn("flex items-center gap-1", className)}>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
variant="ghost"
|
||||||
|
className="size-8"
|
||||||
|
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
|
||||||
|
>
|
||||||
|
<HugeiconsIcon icon={Sun03Icon} className="!size-[1.1rem]" />
|
||||||
|
</Button>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button variant="ghost" size="icon" className="size-8 gap-0 p-1">
|
||||||
|
<div className="flex gap-0.5">
|
||||||
|
{activePalette?.preview && (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="size-3 rounded-full border border-border"
|
||||||
|
style={{ backgroundColor: activePalette.preview.primary }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="size-3 rounded-full border border-border"
|
||||||
|
style={{ backgroundColor: activePalette.preview.accent }}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent align="end" className="w-48 p-2">
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<p className="text-muted-foreground px-2 text-xs font-medium">
|
||||||
|
Palette
|
||||||
|
</p>
|
||||||
|
{PALETTES.map((palette) => (
|
||||||
|
<button
|
||||||
|
key={palette.id}
|
||||||
|
type="button"
|
||||||
|
className={cn(
|
||||||
|
"flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-accent",
|
||||||
|
paletteId === palette.id && "bg-accent",
|
||||||
|
)}
|
||||||
|
onClick={() => setPalette(palette.id)}
|
||||||
|
>
|
||||||
|
<div className="flex gap-0.5">
|
||||||
|
<div
|
||||||
|
className="size-3.5 rounded-full border border-border"
|
||||||
|
style={{ backgroundColor: palette.preview.primary }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="size-3.5 rounded-full border border-border"
|
||||||
|
style={{ backgroundColor: palette.preview.background }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="size-3.5 rounded-full border border-border"
|
||||||
|
style={{ backgroundColor: palette.preview.accent }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span className="flex-1 text-left">{palette.name}</span>
|
||||||
|
{paletteId === palette.id && (
|
||||||
|
<HugeiconsIcon
|
||||||
|
icon={CheckmarkCircle01Icon}
|
||||||
|
className="text-primary !size-4"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
const DISMISSED_KEY = "opencut-storage-persist-dismissed";
|
const DISMISSED_KEY = "neuralcut-storage-persist-dismissed";
|
||||||
|
|
||||||
function isFirefox(): boolean {
|
function isFirefox(): boolean {
|
||||||
return navigator.userAgent.toLowerCase().includes("firefox");
|
return navigator.userAgent.toLowerCase().includes("firefox");
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export const auth = betterAuth({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
baseURL: webEnv.NEXT_PUBLIC_SITE_URL,
|
baseURL: webEnv.NEXT_PUBLIC_SITE_URL,
|
||||||
appName: "OpenCut",
|
appName: "NeuralCut",
|
||||||
trustedOrigins: [webEnv.NEXT_PUBLIC_SITE_URL],
|
trustedOrigins: [webEnv.NEXT_PUBLIC_SITE_URL],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export const SITE_URL = "https://opencut.app";
|
export const SITE_URL = "https://neuralcut.app";
|
||||||
|
|
||||||
export const SITE_INFO = {
|
export const SITE_INFO = {
|
||||||
title: "OpenCut",
|
title: "NeuralCut",
|
||||||
description:
|
description:
|
||||||
"A simple but powerful video editor that gets the job done. In your browser.",
|
"A simple but powerful video editor that gets the job done. In your browser.",
|
||||||
url: SITE_URL,
|
url: SITE_URL,
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ export const EXTERNAL_TOOLS: ExternalTool[] = [
|
||||||
{
|
{
|
||||||
name: "Marble",
|
name: "Marble",
|
||||||
description:
|
description:
|
||||||
"Modern headless CMS for content management and the blog for OpenCut",
|
"Modern headless CMS for content management and the blog for NeuralCut",
|
||||||
url: "https://marblecms.com?utm_source=opencut",
|
url: "https://marblecms.com?utm_source=opencut",
|
||||||
icon: OcMarbleIcon,
|
icon: OcMarbleIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Databuddy",
|
name: "Databuddy",
|
||||||
description: "GDPR compliant analytics and user insights for OpenCut",
|
description: "GDPR compliant analytics and user insights for NeuralCut",
|
||||||
url: "https://databuddy.cc?utm_source=opencut",
|
url: "https://databuddy.cc?utm_source=opencut",
|
||||||
icon: OcDataBuddyIcon,
|
icon: OcDataBuddyIcon,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export const SPONSORS: Sponsor[] = [
|
||||||
name: "Vercel",
|
name: "Vercel",
|
||||||
url: "https://vercel.com?utm_source=opencut",
|
url: "https://vercel.com?utm_source=opencut",
|
||||||
logo: "/logos/others/vercel.svg",
|
logo: "/logos/others/vercel.svg",
|
||||||
description: "Platform where we deploy and host OpenCut.",
|
description: "Platform where we deploy and host NeuralCut.",
|
||||||
invertOnDark: true,
|
invertOnDark: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { useThemeStore } from "./theme-store";
|
||||||
|
export { PALETTES, getPaletteById } from "./palettes";
|
||||||
|
export type { PaletteMeta } from "./types";
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import type { PaletteMeta } from "../types";
|
||||||
|
|
||||||
|
export const CLASSIC_PALETTE: PaletteMeta = {
|
||||||
|
id: "classic",
|
||||||
|
name: "Classic",
|
||||||
|
preview: {
|
||||||
|
primary: "#15A0E6",
|
||||||
|
background: "#0D0D0D",
|
||||||
|
accent: "#333333",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { NEURALCUT_PALETTE } from "./neuralcut";
|
||||||
|
import { CLASSIC_PALETTE } from "./classic";
|
||||||
|
import type { PaletteMeta } from "../types";
|
||||||
|
|
||||||
|
export const PALETTES: PaletteMeta[] = [NEURALCUT_PALETTE, CLASSIC_PALETTE];
|
||||||
|
|
||||||
|
export function getPaletteById(id: string): PaletteMeta | undefined {
|
||||||
|
return PALETTES.find((p) => p.id === id);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import type { PaletteMeta } from "../types";
|
||||||
|
|
||||||
|
export const NEURALCUT_PALETTE: PaletteMeta = {
|
||||||
|
id: "neuralcut",
|
||||||
|
name: "NeuralCut",
|
||||||
|
preview: {
|
||||||
|
primary: "#F55385",
|
||||||
|
background: "#1B212B",
|
||||||
|
accent: "#BC466D",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { ThemeProvider } from "next-themes";
|
||||||
|
import { useThemeStore } from "@/lib/themes";
|
||||||
|
|
||||||
|
const PALETTE_SCRIPT = `
|
||||||
|
(function(){
|
||||||
|
try {
|
||||||
|
var s = localStorage.getItem('neuralcut-theme');
|
||||||
|
if (s) {
|
||||||
|
var d = JSON.parse(s);
|
||||||
|
if (d && d.state && d.state.paletteId) {
|
||||||
|
document.documentElement.setAttribute('data-palette', d.state.paletteId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('data-palette', 'neuralcut');
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
document.documentElement.setAttribute('data-palette', 'neuralcut');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function NeuralCutThemeProvider({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
const paletteId = useThemeStore((s) => s.paletteId);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.documentElement.setAttribute("data-palette", paletteId);
|
||||||
|
}, [paletteId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<script dangerouslySetInnerHTML={{ __html: PALETTE_SCRIPT }} />
|
||||||
|
<ThemeProvider
|
||||||
|
attribute="class"
|
||||||
|
defaultTheme="system"
|
||||||
|
disableTransitionOnChange
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ThemeProvider>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { create } from "zustand";
|
||||||
|
import { persist } from "zustand/middleware";
|
||||||
|
import { NEURALCUT_PALETTE } from "./palettes/neuralcut";
|
||||||
|
|
||||||
|
interface ThemeState {
|
||||||
|
paletteId: string;
|
||||||
|
setPalette: (id: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useThemeStore = create<ThemeState>()(
|
||||||
|
persist(
|
||||||
|
(set) => ({
|
||||||
|
paletteId: NEURALCUT_PALETTE.id,
|
||||||
|
setPalette: (id: string) => set({ paletteId: id }),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: "neuralcut-theme",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
export interface PaletteMeta {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
preview: { primary: string; background: string; accent: string };
|
||||||
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ export const useKeybindingsStore = create<KeybindingsState>()(
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: "opencut-keybindings",
|
name: "neuralcut-keybindings",
|
||||||
version: CURRENT_VERSION,
|
version: CURRENT_VERSION,
|
||||||
partialize: (state) => ({
|
partialize: (state) => ({
|
||||||
keybindings: state.keybindings,
|
keybindings: state.keybindings,
|
||||||
|
|
|
||||||
16
package.json
16
package.json
|
|
@ -1,25 +1,25 @@
|
||||||
{
|
{
|
||||||
"name": "opencut",
|
"name": "neuralcut",
|
||||||
"packageManager": "bun@1.2.18",
|
"packageManager": "bun@1.2.18",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*",
|
"apps/*",
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:tools": "turbo run build --filter=@opencut/tools",
|
"build:tools": "turbo run build --filter=@neuralcut/tools",
|
||||||
"build:wasm": "wasm-pack build rust/wasm --target bundler --out-dir pkg",
|
"build:wasm": "wasm-pack build rust/wasm --target bundler --out-dir pkg",
|
||||||
"build:web": "turbo run build --filter=@opencut/web",
|
"build:web": "turbo run build --filter=@neuralcut/web",
|
||||||
"deploy:web": "turbo run deploy --filter=@opencut/web",
|
"deploy:web": "turbo run deploy --filter=@neuralcut/web",
|
||||||
"dev:tools": "turbo run dev --filter=@opencut/tools",
|
"dev:tools": "turbo run dev --filter=@neuralcut/tools",
|
||||||
"dev:wasm": "cargo watch -w rust/crates -w rust/wasm/src -s 'wasm-pack build rust/wasm --target bundler --out-dir pkg'",
|
"dev:wasm": "cargo watch -w rust/crates -w rust/wasm/src -s 'wasm-pack build rust/wasm --target bundler --out-dir pkg'",
|
||||||
"dev:web": "turbo run dev --filter=@opencut/web",
|
"dev:web": "turbo run dev --filter=@neuralcut/web",
|
||||||
"format:web": "biome format apps/web/src/services/renderer --write --max-diagnostics=1000",
|
"format:web": "biome format apps/web/src/services/renderer --write --max-diagnostics=1000",
|
||||||
"generate:fonts": "npx tsx apps/web/scripts/generate-font-sprites.ts",
|
"generate:fonts": "npx tsx apps/web/scripts/generate-font-sprites.ts",
|
||||||
"lint:web": "biome lint apps/web/src --max-diagnostics=1000",
|
"lint:web": "biome lint apps/web/src --max-diagnostics=1000",
|
||||||
"lint:web:fix": "biome lint apps/web/src --write --unsafe --max-diagnostics=1000",
|
"lint:web:fix": "biome lint apps/web/src --write --unsafe --max-diagnostics=1000",
|
||||||
"preview:web": "turbo run preview --filter=@opencut/web",
|
"preview:web": "turbo run preview --filter=@neuralcut/web",
|
||||||
"publish:wasm": "bun run build:wasm && npm publish rust/wasm/pkg --access public",
|
"publish:wasm": "bun run build:wasm && npm publish rust/wasm/pkg --access public",
|
||||||
"start:tools": "turbo run start --filter=@opencut/tools",
|
"start:tools": "turbo run start --filter=@neuralcut/tools",
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue