Merge branch 'main' into batua
2
.gitignore
vendored
@@ -36,3 +36,5 @@ yarn-error.log*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
!src/app/.env/
|
||||||
7
.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": true,
|
||||||
|
"semi": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"plugins": ["prettier-plugin-tailwindcss"]
|
||||||
|
}
|
||||||
11
README.md
@@ -1,13 +1,16 @@
|
|||||||
<p align="center">
|
<div align="center">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://www.zen-browser.app/logos/zen-alpha-white.svg">
|
<img src="./public/logos/zen-alpha-white.svg" width="128px">
|
||||||
<img src="https://www.zen-browser.app/logos/zen-alpha-black.svg" width="64px">
|
|
||||||
</picture>
|
</picture>
|
||||||
</p>
|
</div>
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
Zen Browser Website
|
Zen Browser Website
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
[](https://www.jsdelivr.com/package/gh/zen-browser/www)
|
||||||
|
|
||||||
|
[Analytics](https://plausible.io/zen-browser.app/) | [Uptime-Phare](https://uptime.zen-browser.app)
|
||||||
|
|
||||||
This repository contains the source code for the Zen Browser Website. We are thrilled to welcome you to our community. Before you start, please read this document to understand how you can contribute to this project.
|
This repository contains the source code for the Zen Browser Website. We are thrilled to welcome you to our community. Before you start, please read this document to understand how you can contribute to this project.
|
||||||
|
|
||||||
Zen Browser's website is built with [Next.js](https://nextjs.org/), [TypeScript](https://www.typescriptlang.org/), and [Tailwind CSS](https://tailwindcss.com/).
|
Zen Browser's website is built with [Next.js](https://nextjs.org/), [TypeScript](https://www.typescriptlang.org/), and [Tailwind CSS](https://tailwindcss.com/).
|
||||||
|
|||||||
45
next.config.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = (phase, { defaultConfig }) => {
|
||||||
|
const defaultConfigWWW = {
|
||||||
|
images: {
|
||||||
|
remotePatterns: [
|
||||||
|
{
|
||||||
|
protocol: "https",
|
||||||
|
hostname: "raw.githubusercontent.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
protocol: "https",
|
||||||
|
hostname: "cdn.jsdelivr.net",
|
||||||
|
port: '',
|
||||||
|
pathname: '/gh/zen-browser/**',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
domains: ['localhost', 'cdn.jsdelivr.net', "raw.githubusercontent.com"], // Allow images from jsDelivr
|
||||||
|
},
|
||||||
|
experimental: {
|
||||||
|
serverActions: {
|
||||||
|
// edit: updated to new key. Was previously `allowedForwardedHosts`
|
||||||
|
allowedOrigins: ["localhost:3000", "get-zen.vercel.app"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
compiler: {
|
||||||
|
styledComponents: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (phase === PHASE_DEVELOPMENT_SERVER) {
|
||||||
|
return {
|
||||||
|
...defaultConfigWWW,
|
||||||
|
// development only config options here
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...defaultConfigWWW,
|
||||||
|
// production only config options here
|
||||||
|
output: 'export',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = nextConfig;
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
|
||||||
const nextConfig = {
|
|
||||||
output: 'export',
|
|
||||||
images: {
|
|
||||||
remotePatterns: [
|
|
||||||
{
|
|
||||||
protocol: "https",
|
|
||||||
hostname: "raw.githubusercontent.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
protocol: "https",
|
|
||||||
hostname: "cdn.jsdelivr.net",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
domains: ['cdn.jsdelivr.net', "raw.githubusercontent.com"], // Allow images from jsDelivr
|
|
||||||
},
|
|
||||||
experimental: {
|
|
||||||
serverActions: {
|
|
||||||
// edit: updated to new key. Was previously `allowedForwardedHosts`
|
|
||||||
allowedOrigins: ["localhost:3000", "get-zen.vercel.app"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
compiler: {
|
|
||||||
styledComponents: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default nextConfig;
|
|
||||||
4352
package-lock.json
generated
@@ -9,10 +9,14 @@
|
|||||||
"dev": "next dev --turbo",
|
"dev": "next dev --turbo",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint",
|
||||||
|
"pages:build": "npx @cloudflare/next-on-pages",
|
||||||
|
"preview": "npm run pages:build && wrangler pages dev",
|
||||||
|
"deploy": "npm run pages:build && wrangler pages deploy"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^3.9.0",
|
"@hookform/resolvers": "^3.9.0",
|
||||||
|
"@radix-ui/react-accordion": "^1.2.0",
|
||||||
"@radix-ui/react-checkbox": "^1.1.1",
|
"@radix-ui/react-checkbox": "^1.1.1",
|
||||||
"@radix-ui/react-dialog": "^1.1.1",
|
"@radix-ui/react-dialog": "^1.1.1",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
@@ -48,6 +52,7 @@
|
|||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@cloudflare/next-on-pages": "^1.13.2",
|
||||||
"@types/canvas-confetti": "^1.6.4",
|
"@types/canvas-confetti": "^1.6.4",
|
||||||
"@types/node": "^20.14.15",
|
"@types/node": "^20.14.15",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.3",
|
||||||
@@ -56,6 +61,8 @@
|
|||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-next": "14.2.4",
|
"eslint-config-next": "14.2.4",
|
||||||
"postcss": "^8.4.41",
|
"postcss": "^8.4.41",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.6.6",
|
||||||
"tailwindcss": "^3.4.9",
|
"tailwindcss": "^3.4.9",
|
||||||
"typescript": "^5.5.4"
|
"typescript": "^5.5.4"
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
public/browser-1.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/browser-2.png
Normal file
|
After Width: | Height: | Size: 701 KiB |
BIN
public/browser-3.png
Normal file
|
After Width: | Height: | Size: 198 KiB |
BIN
public/browser-4.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
public/feature-item-1.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
public/logos/zen-alpha-black.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
public/themes.webp
Normal file
|
After Width: | Height: | Size: 155 KiB |
7
src/app/.env/page.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
export default function WhyAreYouEvenHere() {
|
||||||
|
redirect("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
39
src/app/about/page.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
"use client";
|
||||||
|
import Footer from "@/components/footer";
|
||||||
|
import { Navigation } from "@/components/navigation";
|
||||||
|
import { releaseNoteIsAlpha, releaseNotes } from "@/lib/release-notes";
|
||||||
|
import Link from "next/link";
|
||||||
|
import Markdown from 'react-markdown'
|
||||||
|
import '../privacy-policy/markdown.css';
|
||||||
|
|
||||||
|
export default function PrivacyPolicy() {
|
||||||
|
return (
|
||||||
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
|
<div id="policy" className="min-h-screen py-42 flex mx-auto my-52 p-10 lg:p-0 w-full lg:w-1/3 flex-col">
|
||||||
|
<Markdown>
|
||||||
|
{`
|
||||||
|
# Main Developer Team
|
||||||
|
|
||||||
|
* [**Mauro Baladés**](https://github.com/mauro-balades): Creator, Main Developer, and a funny guy.
|
||||||
|
* **Oscar Gonzalez**: Site Reliability Engineer (SRE) and code signing.
|
||||||
|
* [**Onno**](https://www.onnno.nl/index.html): logo designer.
|
||||||
|
* [**Jafeth Garro**](https://iamjafeth.com/): Documentation writer.
|
||||||
|
* **Peter Jung**: general contributor and AUR maintainer.
|
||||||
|
* [**Gunir**](https://github.com/gunir): Active contributor.
|
||||||
|
* [**n7itro**](https://github.com/n7itro): Active contributor.
|
||||||
|
* [**Canoa**](https://thatcanoa.org/) Active contributor, and very active in issue handling
|
||||||
|
* [**Jan Heres**](https://janheres.eu/): Active contributor and helps with MacOS builds.
|
||||||
|
|
||||||
|
# Many more contributors
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|

|
||||||
|
`}
|
||||||
|
</Markdown>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { getAllThemes, getThemeFromId } from '@/lib/themes';
|
|
||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
||||||
import { NextRequest, NextResponse } from 'next/server';
|
|
||||||
|
|
||||||
// Static NextJS API route. We will have /get-theme?id=theme-id static route
|
|
||||||
export async function generateStaticParams() {
|
|
||||||
const themes = await getAllThemes();
|
|
||||||
return themes.map((theme) => ({
|
|
||||||
id: theme.id,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function removeUneccessaryKeys(theme: any) {
|
|
||||||
delete theme["isDarkMode"];
|
|
||||||
delete theme["isColorTheme"];
|
|
||||||
return theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function GET(request: any, { params }: { params: { id: string } }) {
|
|
||||||
const themes = await getAllThemes();
|
|
||||||
const theme = themes.find((theme) => theme.id === params.id);
|
|
||||||
console.log(theme);
|
|
||||||
return NextResponse.json(removeUneccessaryKeys(theme));
|
|
||||||
}
|
|
||||||
@@ -6,8 +6,6 @@ export default function BrandingAssetsPage() {
|
|||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
<BrandingAssets />
|
<BrandingAssets />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ export default function BrandingAssetsPage() {
|
|||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
<CreateThemePage />
|
<CreateThemePage />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ export default function Download() {
|
|||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
<DownloadPage />
|
<DownloadPage />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
--color-two: #fe8bbb;
|
--color-two: #fe8bbb;
|
||||||
--color-three: #9e7aff;
|
--color-three: #9e7aff;
|
||||||
|
|
||||||
|
--surface: rgb(245, 245, 245);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
--color-one: #37ecba;
|
--color-one: #37ecba;
|
||||||
--color-two: #72afd3;
|
--color-two: #72afd3;
|
||||||
@@ -48,10 +50,12 @@
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
[data-theme='dark'], .dark {
|
||||||
--background: 0 0% 0%;
|
--background: 0 0% 0%;
|
||||||
--foreground: 0 0% 98%;
|
--foreground: 0 0% 98%;
|
||||||
|
|
||||||
|
--surface: rgb(23, 23, 23);
|
||||||
|
|
||||||
--card: 0 0% 3.9%;
|
--card: 0 0% 3.9%;
|
||||||
--card-foreground: 0 0% 98%;
|
--card-foreground: 0 0% 98%;
|
||||||
|
|
||||||
@@ -81,10 +85,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
|
html {
|
||||||
|
@apply scroll-smooth;
|
||||||
|
}
|
||||||
* {
|
* {
|
||||||
@apply border-border;
|
@apply border-border;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,8 @@ import { Inter } from "next/font/google";
|
|||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { ThemeProvider } from "@/components/theme-provider";
|
import { ThemeProvider } from "@/components/theme-provider";
|
||||||
import StyledComponentsRegistry from "@/lib/styled-components-registry";
|
import StyledComponentsRegistry from "@/lib/styled-components-registry";
|
||||||
|
import Footer from "@/components/footer";
|
||||||
|
import { Navigation } from "@/components/navigation";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
@@ -12,25 +14,32 @@ export const metadata: Metadata = {
|
|||||||
keywords: ["Zen", "Browser", "Zen Browser", "Web", "Internet", "Fast"],
|
keywords: ["Zen", "Browser", "Zen Browser", "Web", "Internet", "Fast"],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang="en" suppressHydrationWarning>
|
<html suppressHydrationWarning>
|
||||||
<head>
|
<head>
|
||||||
<link rel="me" href="https://fosstodon.org/@zenbrowser"></link>
|
<link rel="me" href="https://fosstodon.org/@zenbrowser"></link>
|
||||||
|
<script defer data-domain="zen-browser.app" src="https://plausible.io/js/script.js"></script>
|
||||||
<link rel="alternate" type="application/rss+xml" title="Zen Browser Release Notes" href="https://www.zen-browser.app/feed.xml" />
|
<link rel="alternate" type="application/rss+xml" title="Zen Browser Release Notes" href="https://www.zen-browser.app/feed.xml" />
|
||||||
</head>
|
</head>
|
||||||
<body className={inter.className}>
|
<body className={inter.className}>
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
attribute="class"
|
attribute="class"
|
||||||
defaultTheme="dark"
|
|
||||||
enableSystem
|
enableSystem
|
||||||
disableTransitionOnChange
|
disableTransitionOnChange
|
||||||
>
|
>
|
||||||
<StyledComponentsRegistry>{children}</StyledComponentsRegistry>
|
<StyledComponentsRegistry>
|
||||||
|
<div>
|
||||||
|
{children}
|
||||||
|
<Footer />
|
||||||
|
<Navigation /> {/* At the bottom of the page */}
|
||||||
|
</div>
|
||||||
|
</StyledComponentsRegistry>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
8
src/app/not-found.tsx
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
export default function NotFoundPage() {
|
||||||
|
return (
|
||||||
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
|
<h1>404</h1>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -10,8 +10,6 @@ export default function Home() {
|
|||||||
<main className="flex min-h-screen overflow-x-hidden flex-col items-center justify-start">
|
<main className="flex min-h-screen overflow-x-hidden flex-col items-center justify-start">
|
||||||
<Header />
|
<Header />
|
||||||
<Features />
|
<Features />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ You can also optionally enable telemetry data collection and other Mozilla Resea
|
|||||||
# 9. Contact Us
|
# 9. Contact Us
|
||||||
If you have any questions or concerns about this Privacy Policy or Zen Browser, please contact us at:
|
If you have any questions or concerns about this Privacy Policy or Zen Browser, please contact us at:
|
||||||
|
|
||||||
* Discord: [Zen Browser's Discord](https://discord.gg/nnShMQzR4b)
|
* Discord: [Zen Browser's Discord](https://discord.com/servers/mauro-s-little-sweatshop-1088172780480114748)
|
||||||
* GitHub: [Organization](https://github.com/zen-browser)
|
* GitHub: [Organization](https://github.com/zen-browser)
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -91,8 +91,6 @@ If you have any questions or concerns about this Privacy Policy or Zen Browser,
|
|||||||
By using Zen Browser, you agree to this Privacy Policy. Remember, with Zen, your privacy is in your hands.`}
|
By using Zen Browser, you agree to this Privacy Policy. Remember, with Zen, your privacy is in your hands.`}
|
||||||
</Markdown>
|
</Markdown>
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,22 +24,18 @@ export default function ReleaseNotePage({ params }: { params: { version: string
|
|||||||
<main className="flex min-h-screen flex-col items-center justify-center">
|
<main className="flex min-h-screen flex-col items-center justify-center">
|
||||||
<div className="h-screen flex flex-wrap items-center justify-center">
|
<div className="h-screen flex flex-wrap items-center justify-center">
|
||||||
<h1 className="text-4xl font-bold mt-12">Release note not found</h1>
|
<h1 className="text-4xl font-bold mt-12">Release note not found</h1>
|
||||||
<Link href="/release-notes">
|
<a href="/release-notes">
|
||||||
<Button className="mt-4 items-center justify-center">
|
<Button className="mt-4 items-center justify-center">
|
||||||
Back to release notes
|
Back to release notes
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-center">
|
<main className="flex min-h-screen flex-col items-center justify-center">
|
||||||
<ReleaseNote data={releaseNote} />
|
<ReleaseNote data={releaseNote} />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export default function ReleaseNotes() {
|
|||||||
<h1 className="text-4xl text-center font-bold mt-24">Release Notes</h1>
|
<h1 className="text-4xl text-center font-bold mt-24">Release Notes</h1>
|
||||||
<div className="grid gap-5 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 mt-10">
|
<div className="grid gap-5 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 mt-10">
|
||||||
{releaseNotes.map((releaseNote) => (
|
{releaseNotes.map((releaseNote) => (
|
||||||
<Link href={`/release-notes/${releaseNote.version}`} className="bg-background relative max-w-64 overflow-hidden rounded-lg border p-5 hover:border-blue-500 transition-all duration-300 hover:-translate-y-1 hover:-translate-x-1" key={releaseNote.version}>
|
<a href={`/release-notes/${releaseNote.version}`} className="bg-background relative max-w-64 overflow-hidden rounded-lg border p-5 hover:border-blue-500 transition-all duration-300 hover:-translate-y-1 hover:-translate-x-1" key={releaseNote.version}>
|
||||||
<div className="text-md font-medium mb-5">
|
<div className="text-md font-medium mb-5">
|
||||||
{releaseNote.version}
|
{releaseNote.version}
|
||||||
</div>
|
</div>
|
||||||
@@ -24,12 +24,10 @@ export default function ReleaseNotes() {
|
|||||||
Alpha Release
|
Alpha Release
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Link>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,6 @@ export default async function ThemeInfoPage({ params }: { params: { theme: strin
|
|||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
<ThemePage themeID={theme} />
|
<ThemePage themeID={theme} />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
import Footer from "@/components/footer";
|
import Footer from "@/components/footer";
|
||||||
import MarketplacePage from "@/components/marketplace";
|
import MarketplacePage from "@/components/marketplace";
|
||||||
import { Navigation } from "@/components/navigation";
|
import { Navigation } from "@/components/navigation";
|
||||||
|
import { getAllThemes, ZenTheme } from "@/lib/themes";
|
||||||
|
import { GetStaticProps } from "next";
|
||||||
|
|
||||||
export default function ThemesMarketplace() {
|
export default async function ThemesMarketplace() {
|
||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
<MarketplacePage />
|
<MarketplacePage themes={await getAllThemes()} />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ export default function Download() {
|
|||||||
return (
|
return (
|
||||||
<main className="flex min-h-screen flex-col items-center justify-start">
|
<main className="flex min-h-screen flex-col items-center justify-start">
|
||||||
<WelcomePage />
|
<WelcomePage />
|
||||||
<Footer />
|
|
||||||
<Navigation /> {/* At the bottom of the page */}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/components/CachedImage.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
function imageLoader({ src }: { src: string }) {
|
||||||
|
return `https://cdn.jsdelivr.net/gh/zen-browser/${src}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CachedImage({ ...props }: any) {
|
||||||
|
return <Image {...props} loader={imageLoader} />;
|
||||||
|
}
|
||||||
@@ -215,20 +215,20 @@ export default function DownloadPage() {
|
|||||||
<div className="flex items-center justify-center flex-col">
|
<div className="flex items-center justify-center flex-col">
|
||||||
<h1 className="text-6xl font-bold">Downloaded! ❤️</h1>
|
<h1 className="text-6xl font-bold">Downloaded! ❤️</h1>
|
||||||
<p className="text-muted-foreground mt-3 text-center">
|
<p className="text-muted-foreground mt-3 text-center">
|
||||||
Zen Browser has been downloaded successfully. Enjoy browsing the
|
Your download of Zen Browser will begin shortly. Enjoy browsing the
|
||||||
web with Zen!
|
web with Zen!
|
||||||
</p>
|
</p>
|
||||||
<div className="flex font-bold mt-5 items-center justify-between mx-auto">
|
<div className="flex font-bold mt-5 items-center justify-between mx-auto">
|
||||||
<Link href="https://github.com/zen-browser">Source Code</Link>
|
<a href="https://github.com/zen-browser">Source Code</a>
|
||||||
<Link
|
<a
|
||||||
className="ml-5"
|
className="ml-5"
|
||||||
href="https://patreon.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
href="https://patreon.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
||||||
>
|
>
|
||||||
Donate
|
Donate
|
||||||
</Link>
|
</a>
|
||||||
<Link className="ml-5" href="/release-notes/latest">
|
<a className="ml-5" href="/release-notes/latest">
|
||||||
Release Notes
|
Release Notes
|
||||||
</Link>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{selectedPlatform === "MacOS" && (
|
{selectedPlatform === "MacOS" && (
|
||||||
<div className="mt-12 flex flex-col items-start border justify-between rounded-md bg-background p-5">
|
<div className="mt-12 flex flex-col items-start border justify-between rounded-md bg-background p-5">
|
||||||
@@ -246,7 +246,7 @@ export default function DownloadPage() {
|
|||||||
"https://docs.zen-browser.app/guides/install-macos")
|
"https://docs.zen-browser.app/guides/install-macos")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Download Zen for MacOS
|
Installation Instructions for MacOS
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -259,6 +259,7 @@ export default function DownloadPage() {
|
|||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{/*Changes for the Choose your platform as checkbox looks old*/}
|
||||||
<div className="relative w-full">
|
<div className="relative w-full">
|
||||||
{platform === null && (
|
{platform === null && (
|
||||||
<FormField enter={platform === null} out={platform !== null}>
|
<FormField enter={platform === null} out={platform !== null}>
|
||||||
@@ -266,39 +267,61 @@ export default function DownloadPage() {
|
|||||||
<FieldDescription>
|
<FieldDescription>
|
||||||
Choose the platform you want to download Zen for.
|
Choose the platform you want to download Zen for.
|
||||||
</FieldDescription>
|
</FieldDescription>
|
||||||
<div
|
<div className="flex">
|
||||||
onClick={() => setSelectedPlatform("Windows")}
|
<div
|
||||||
className={ny(
|
onClick={() => setSelectedPlatform("Windows")}
|
||||||
"select-none mb-2 px-4 py-3 flex items-center rounded-lg bg-background cursor-pointer border",
|
className={ny(
|
||||||
selectedPlatform === "Windows" ? "border-blue-400" : ""
|
"select-none mr-2 flex flex-col items-center justify-center rounded-lg bg-background cursor-pointer border",
|
||||||
)}
|
selectedPlatform === "Windows" ? "border-blue-400" : ""
|
||||||
>
|
)}
|
||||||
<Checkbox checked={selectedPlatform === "Windows"} />
|
style={{
|
||||||
<i className="devicon-windows8-original ml-3 p-2 border border-blue-400 rounded-lg"></i>
|
height: "11.25rem",
|
||||||
<div className="ml-2">Windows</div>
|
width: "18.75rem",
|
||||||
</div>
|
}}
|
||||||
<div
|
>
|
||||||
onClick={() => setSelectedPlatform("Linux")}
|
<i
|
||||||
className={ny(
|
className="devicon-windows8-original p-2 border border-blue-400 rounded-lg"
|
||||||
"select-none mb-2 px-4 py-3 flex items-center rounded-lg bg-background cursor-pointer border",
|
style={{ marginBottom: "10px" }}
|
||||||
selectedPlatform === "Linux" ? "border-yellow-400" : ""
|
></i>
|
||||||
)}
|
<div className="font-bold">Windows</div>
|
||||||
>
|
</div>
|
||||||
<Checkbox checked={selectedPlatform === "Linux"} />
|
|
||||||
<i className="devicon-linux-plain ml-3 p-2 border border-yellow-400 rounded-lg"></i>
|
<div
|
||||||
<div className="ml-2">Linux</div>
|
onClick={() => setSelectedPlatform("Linux")}
|
||||||
</div>
|
className={ny(
|
||||||
<div
|
"select-none mr-2 flex flex-col items-center justify-center rounded-lg bg-background cursor-pointer border",
|
||||||
onClick={() => setSelectedPlatform("MacOS")}
|
selectedPlatform === "Linux" ? "border-yellow-400" : ""
|
||||||
className={ny(
|
)}
|
||||||
"select-none mb-2 px-4 py-3 flex items-center rounded-lg bg-background cursor-pointer border",
|
style={{
|
||||||
selectedPlatform === "MacOS" ? "border-purple-400" : ""
|
height: "11.25rem",
|
||||||
)}
|
width: "18.75rem",
|
||||||
>
|
}}
|
||||||
<Checkbox checked={selectedPlatform === "MacOS"} />
|
>
|
||||||
<i className="devicon-apple-original p-2 border border-purple-400 ml-3 rounded-lg"></i>
|
<i
|
||||||
<div className="ml-2 font-bold">MacOS</div>
|
className="devicon-linux-plain p-2 border border-yellow-400 rounded-lg"
|
||||||
</div>
|
style={{ marginBottom: "10px" }}
|
||||||
|
></i>
|
||||||
|
<div className="font-bold">Linux</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
onClick={() => setSelectedPlatform("MacOS")}
|
||||||
|
className={ny(
|
||||||
|
"select-none flex flex-col items-center justify-center rounded-lg bg-background cursor-pointer border",
|
||||||
|
selectedPlatform === "MacOS" ? "border-purple-400" : ""
|
||||||
|
)}
|
||||||
|
style={{
|
||||||
|
height: "11.25rem",
|
||||||
|
width: "18.75rem",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="devicon-apple-original p-2 border border-purple-400 rounded-lg"
|
||||||
|
style={{ marginBottom: "10px" }}
|
||||||
|
></i>
|
||||||
|
<div className="font-bold">MacOS</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</FormField>
|
</FormField>
|
||||||
)}
|
)}
|
||||||
{/* Architecture */}
|
{/* Architecture */}
|
||||||
@@ -358,51 +381,45 @@ export default function DownloadPage() {
|
|||||||
</div>
|
</div>
|
||||||
</FormField>
|
</FormField>
|
||||||
)}
|
)}
|
||||||
{platform === "MacOS" && flowIndex === 1 && (
|
{platform === "MacOS" && flowIndex === 1 && (
|
||||||
<FormField
|
<FormField
|
||||||
enter={platform === "MacOS"}
|
enter={platform === "MacOS"}
|
||||||
out={platform !== "MacOS"}
|
out={platform !== "MacOS"}
|
||||||
>
|
>
|
||||||
<FieldTitle>Download Zen for MacOS</FieldTitle>
|
<FieldTitle>Download Zen for MacOS</FieldTitle>
|
||||||
<FieldDescription>
|
<FieldDescription>
|
||||||
Click the button below to download Zen for MacOS.
|
Click the button below to download Zen for MacOS.
|
||||||
</FieldDescription>
|
</FieldDescription>
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
<div
|
<div
|
||||||
onClick={() => setSelectedArchitecture("specific")}
|
onClick={() => setSelectedArchitecture("specific")}
|
||||||
className={ny(
|
className={ny(
|
||||||
"select-none w-full h-full mb-2 p-5 flex flex-col items-center rounded-lg bg-background cursor-pointer border",
|
"select-none w-full h-64 mb-2 p-5 flex flex-col items-center rounded-lg bg-background cursor-pointer border",
|
||||||
selectedArchitecture === "specific"
|
selectedArchitecture === "specific" ? "border-blue-400" : ""
|
||||||
? "border-blue-400"
|
)}
|
||||||
: ""
|
>
|
||||||
)}
|
<h1 className="text-5xl my-2 opacity-40 dark:opacity-20">🍏</h1>
|
||||||
>
|
<h1 className="text-2xl font-semibold my-2">AArch64</h1>
|
||||||
<h1 className="text-5xl my-2 opacity-40 dark:opacity-20">
|
<p className="text-muted-foreground mx-auto text-center">
|
||||||
🍏
|
64-bit ARM architecture, for Apple's M Series Chips
|
||||||
</h1>
|
</p>
|
||||||
<h1 className="text-2xl font-semibold my-2">AArch64</h1>
|
</div>
|
||||||
<p className="text-muted-foreground mx-auto text-center">64-bit ARM architecture, for Apple's M Series Chips</p>
|
<div
|
||||||
</div>
|
onClick={() => setSelectedArchitecture("generic")}
|
||||||
<div
|
className={ny(
|
||||||
onClick={() => setSelectedArchitecture("generic")}
|
"select-none w-full h-64 mb-2 ml-10 p-5 flex flex-col items-center rounded-lg bg-background cursor-pointer border",
|
||||||
className={ny(
|
selectedArchitecture === "generic" ? "border-blue-400" : ""
|
||||||
"select-none w-full h-full mb-2 ml-10 p-5 flex flex-col items-center rounded-lg bg-background cursor-pointer border",
|
)}
|
||||||
selectedArchitecture === "generic"
|
>
|
||||||
? "border-blue-400"
|
<h1 className="text-5xl font-bold my-2 opacity-40 dark:opacity-20">x64</h1>
|
||||||
: ""
|
<h1 className="text-2xl font-semibold my-2">Intel</h1>
|
||||||
)}
|
<p className="text-muted-foreground mx-auto text-center">
|
||||||
>
|
64-bit Intel architecture, for older Macs
|
||||||
<h1 className="text-5xl font-bold my-2 opacity-40 dark:opacity-20">
|
</p>
|
||||||
x64
|
</div>
|
||||||
</h1>
|
</div>
|
||||||
<h1 className="text-2xl font-semibold my-2">Intel</h1>
|
</FormField>
|
||||||
<p className="text-muted-foreground mx-auto text-center">
|
)}
|
||||||
64-bit Intel architecture, for older Macs
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FormField>
|
|
||||||
)}
|
|
||||||
{flowIndex === 2 && platform === "Windows" && (
|
{flowIndex === 2 && platform === "Windows" && (
|
||||||
<FormField
|
<FormField
|
||||||
enter={platform === "Windows" && flowIndex === 2}
|
enter={platform === "Windows" && flowIndex === 2}
|
||||||
@@ -551,13 +568,13 @@ export default function DownloadPage() {
|
|||||||
<InfoCircledIcon className="size-4 mr-2" />
|
<InfoCircledIcon className="size-4 mr-2" />
|
||||||
<p className="text-muted-foreground">
|
<p className="text-muted-foreground">
|
||||||
Confused about which build to choose?{" "}
|
Confused about which build to choose?{" "}
|
||||||
<Link
|
<a
|
||||||
href="https://docs.zen-browser.app/guides/generic-optimized"
|
href="https://docs.zen-browser.app/guides/generic-optimized"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="text-blue-400"
|
className="text-blue-400"
|
||||||
>
|
>
|
||||||
System requirements
|
System requirements
|
||||||
</Link>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,33 +1,45 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import Sticky from 'react-sticky-el';
|
import Sticky from 'react-sticky-el';
|
||||||
import {
|
import {
|
||||||
|
BookmarkCheckIcon,
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
ChevronLeft,
|
ChevronLeft,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
|
ExternalLinkIcon,
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
EyeOffIcon,
|
EyeOffIcon,
|
||||||
Github,
|
Github,
|
||||||
|
HeartHandshake,
|
||||||
|
HeartPulseIcon,
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
|
PaintBucket,
|
||||||
|
PersonStanding,
|
||||||
RabbitIcon,
|
RabbitIcon,
|
||||||
ShieldAlertIcon,
|
ShieldAlertIcon,
|
||||||
ShieldCheck,
|
ShieldCheck,
|
||||||
SidebarCloseIcon,
|
SidebarCloseIcon,
|
||||||
SidebarIcon,
|
SidebarIcon,
|
||||||
|
SidebarOpenIcon,
|
||||||
SpaceIcon,
|
SpaceIcon,
|
||||||
SplitSquareHorizontal,
|
SplitSquareHorizontal,
|
||||||
SplitSquareVertical,
|
SplitSquareVertical,
|
||||||
|
SplitSquareVerticalIcon,
|
||||||
|
TableIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
Cross1Icon,
|
Cross1Icon,
|
||||||
EyeClosedIcon,
|
EyeClosedIcon,
|
||||||
HeartFilledIcon,
|
HeartFilledIcon,
|
||||||
|
Link1Icon,
|
||||||
LockClosedIcon,
|
LockClosedIcon,
|
||||||
|
QuestionMarkCircledIcon,
|
||||||
QuestionMarkIcon,
|
QuestionMarkIcon,
|
||||||
ReloadIcon,
|
ReloadIcon,
|
||||||
|
SpaceBetweenHorizontallyIcon,
|
||||||
UpdateIcon,
|
UpdateIcon,
|
||||||
} from '@radix-ui/react-icons';
|
} from '@radix-ui/react-icons';
|
||||||
import Image from 'next/image';
|
import Image from "next/legacy/image";
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Button } from './ui/button';
|
import { Button } from './ui/button';
|
||||||
import { COLORS } from './create-theme';
|
import { COLORS } from './create-theme';
|
||||||
@@ -42,417 +54,263 @@ import {
|
|||||||
} from './ui/table';
|
} from './ui/table';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { ny } from '@/lib/utils';
|
import { ny } from '@/lib/utils';
|
||||||
|
import ThemeCard from './theme-card';
|
||||||
|
import { getAllThemes, ZenTheme } from '@/lib/themes';
|
||||||
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './ui/accordion';
|
||||||
|
import Logo from './logo';
|
||||||
|
import CachedImage from './CachedImage';
|
||||||
|
import { transform } from 'next/dist/build/swc';
|
||||||
|
|
||||||
function Checkmark() {
|
function Checkmark() {
|
||||||
return (
|
return (
|
||||||
<CheckIcon className="mx-auto text-black rounded-full bg-green-500 dark:bg-green-400 p-1 w-7 h-7" />
|
<CheckIcon className="text-black rounded-full bg-green-500 dark:bg-green-400 p-1 w-7 h-7 flex-none" />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Cross() {
|
function Cross() {
|
||||||
return (
|
return (
|
||||||
<XIcon className="mx-auto text-black rounded-full bg-red-500 dark:bg-red-400 p-1 w-7 h-7" />
|
<XIcon className="text-black rounded-full bg-red-500 dark:bg-red-400 p-1 w-7 h-7" />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Question() {
|
function Question() {
|
||||||
return (
|
return (
|
||||||
<QuestionMarkIcon className="mx-auto text-black rounded-full bg-yellow-500 dark:bg-yellow-400 p-1 w-7 h-7" />
|
<QuestionMarkIcon className="text-black rounded-full bg-yellow-500 dark:bg-yellow-400 p-1 w-7 h-7" />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Features() {
|
export default function Features() {
|
||||||
const [feature, setFeature] = useState(0);
|
const [feature, setFeature] = useState("item-1");
|
||||||
React.useEffect(() => {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
setFeature((feature) => (feature + 1) % 3);
|
|
||||||
}, 3000);
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
});
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-[1300px] relative my-32 mx-auto md:border-2 rounded-md md:w-full xl:w-4/5 2xl:w-3/5">
|
<section className="flex-col w-full" id="features">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 md:grid-rows-10 w-full">
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-16 shadow'>
|
||||||
<div className="items-center justify-center flex flex-col p-16">
|
<div className="p-5 lg:p-12 flex-1">
|
||||||
<div className="rounded-full px-8 py-3 shadow border-2 flex items-center justify-center">
|
<div className="flex p-12 flex-col justify-center">
|
||||||
<RabbitIcon className="mx-auto w-7 h-7" />
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Your Browser, your way <PaintBucket className='inline w-10 h-10'></PaintBucket></h3>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>With Zen's Theme Store, you can customize your browsing experience to reflect your unique style and preferences. Choose from a wide array of themes, colors, and layouts to make Zen truly your own, transforming your browser into a personalized digital space.</p>
|
||||||
|
<div className="relative">
|
||||||
|
<Button className='mt-8' onClick={() => window.open('/themes', '_self')}>View Theme Store</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-10">
|
<hr />
|
||||||
<h2 className="text-lg font-bold text-center">
|
<div className="flex p-12 flex-col justify-center">
|
||||||
Goodbye bad performance
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Always up to date <UpdateIcon className='inline w-10 h-10'></UpdateIcon></h3>
|
||||||
</h2>
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen Browser is always up to date, ensuring that you have the latest features and security updates. With automatic updates, you can rest easy knowing that your browser is secure and up to date.</p>
|
||||||
<p className="text-center text-sm mt-2 text-muted-foreground">
|
<div className="relative">
|
||||||
We are constantly tweaking Firefox's engine and settings to make it
|
<Button className='mt-8' onClick={() => window.open('/download', '_self')}>Download Now</Button>
|
||||||
faster than ever. <a className="text-blue-500" href="https://docs.zen-browser.app/benchmarks" target='_blank'>Learn more</a>
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="items-center justify-center md:border-l-2 flex flex-col p-16">
|
|
||||||
<div className="rounded-full px-8 py-3 shadow border-2 flex items-center justify-center">
|
|
||||||
<LockClosedIcon className="mx-auto w-7 h-7" />
|
|
||||||
</div>
|
|
||||||
<div className="mt-10">
|
|
||||||
<h2 className="text-lg font-bold text-center">Privacy first</h2>
|
|
||||||
<p className="text-center text-sm mt-2 text-muted-foreground">
|
|
||||||
We don't track you. We don't sell your data. We don't even know
|
|
||||||
who you are.{' '}
|
|
||||||
<a className="text-blue-500" href="/privacy-policy">
|
|
||||||
Learn more
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="items-center justify-center md:border-l-2 flex flex-col p-16">
|
|
||||||
<div className="rounded-full px-8 py-3 shadow border-2 flex items-center justify-center">
|
|
||||||
<ShieldCheck className="mx-auto w-7 h-7" />
|
|
||||||
</div>
|
|
||||||
<div className="mt-10">
|
|
||||||
<h2 className="text-lg font-bold text-center">Secure by default</h2>
|
|
||||||
<p className="text-center text-sm mt-2 text-muted-foreground">
|
|
||||||
We are always using the latest security features from Firefox to
|
|
||||||
keep you safe.{' '}
|
|
||||||
<a
|
|
||||||
className="text-blue-500"
|
|
||||||
href="https://docs.zen-browser.app/faq#how-do-i-know-zen-is-safe"
|
|
||||||
>
|
|
||||||
Learn more
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="relative md:border-t-2 hidden md:block flex-col p-16 row-span-4 scrollarea">
|
|
||||||
<Sticky
|
|
||||||
stickyClassName="mx-auto py-32"
|
|
||||||
hideOnBoundaryHit={false}
|
|
||||||
boundaryElement=".scrollarea"
|
|
||||||
topOffset={-130}
|
|
||||||
>
|
|
||||||
<h2 className="text-3xl font-bold">User experience comes first</h2>
|
|
||||||
<p className="text-sm mt-2 text-muted-foreground">
|
|
||||||
We are always looking for ways to make your experience better.
|
|
||||||
Always looking for feedback and suggestions!
|
|
||||||
</p>
|
|
||||||
</Sticky>
|
|
||||||
</div>
|
|
||||||
<div className="relative md:grid border-t-2 md:border-l-2 md:col-span-2 md:grid-cols-2 row-span-2">
|
|
||||||
<div className="p-16 md:px-32 h-full md:absolute top-0 left-0 flex flex-col">
|
|
||||||
<div className="">
|
|
||||||
<div>
|
|
||||||
<h2 className="text-3xl font-bold">Customization is key</h2>
|
|
||||||
<p className="text-sm mt-2 text-muted-foreground">
|
|
||||||
We are always looking for ways to make your experience better.
|
|
||||||
With stackable themes that can be mixed and matched, you can
|
|
||||||
create a browser that is truly yours.{' '}
|
|
||||||
<a
|
|
||||||
className="text-blue-500"
|
|
||||||
href="https://docs.zen-browser.app/themes-store/themes-marketplace"
|
|
||||||
>
|
|
||||||
Learn more
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Link href="/download">
|
|
||||||
<Button className="mt-4 rounded-full p-5 ml-auto">
|
|
||||||
Download Zen now!
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<div className="border rounded-lg shadow-md mt-16 mx-auto p-4 bg-white dark:bg-black flex w-fit transform -translate-x-1/3">
|
|
||||||
{COLORS.map((color) => (
|
|
||||||
<div
|
|
||||||
key={color}
|
|
||||||
className="w-5 h-5 rounded-full mx-3 "
|
|
||||||
style={{ backgroundColor: color }}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="border w-1/2 rounded-lg shadow-md mt-16 mx-auto p-4 bg-white dark:bg-black flex transform translate-x-[calc(50%-1.5rem)]">
|
|
||||||
<Slider defaultValue={[80]} max={100} />
|
|
||||||
</div>
|
|
||||||
<a
|
|
||||||
href="/themes"
|
|
||||||
className="border-2 w-fit md:w-1/2 lg:w-fit flex items-center justify-center rounded-xl shadow-md mt-16 mx-auto p-4 bg-white dark:bg-black border-blue-500 flex text-muted-foreground"
|
|
||||||
>
|
|
||||||
<span>Checkout our themes store</span>
|
|
||||||
<ChevronRight className="w-5 h-5 ml-2" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="relative md:grid md:border-l-2 border-t-2 md:col-span-2 grid-cols-2 row-span-2">
|
|
||||||
<div className="p-16 md:px-32 h-full md:absolute top-0 left-0 flex flex-col">
|
|
||||||
<div className="flex flex-col md:flex-row">
|
|
||||||
<div className="relative">
|
|
||||||
<h2 className="text-3xl font-bold">Compact mode is here!</h2>
|
|
||||||
<p className="text-sm mt-2 text-muted-foreground">
|
|
||||||
With a new compact mode, you can save space and focus on what
|
|
||||||
matters.
|
|
||||||
</p>
|
|
||||||
<div className="bg-blue-600 p-1 px-2 text-white rounded-md text-xs transform rotate-[10deg] absolute right-0 top-[-10px]">
|
|
||||||
Killer feature
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Link href="/download">
|
|
||||||
<Button className="mt-4 rounded-full p-5 ml-4">
|
|
||||||
Download Zen now!
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<img
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/compact-mode.png"
|
|
||||||
className="scale-105 hover:scale-110 transform rotate-[-2deg] transition-all duration-100 rounded-md w-full shadow-md dark:shadow-none dark:border-2 mt-16 border-blue-600"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col p-5 md:p-16 md:col-span-2 border-t-2 row-span-2">
|
|
||||||
<div className="rounded-full px-8 py-3 shadow border-2 flex items-center">
|
|
||||||
<div className="font-bold text-md">
|
|
||||||
What makes Zen Browser different?
|
|
||||||
</div>
|
|
||||||
<img src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/favicon.ico" className="ml-auto w-7 h-7" />
|
|
||||||
</div>
|
|
||||||
<div className="h-full w-full flex items-center justify-center">
|
|
||||||
<Table className="w-full">
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow
|
|
||||||
className="!border-none"
|
|
||||||
style={{ pointerEvents: 'none' }}
|
|
||||||
>
|
|
||||||
<TableHead className="py-2 text-2xl font-bold text-black dark:text-white">
|
|
||||||
<span className="">How Zen compares to other browsers</span>
|
|
||||||
</TableHead>
|
|
||||||
<TableHead className="py-2 font-bold text-center">
|
|
||||||
<img
|
|
||||||
height={32}
|
|
||||||
width={32}
|
|
||||||
src="/favicon.ico"
|
|
||||||
className="border-2 rounded-lg mx-auto mb-2 w-8 h-8"
|
|
||||||
alt="zen"
|
|
||||||
/>
|
|
||||||
Zen
|
|
||||||
</TableHead>
|
|
||||||
<TableHead className="py-2 pl-4 lg:pr-0 pr-2 font-bold text-center opacity-60">
|
|
||||||
<img
|
|
||||||
height={32}
|
|
||||||
width={32}
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/floorp.png"
|
|
||||||
className="bg-black dark:bg-white rounded-md p-1 mx-auto mb-2 w-7 h-7"
|
|
||||||
alt="floorp"
|
|
||||||
/>
|
|
||||||
Floorp
|
|
||||||
</TableHead>
|
|
||||||
<TableHead className="py-2 pl-0 font-bold text-center opacity-60">
|
|
||||||
<img
|
|
||||||
height={32}
|
|
||||||
width={32}
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/librewolf.png"
|
|
||||||
className="bg-black dark:bg-white rounded-md mx-auto p-1 mb-2 w-7 h-7"
|
|
||||||
alt="librewolf"
|
|
||||||
/>
|
|
||||||
LibreWolf
|
|
||||||
</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
<TableRow className="border-none">
|
|
||||||
<TableCell className="py-3 font-medium">
|
|
||||||
Fine-grained security like sandboxing
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Checkmark />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3 pl-4 pr-0">
|
|
||||||
<Cross />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Checkmark />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow className="border-none">
|
|
||||||
<TableCell className="py-3 font-medium">
|
|
||||||
Optimized for peak performance
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Checkmark />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3 pl-4 pr-0">
|
|
||||||
<Cross />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Cross />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow className="border-none">
|
|
||||||
<TableCell className="py-3 font-medium">
|
|
||||||
Based on the latest Firefox
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Checkmark />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3 pl-4 pr-0">
|
|
||||||
<Cross />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Checkmark />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow className="border-none">
|
|
||||||
<TableCell className="py-3 font-medium">
|
|
||||||
Customizable with cutting-edge features
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Checkmark />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3 pl-4 pr-0">
|
|
||||||
<Checkmark />
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="py-3">
|
|
||||||
<Cross />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="border-t-2 md:border-l-2 row-span-3 grid grid-rows-3">
|
|
||||||
<div className="flex items-center flex-col justify-center p-16">
|
|
||||||
<div className="border-2 shadow-md rounded-full p-8 py-3 flex items-center justify-center">
|
|
||||||
<Github className="w-8 h-8" />
|
|
||||||
<h2 className="text-lg font-bold ml-4">Open source</h2>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm mt-8 text-muted-foreground text-center">
|
|
||||||
Zen Browser is open source and always will be. You can check out
|
|
||||||
the source code on our{' '}
|
|
||||||
<a
|
|
||||||
className="text-blue-500"
|
|
||||||
href="https://github.com/zen-browser"
|
|
||||||
>
|
|
||||||
Github
|
|
||||||
</a>
|
|
||||||
!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center justify-center p-16 md:border-t-2">
|
|
||||||
<div className="border-2 shadow-md rounded-full p-8 py-3 flex items-center justify-center">
|
|
||||||
<ReloadIcon className="w-8 h-8" />
|
|
||||||
<h2 className="text-lg font-bold ml-4">Updated</h2>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm mt-8 text-muted-foreground text-center">
|
|
||||||
We are always working on new features and improvements. You can
|
|
||||||
expect regular updates to keep your browser up to date.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col p-16 md:border-t-2">
|
<div className="border-t lg:border-t-0 lg:border-l h-[1px] lg:h-[unset] lg:w-[1px] mx-2"></div>
|
||||||
<div className="border-2 mt-4 shadow-md rounded-full p-8 py-3 flex items-center justify-center">
|
<div className="p-5 lg:p-12 flex-1">
|
||||||
<HeartFilledIcon className="w-8 h-8" />
|
<div className="flex p-12 flex-col justify-center">
|
||||||
<h2 className="text-lg font-bold ml-4">Community</h2>
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Community driven and Open Source <Link1Icon className='inline w-10 h-10'></Link1Icon></h3>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen thrives on the contributions of its vibrant community. As an open-source project, Zen encourages collaboration and innovation, allowing users and developers alike to shape the future of the browser.</p>
|
||||||
|
<div className='relative'>
|
||||||
|
<Button className='mt-8' onClick={() => window.open('https://github.com/zen-browser', '_blank')}>GitHub Page</Button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm mt-8 text-muted-foreground text-center">
|
<div className='w-full mt-14'>
|
||||||
Zen Browser is built by a community of passionate developers and
|
<div className='flex items-center'>
|
||||||
designers. You can join us on our{' '}
|
<Checkmark />
|
||||||
<a className="text-blue-500" href="https://discord.gg/nnShMQzR4b">
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Firefox Based</p>
|
||||||
Discord
|
</div>
|
||||||
</a>
|
<div className='flex items-center mt-5'>
|
||||||
!
|
<Checkmark />
|
||||||
</p>
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Fully Open source</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className='flex items-center mt-5'>
|
||||||
<div className="flex flex-col md:border-t-2 md:col-span-2 grid grid-cols-1 md:grid-cols-2">
|
<Checkmark />
|
||||||
<div className="p-16 border-r-2 flex flex-col items-center justify-center">
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Automated Releases to ensure security</p>
|
||||||
<div className="border-2 shadow-md rounded-full p-8 py-3 flex items-center justify-center">
|
</div>
|
||||||
<EyeClosedIcon className="w-8 h-8" />
|
<div className='flex items-center mt-5'>
|
||||||
<h2 className="text-lg font-bold ml-4">Your Data</h2>
|
<Checkmark />
|
||||||
</div>
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Community driven</p>
|
||||||
<p className="text-sm mt-8 text-muted-foreground text-center">
|
</div>
|
||||||
We are always looking for ways to improve your privacy. Zen
|
<div className='flex items-center mt-5'>
|
||||||
Browser comes with built-in privacy features to keep you safe.
|
<Checkmark />
|
||||||
</p>
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Constantly improving</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-16 flex flex-col items-center justify-center">
|
|
||||||
<div className="border-2 shadow-md rounded-full p-8 py-3 flex items-center justify-center">
|
|
||||||
<UpdateIcon className="w-8 h-8" />
|
|
||||||
<h2 className="text-lg font-bold ml-4">Improvements</h2>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm mt-8 text-muted-foreground text-center">
|
|
||||||
We are always looking for ways to make Zen Browser better. You can
|
|
||||||
expect regular updates with new features and improvements.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col border-t-2 md:col-span-3 grid grid-cols-1 md:grid-cols-3 grid-rows-2 row-span-2">
|
|
||||||
<div className="relative p-16 border-r-2 flex flex-col items-center justify-center row-span-2 col-span-2">
|
|
||||||
<div className="relative w-full h-full flex items-center justify-center">
|
|
||||||
<img
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/split-view.png"
|
|
||||||
className={ny(
|
|
||||||
'absolute hover:scale-105 rounded-md w-full shadow-md dark:shadow-none dark:border-2 border-blue-500 transform transition-all duration-300',
|
|
||||||
feature === 0 ? 'translate-x-0' : '-translate-x-1/4 opacity-0'
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/workspaces.png"
|
|
||||||
className={ny(
|
|
||||||
'absolute hover:scale-105 rounded-md w-full shadow-md dark:shadow-none dark:border-2 border-blue-500 transform transition-all duration-300',
|
|
||||||
feature === 1 ? 'translate-x-0' : '-translate-x-1/4 opacity-0'
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/sidebar.png"
|
|
||||||
className={ny(
|
|
||||||
'absolute hover:scale-105 rounded-md w-full shadow-md dark:shadow-none dark:border-2 border-blue-500 transform transition-all duration-300',
|
|
||||||
feature === 2 ? 'translate-x-0' : '-translate-x-1/4 opacity-0'
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="p-16 flex flex-col items-center justify-around row-span-2">
|
|
||||||
<div
|
|
||||||
className={ny(
|
|
||||||
feature === 0 ? 'opacity-100' : 'opacity-50',
|
|
||||||
'mt-10 md:mt-0 transform transition-all duration-200 cursor-pointer'
|
|
||||||
)}
|
|
||||||
onClick={() => setFeature(0)}
|
|
||||||
>
|
|
||||||
<h2 className="text-lg font-bold ml-4 flex items-center">
|
|
||||||
<SplitSquareHorizontal className="w-4 h-4 mr-2" />
|
|
||||||
Split view
|
|
||||||
</h2>
|
|
||||||
<p className="text-sm mt-2 text-muted-foreground ml-5">
|
|
||||||
Split your browser into two windows to work more efficiently.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={ny(
|
|
||||||
feature === 1 ? 'opacity-100' : 'opacity-50',
|
|
||||||
'mt-10 md:mt-0 transform transition-all duration-200 cursor-pointer'
|
|
||||||
)}
|
|
||||||
onClick={() => setFeature(1)}
|
|
||||||
>
|
|
||||||
<h2 className="text-lg font-bold ml-4 flex items-center">
|
|
||||||
<HomeIcon className="w-4 h-4 mr-2" />
|
|
||||||
Workspaces
|
|
||||||
</h2>
|
|
||||||
<p className="text-sm mt-2 text-muted-foreground ml-5">
|
|
||||||
Organize your tabs into workspaces to keep things tidy.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={ny(
|
|
||||||
feature === 2 ? 'opacity-100' : 'opacity-50',
|
|
||||||
'mt-10 md:mt-0 transform transition-all duration-200 cursor-pointer'
|
|
||||||
)}
|
|
||||||
onClick={() => setFeature(2)}
|
|
||||||
>
|
|
||||||
<h2 className="text-lg font-bold ml-4 flex items-center">
|
|
||||||
<SidebarIcon className="w-4 h-4 mr-2" />
|
|
||||||
Sidebar
|
|
||||||
</h2>
|
|
||||||
<p className="text-sm mt-2 text-muted-foreground ml-5">
|
|
||||||
Keep your favorite websites at your fingertips with the sidebar.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
|
<div className='p-16 lg:w-1/2 flex flex-col justify-center'>
|
||||||
|
<h1 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Built for simplicity <EyeIcon className='inline w-8 h-8'></EyeIcon></h1>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen Browser is designed to be simple and easy to use. It's built with the user in mind, so you can focus on what matters most.</p>
|
||||||
|
<div className='w-full mt-8'>
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Completely Customizable</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center mt-4'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Vertical Tabs</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center mt-4'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Thoughtful Design</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CachedImage width={1350} height={900} src="www/public/browser-1.png" alt="Zen Browser" className="rounded-md lg:w-1/2 object-cover object-right" />
|
||||||
|
</div>
|
||||||
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
|
<CachedImage width={1350} height={900} src="www/public/browser-2.png" alt="Zen Browser" className="rounded-md lg:w-1/2 object-cover object-left" />
|
||||||
|
<div className='p-16 lg:w-1/2 flex flex-col justify-center'>
|
||||||
|
<h1 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Split Views <SplitSquareHorizontal className='inline w-8 h-8'></SplitSquareHorizontal></h1>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen Browser allows you to split your view into multiple panes, so you can work on multiple things at once. It's perfect for multitasking.</p>
|
||||||
|
<div className="relative">
|
||||||
|
<Button className='mt-8' onClick={() => window.open('/download', '_self')}>Download Now</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='w-full md:w-5/6 lg:w-3/4 p-5 lg:p-12 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
|
<div className="flex p-16 lg:w-1/2 flex-col justify-center">
|
||||||
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Better tab management <BookmarkCheckIcon className='inline w-8 h-8'></BookmarkCheckIcon></h3>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Better tab management helps you stay organized and focused, reducing clutter and enhancing productivity</p>
|
||||||
|
<div className='w-full mt-8'>
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Workspaces</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center mt-4'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Fast profile switcher</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center mt-4'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Container Tabs</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center mt-4'>
|
||||||
|
<Question />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Tab Groups (Coming Soon)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="border-t lg:border-t-0 lg:border-l h-[1px] lg:h-[unset] lg:w-[1px] mx-2"></div>
|
||||||
|
<div className="flex p-16 lg:w-1/2 flex-col">
|
||||||
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Security and Privacy is <span className='text-purple-500 font-bold'>important</span> to us <LockClosedIcon className='inline w-8 h-8'></LockClosedIcon></h3>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>
|
||||||
|
Zen is based on Firefox, ensuring that your browsing experience prioritizes security and privacy. With advanced tracking protection and minimal data collection, Zen keeps your online activity safe and secure, giving you peace of mind as you explore the web.
|
||||||
|
</p>
|
||||||
|
<div className="relative">
|
||||||
|
<Button className='mt-8' variant="ghost" onClick={() => window.open('https://docs.zen-browser.app/security', '_blank')}>Security in Zen <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
||||||
|
<Button className='mt-8' variant="ghost" onClick={() => window.open('/privacy-policy', '_blank')}>Your Privacy <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
|
<div className='p-16 lg:w-1/2 flex flex-col justify-center'>
|
||||||
|
<h1 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Sidebar <SidebarIcon className='inline w-8 h-8 ml-1'></SidebarIcon></h1>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen Browser has a built-in sidebar that lets you quickly access your favorite websites, bookmarks, and more. It's the perfect way to stay organized.</p>
|
||||||
|
<div className='w-full mt-8'>
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Quick Access</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center mt-4'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Customizable</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center mt-4'>
|
||||||
|
<Checkmark />
|
||||||
|
<p className='ml-2 text-gray-600 dark:text-gray-300'>Easy to Use</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CachedImage width={1350} height={900} src="www/public/browser-3.png" alt="Zen Browser" className="rounded-md lg:w-1/2 object-cover object-left" />
|
||||||
|
</div>
|
||||||
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
|
<CachedImage width={1350} height={900} src="www/public/browser-4.jpg" alt="Zen Browser" className="rounded-md lg:w-1/2 object-cover object-left" />
|
||||||
|
<div className='p-16 lg:w-1/2 flex flex-col justify-center'>
|
||||||
|
<h1 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Introducing Compact Mode <SidebarCloseIcon className='inline w-8 h-8'></SidebarCloseIcon></h1>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Zen Browser's compact mode gives you more screen real estate by hiding the title bar and tabs. It's perfect for when you need to focus on your work.</p>
|
||||||
|
<div className="relative">
|
||||||
|
<Button className='mt-8' onClick={() => window.open('/download', '_self')}>What are you waiting for?</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='w-full md:w-5/6 lg:w-3/4 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
|
<div className="relative w-full lg:w-1/2 p-5 lg:p-12 flex flex-col justify-center">
|
||||||
|
<h1 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Frequently Asked Questions <QuestionMarkCircledIcon className='inline w-8 h-8'></QuestionMarkCircledIcon></h1>
|
||||||
|
<Accordion type="single" value={feature} onValueChange={setFeature} defaultValue="item-1" className='mt-8'>
|
||||||
|
<AccordionItem value="item-1">
|
||||||
|
<AccordionTrigger>is it firefox based?</AccordionTrigger>
|
||||||
|
<AccordionContent>
|
||||||
|
Yes, Zen Browser is focused on being always at the latest version of Firefox, ensuring that you have the latest security updates and features.
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem value="item-2">
|
||||||
|
<AccordionTrigger>Does it track me?</AccordionTrigger>
|
||||||
|
<AccordionContent>
|
||||||
|
<strong>No!</strong> Zen Browser is built with privacy in mind. We don't track you, we don't collect your data, and we don't sell your data to third parties.
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
<AccordionItem value="item-3">
|
||||||
|
<AccordionTrigger>How secure is Zen Browser?</AccordionTrigger>
|
||||||
|
<AccordionContent>
|
||||||
|
Zen Browser is built on top of Firefox, which is known for its security features. We also have additional security features like https only built into Zen Browser to help keep you safe online.
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
</div>
|
||||||
|
<div className="lg:w-1/2 h-auto rounded-md relative overflow-hidden">
|
||||||
|
<CachedImage width={1350} height={900} src="www/public/feature-item-1.png" alt="Zen Browser" className="object-cover h-full w-full robject-right ounded-md" />
|
||||||
|
{feature == "item-1" && (
|
||||||
|
<div className='w-full h-full absolute top-0 left-0 grid grid-rows-3'>
|
||||||
|
<div></div>
|
||||||
|
<div className="w-fit h-fit m-auto tems-center bg-surface p-4 border-2 border-white shadow flex rounded-full animate-fade-in">
|
||||||
|
<Logo className='w-10 h-10' /> <span className='text-4xl mx-4'>+</span> <svg className='w-10 h-10 relative dark:fill-white' xmlns="http://www.w3.org/2000/svg" fill-opacity="context-fill-opacity"><path style={{ transform: "scale(2) translate(5%, 5%)" }} d="M10.39 0C8.948.788 7.987 2.025 7.767 3.66c-1.017.162-1.768.781-1.768.781s.72-.44 1.736-.511a4.04 4.04 0 0 1 3.789 2.034s-.758-.62-1.928-.468c1.315.68 1.872 2.002 1.701 3.369-.17 1.367-1.183 2.435-2.354 2.723-1.171.287-2.333.099-3.229-.61-.896-.708-1.251-1.533-1.305-2.254.213-.533.541-.812 1.1-1.092.558-.279 1.422-.283 1.572-.283s.8-.507.95-.894c-.726-.363-1.292-.65-1.696-.934-.404-.283-.492-.534-1.012-.898-.307-1.006-.021-1.955-.021-1.955s-1.043.437-1.93 1.49c0 0-.342-.338-.28-2.006-.427.155-1.366 1.004-1.947 1.92a7.277 7.277 0 0 0-.798 1.723A8.296 8.296 0 0 0-.003 8a8 8 0 0 0 16 0c0-2.256-.93-4.252-2.188-5.002 0 0 .542.932.813 2.43-.4-1.04-1.235-2.166-1.877-2.844-.643-.678-2.068-1.88-2.357-2.584z" /></svg>
|
||||||
|
</div>
|
||||||
|
<a href='https://github.com/zen-browser/desktop?tab=readme-ov-file#compatibility' target='_blank' className="w-fit h-fit m-auto items-center border-2 border-white shadow tems-center bg-surface p-4 flex rounded-full opacity-0 animate-fade-in [--animation-delay:300ms]">
|
||||||
|
See what version of Firefox Zen uses <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{feature == "item-2" && (
|
||||||
|
<div className='w-full h-full absolute top-0 left-0 grid grid-rows-3'>
|
||||||
|
<div></div>
|
||||||
|
<div className="w-fit h-fit m-auto tems-center bg-surface p-4 border-2 border-white shadow flex rounded-full animate-fade-in">
|
||||||
|
<LockClosedIcon className='w-10 h-10' /> <span className='text-4xl mx-4'>+</span> <EyeClosedIcon className='w-10 h-10' />
|
||||||
|
</div>
|
||||||
|
<a href='/privacy-policy' target='_blank' className="w-fit h-fit m-auto items-center border-2 border-white shadow tems-center bg-surface p-4 flex rounded-full opacity-0 animate-fade-in [--animation-delay:300ms]">
|
||||||
|
Learn about Zen's privacy policy <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{feature == "item-3" && (
|
||||||
|
<div className='w-full h-full absolute top-0 left-0 grid grid-rows-3'>
|
||||||
|
<div></div>
|
||||||
|
<div className="w-fit h-fit m-auto tems-center bg-surface p-4 border-2 border-white shadow flex rounded-full animate-fade-in">
|
||||||
|
<ShieldCheck className='w-10 h-10' /> <span className='text-4xl mx-4'>+</span> <ShieldAlertIcon className='w-10 h-10' />
|
||||||
|
</div>
|
||||||
|
<a href='https://docs.zen-browser.app/security' target='_blank' className="w-fit h-fit m-auto items-center w-fit border-2 border-white shadow tems-center bg-surface p-4 flex rounded-full opacity-0 animate-fade-in [--animation-delay:300ms]">
|
||||||
|
See how Zen keeps you safe <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='w-full md:w-5/6 lg:w-3/4 p-5 lg:p-12 flex flex-col lg:flex-row md:rounded-md mx-auto bg-surface mt-36 shadow'>
|
||||||
|
<div className="flex p-16 lg:w-1/2 flex-col justify-center">
|
||||||
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Convinced?</h3>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Download Zen Browser now and experience the future of browsing.</p>
|
||||||
|
<div className="relative">
|
||||||
|
<Button className='mt-8' onClick={() => window.open('/download', '_self')}>Download Now</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="border-t lg:border-t-0 lg:border-l h-[1px] lg:h-[unset] lg:w-[1px] mx-2"></div>
|
||||||
|
<div className="flex p-16 lg:w-1/2 flex-col justify-center">
|
||||||
|
<h3 className='text-4xl font-medium text-gray-800 dark:text-gray-100'>Even more convinced? <HeartHandshake className='inline text-red-500 h-10 w-10' /></h3>
|
||||||
|
<p className='text-lg mt-4 text-gray-600 dark:text-gray-300'>Help support the development of Zen Browser by donating to our cause.</p>
|
||||||
|
<div className="relative mt-8 flex">
|
||||||
|
<Button variant="ghost" onClick={() => window.open('https://patreon.com/zen_browser', '_blank')}>Patreon <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
||||||
|
<Button className="ml-8" variant="ghost" onClick={() => window.open('https://ko-fi.com/zen_browser', '_blank')}>Ko-fi <ExternalLinkIcon className='opacity-50 h-4 w-4 ml-4' /></Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,114 @@
|
|||||||
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Logo from "./logo";
|
import Logo from "./logo";
|
||||||
import TextReveal from "./ui/text-reveal";
|
import TextReveal from "./ui/text-reveal";
|
||||||
|
import { DiscordLogoIcon, GitHubLogoIcon } from "@radix-ui/react-icons";
|
||||||
|
import { MastodonLogo } from "./icons/mastodon";
|
||||||
|
import { Button } from "./ui/button";
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<div className="font-medium flex-col md:flex-row px-10 md:px-0 border-t w-full border-grey py-10 mt-10 flex justify-center align-center">
|
<div className="font-medium px-10 md:px-0 border-t w-full border-grey py-10 mt-10 flex align-center flex-col">
|
||||||
Zen Browser © {new Date().getFullYear()} - Made with ❤️ by the Zen team.
|
<div className="flex mx-auto px-10 lg:px-0 border-b pb-10 justify-between pt-10 w-full lg:!w-2/3">
|
||||||
<Link
|
<div className="flex flex-col">
|
||||||
href={"https://github.com/zen-browser"}
|
<Logo />
|
||||||
target="_blank"
|
<div className="mt-auto">
|
||||||
className="mt-5 md:mt-0 md:ml-2 font-bold"
|
<h1 className="text-2xl font-bold opacity-80">Zen Browser</h1>
|
||||||
>
|
<h2 className="text-md font-bold opacity-80 mt-6">Follow Us</h2>
|
||||||
Source Code
|
<div className="flex mt-4 opacity-70">
|
||||||
</Link>
|
<a href="https://github.com/zen-browser">
|
||||||
|
<GitHubLogoIcon className="w-5 h-5" />
|
||||||
|
</a>
|
||||||
|
<a href="https://discord.com/servers/mauro-s-little-sweatshop-1088172780480114748" className="ml-5">
|
||||||
|
<DiscordLogoIcon className="w-5 h-5" />
|
||||||
|
</a>
|
||||||
|
<a href="https://fosstodon.org/@zenbrowser" className="ml-5">
|
||||||
|
<MastodonLogo className="w-5 h-5" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col md:flex-row">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-md font-bold opacity-80">Get Started</h2>
|
||||||
|
<ul className="mt-4 opacity-70 font-normal">
|
||||||
|
<li>
|
||||||
|
<a href="/themes">
|
||||||
|
Themes
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="/download">
|
||||||
|
Download
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="/create-theme">
|
||||||
|
Create a Theme
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="mt-10 md:mt-0 md:ml-12 lg:ml-24">
|
||||||
|
<h2 className="text-md font-bold opacity-80">Get Help</h2>
|
||||||
|
<ul className="mt-4 opacity-70 font-normal">
|
||||||
|
<li>
|
||||||
|
<a href="https://discord.com/servers/mauro-s-little-sweatshop-1088172780480114748">
|
||||||
|
Discord
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2 font-normal">
|
||||||
|
<a href="https://github.com/zen-browser/desktop/issues">
|
||||||
|
Report an Issue
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h2 className="text-md font-bold opacity-80 mt-8">About</h2>
|
||||||
|
<ul className="mt-4 opacity-70 font-normal">
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="/about">
|
||||||
|
About Us
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="/privacy-policy">Privacy Policy</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className="mt-10 md:mt-0 md:ml-12 lg:ml-24">
|
||||||
|
<h2 className="text-md font-bold opacity-80">Resources</h2>
|
||||||
|
<ul className="mt-4 opacity-70 font-normal">
|
||||||
|
<li>
|
||||||
|
<a href="/branding-assets">Branding Assets</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="https://github.com/zen-browser/desktop">Source Code</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="https://docs.zen-browser.app">Documentation</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="/release-notes">Release Notes</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h2 className="text-md font-bold opacity-80 mt-8">Support Us</h2>
|
||||||
|
<ul className="mt-4 opacity-70 font-normal">
|
||||||
|
<li>
|
||||||
|
<a href="https://patreon.com/zen_browser">Patreon</a>
|
||||||
|
</li>
|
||||||
|
<li className="mt-2">
|
||||||
|
<a href="https://ko-fi.com/zen_browser">Ko-fi</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex w-full pt-10 pr-5 pl-3 mx-auto lg:!w-2/3 items-center">
|
||||||
|
<p className="text-xs font-normal opacity-30">Crafted with ❤️ by the community - Copyright © {new Date().getFullYear()} Zen Browser</p>
|
||||||
|
<a href="/download" className="ml-auto">
|
||||||
|
<Button className="ml-auto">Download</Button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import AnimatedGradientText from "./ui/animated-gradient-text";
|
|||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import { BorderBeam } from "./ui/border-beam";
|
import { BorderBeam } from "./ui/border-beam";
|
||||||
import { ny } from "@/lib/utils";
|
import { ny } from "@/lib/utils";
|
||||||
import { ChevronRight } from "lucide-react";
|
import { ChevronDown, ChevronRight } from "lucide-react";
|
||||||
import Particles from "./ui/particles";
|
import Particles from "./ui/particles";
|
||||||
import Image from "next/image";
|
import Image from "next/legacy/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
@@ -18,9 +18,9 @@ export default function Header() {
|
|||||||
<>
|
<>
|
||||||
<section
|
<section
|
||||||
id="hero"
|
id="hero"
|
||||||
className="relative mx-auto mt-40 max-w-7xl px-6 text-center md:px-8"
|
className="relative mx-auto min-h-screen flex justify-center flex-col max-w-7xl px-6 text-center md:px-8"
|
||||||
>
|
>
|
||||||
<Link href="/download">
|
<a href="/download">
|
||||||
<AnimatedGradientText>
|
<AnimatedGradientText>
|
||||||
🎉 <hr className="mx-2 h-4 w-[1px] shrink-0 bg-gray-300" />{" "}
|
🎉 <hr className="mx-2 h-4 w-[1px] shrink-0 bg-gray-300" />{" "}
|
||||||
<span
|
<span
|
||||||
@@ -32,7 +32,7 @@ export default function Header() {
|
|||||||
</span>
|
</span>
|
||||||
<ChevronRight className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
|
<ChevronRight className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
|
||||||
</AnimatedGradientText>
|
</AnimatedGradientText>
|
||||||
</Link>
|
</a>
|
||||||
<h1 className="animate-fade-in -translate-y-4 text-balance bg-gradient-to-br from-black from-30% to-black/40 bg-clip-text py-6 text-5xl font-semibold leading-none tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-6xl md:text-7xl lg:text-8xl dark:from-white dark:to-white/40">
|
<h1 className="animate-fade-in -translate-y-4 text-balance bg-gradient-to-br from-black from-30% to-black/40 bg-clip-text py-6 text-5xl font-semibold leading-none tracking-tighter text-transparent opacity-0 [--animation-delay:200ms] sm:text-6xl md:text-7xl lg:text-8xl dark:from-white dark:to-white/40">
|
||||||
Zen is the best way
|
Zen is the best way
|
||||||
<br className="hidden md:block" /> to browse the web.
|
<br className="hidden md:block" /> to browse the web.
|
||||||
@@ -42,64 +42,22 @@ export default function Header() {
|
|||||||
<br className="hidden md:block" /> We care about your experience, not
|
<br className="hidden md:block" /> We care about your experience, not
|
||||||
your data.
|
your data.
|
||||||
</p>
|
</p>
|
||||||
<Link href="/download">
|
<div className="flex flex-col md:flex-row justify-center w-full">
|
||||||
<Button
|
<a href="/download">
|
||||||
className="animate-fade-in -translate-y-4 gap-1 rounded-lg text-white opacity-0 ease-in-out [--animation-delay:600ms] dark:text-black"
|
<Button
|
||||||
>
|
className="animate-fade-in -translate-y-4 gap-1 text-white opacity-0 ease-in-out [--animation-delay:600ms] dark:text-black"
|
||||||
<span>Download Zen Now </span>
|
|
||||||
<ArrowRightIcon className="ml-1 size-4 transition-transform duration-300 ease-in-out group-hover:translate-x-1" />
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
<div
|
|
||||||
ref={ref}
|
|
||||||
className="animate-fade-up relative mt-32 opacity-0 [--animation-delay:400ms] [perspective:2000px] after:absolute after:inset-0 after:z-50 after:[background:linear-gradient(to_top,hsl(var(--background))_10%,transparent)]"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`rounded-xl border border-white/10 bg-white bg-opacity-[0.01] before:absolute before:bottom-1/2 before:left-0 before:top-0 before:size-full before:opacity-0 before:[background-image:linear-gradient(to_bottom,var(--color-one),var(--color-one),transparent_40%)] before:[filter:blur(180px)] ${
|
|
||||||
inView ? "before:animate-image-glow" : ""
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<BorderBeam
|
<span>Download Zen Now </span>
|
||||||
size={200}
|
<ArrowRightIcon className="ml-1 size-4 transition-transform duration-300 ease-in-out group-hover:translate-x-1" />
|
||||||
duration={12}
|
</Button>
|
||||||
delay={11}
|
</a>
|
||||||
colorFrom="var(--color-one)"
|
<a href="#features" className="animate-fade-up -translate-y-4 opacity-0 [--animation-delay:800ms]">
|
||||||
colorTo="var(--color-two)"
|
<Button variant="ghost" className="mt-4 md:mt-0 md:ml-4">
|
||||||
/>
|
Start Exploring <ChevronDown className="ml-1 size-4" />
|
||||||
|
</Button>
|
||||||
<img
|
</a>
|
||||||
width={1500}
|
|
||||||
height={700}
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/browser-dark.png"
|
|
||||||
alt="browser Image"
|
|
||||||
className="relative hidden rounded-[inherit] border object-contain dark:block"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
width={1500}
|
|
||||||
height={700}
|
|
||||||
src="https://cdn.jsdelivr.net/gh/zen-browser/www/public/browser-light.png"
|
|
||||||
alt="browser Image"
|
|
||||||
className="relative block rounded-[inherit] border object-contain dark:hidden"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<Particles
|
|
||||||
className="absolute inset-0 -z-10 hidden dark:block"
|
|
||||||
quantity={50}
|
|
||||||
ease={70}
|
|
||||||
size={0.05}
|
|
||||||
staticity={40}
|
|
||||||
color="#ffffff"
|
|
||||||
/>
|
|
||||||
<Particles
|
|
||||||
className="absolute inset-0 -z-10 block dark:hidden"
|
|
||||||
quantity={50}
|
|
||||||
ease={70}
|
|
||||||
size={0.05}
|
|
||||||
staticity={40}
|
|
||||||
color="#000000"
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
7
src/components/icons/mastodon.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export const MastodonLogo = (props: any) => (
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256" {...props}>
|
||||||
|
|
||||||
|
<path fill="currentColor" d="M184 32H72a40 40 0 0 0-40 40v120a40 40 0 0 0 40 40h88a8 8 0 0 0 0-16H72a24 24 0 0 1-24-24v-8h136a40 40 0 0 0 40-40V72a40 40 0 0 0-40-40m24 112a24 24 0 0 1-24 24H48V72a24 24 0 0 1 24-24h112a24 24 0 0 1 24 24Zm-24-40v32a8 8 0 0 1-16 0v-32a16 16 0 0 0-32 0v32a8 8 0 0 1-16 0v-32a16 16 0 0 0-32 0v32a8 8 0 0 1-16 0v-32a32 32 0 0 1 56-21.13A32 32 0 0 1 184 104"></path>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
@@ -1,20 +1,14 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { LOGO_COLORS } from "@/lib/logos";
|
import { LOGO_COLORS } from "@/lib/logos";
|
||||||
import { ny } from "@/lib/utils";
|
import { ny } from "@/lib/utils";
|
||||||
import Image from "next/image";
|
import Image from "next/legacy/image";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import CachedImage from "./CachedImage";
|
||||||
|
|
||||||
export default function Logo({ withText, ...props }: any) {
|
export default function Logo({ withText, ...props }: any) {
|
||||||
const [randomColor, setRandomColor] = React.useState(LOGO_COLORS[Math.floor(Math.random() * LOGO_COLORS.length)]);
|
|
||||||
React.useEffect(() => {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
setRandomColor(LOGO_COLORS[Math.floor(Math.random() * LOGO_COLORS.length)]);
|
|
||||||
}, 2000);
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}, []);
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center m-0" {...props}>
|
<div className="flex items-center m-0" {...props}>
|
||||||
<img src={`https://cdn.jsdelivr.net/gh/zen-browser/www/public/logos/zen-${randomColor}.svg`} width={40} height={40} alt="Zen Logo" className={ny("transition-all duration-300 hover:scale-110", withText && "mr-2")} />
|
<CachedImage src={`www/public/logos/zen-black.svg`} width={40} height={40} alt="Zen Logo" className={ny("transition-all duration-300 hover:scale-110", withText && "mr-2")} />
|
||||||
{withText && <span className="text-2xl font-bold ml-2">zen</span>}
|
{withText && <span className="text-2xl font-bold ml-2">zen</span>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,24 +5,19 @@ import { getAllThemes, getThemesFromSearch, ZenTheme } from "@/lib/themes";
|
|||||||
import ThemeCard from "./theme-card";
|
import ThemeCard from "./theme-card";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
|
|
||||||
export default function MarketplacePage() {
|
export default function MarketplacePage({ themes }: {themes:ZenTheme[]}) {
|
||||||
const [searchInput, setSearchInput] = React.useState("");
|
const [searchInput, setSearchInput] = React.useState("");
|
||||||
const [tags, setTags] = React.useState<string[]>(["all"]);
|
const [tags, setTags] = React.useState<string[]>(["all"]);
|
||||||
const [themes, setThemes] = React.useState<ZenTheme[]>([]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
getAllThemes().then(setThemes);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full mx-auto items-center justify-center h-full">
|
<div className="flex flex-col w-full mx-auto items-center justify-center h-full">
|
||||||
<div className="mx-auto w-full text-center border-b pt-48 pb-24 mb-12 bg-gradient-to-r from-[#f6cfbe] to-[#b9dcf2] dark:from-[#0d1117] dark:to-[#0d1117]">
|
<div className="mx-auto w-full text-center border-b pt-48 pb-24 mb-12 bg-surface">
|
||||||
<div className="w-full lg:w-1/2 xl:w-1/2 mx-auto px-2 lg:px-none">
|
<div className="w-full lg:w-1/2 xl:w-1/2 mx-auto px-2 lg:px-none">
|
||||||
<h1 className="text-4xl lg:text-7xl font-bold">Themes Store</h1>
|
<h1 className="text-4xl lg:text-7xl font-bold">Themes Store</h1>
|
||||||
<ThemesSearch input={searchInput} setInput={setSearchInput} tags={tags} setTags={setTags} />
|
<ThemesSearch input={searchInput} setInput={setSearchInput} tags={tags} setTags={setTags} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 xl:grid-cols-3 2xl:grid-cols-4 sm:grid-cols-2 gap-8 mt-10 w-5/6 md:!w-5/6 lg:w-1/2 xl:w-2/3 2xl:w-3/4">
|
<div className="px-5 lg:px-0 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 gap-8 mt-10 w-full lg:w-1/2 xl:w-2/3 2xl:w-3/4">
|
||||||
{getThemesFromSearch(themes, searchInput, tags).map((theme) => (
|
{getThemesFromSearch(themes, searchInput, tags).map((theme) => (
|
||||||
<ThemeCard key={theme.name} theme={theme} />
|
<ThemeCard key={theme.name} theme={theme} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { ny } from '@/lib/utils'
|
|||||||
import { components } from './navigation'
|
import { components } from './navigation'
|
||||||
|
|
||||||
export function MobileNav() {
|
export function MobileNav() {
|
||||||
const [open, setOpen] = React.useState(false)
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sheet open={open} onOpenChange={setOpen}>
|
<Sheet open={open} onOpenChange={setOpen}>
|
||||||
@@ -37,31 +37,41 @@ export function MobileNav() {
|
|||||||
>
|
>
|
||||||
<Logo withText />
|
<Logo withText />
|
||||||
</MobileLink>
|
</MobileLink>
|
||||||
<ScrollArea className="my-4 h-[calc(100vh-8rem)] pb-10 pl-6">
|
<ScrollArea className="mt-4 h-[calc(100vh-8rem)] pl-6">
|
||||||
<div className="flex flex-col space-y-3">
|
<div className="flex flex-col space-y-3">
|
||||||
<MobileLink
|
<MobileLink
|
||||||
href="/download"
|
href="/download"
|
||||||
onOpenChange={setOpen}
|
onOpenChange={setOpen}
|
||||||
>
|
>
|
||||||
Download
|
<div>Download</div>
|
||||||
|
<p className="opacity-60 text-xs">
|
||||||
|
Get the latest version of Zen Browser.
|
||||||
|
</p>
|
||||||
</MobileLink>
|
</MobileLink>
|
||||||
<MobileLink
|
<MobileLink
|
||||||
href="/themes"
|
href="/themes"
|
||||||
onOpenChange={setOpen}
|
onOpenChange={setOpen}
|
||||||
>
|
>
|
||||||
Theme Store
|
<div>Theme Store</div>
|
||||||
|
<p className="opacity-60 text-xs">
|
||||||
|
Customize your browsing experience.
|
||||||
|
</p>
|
||||||
</MobileLink>
|
</MobileLink>
|
||||||
<MobileLink
|
<MobileLink
|
||||||
href="/release-notes"
|
href="/release-notes"
|
||||||
onOpenChange={setOpen}
|
onOpenChange={setOpen}
|
||||||
>
|
>
|
||||||
Release Notes
|
<div>Release Notes</div>
|
||||||
|
<p className="opacity-60 text-xs">
|
||||||
|
Stay up to date with the latest changes.
|
||||||
|
</p>
|
||||||
</MobileLink>
|
</MobileLink>
|
||||||
<MobileLink
|
<MobileLink
|
||||||
href="https://patreon.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
href="https://patreon.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
||||||
onOpenChange={setOpen}
|
onOpenChange={setOpen}
|
||||||
>
|
>
|
||||||
Donate {"<"}3
|
<div>Donate {"<"}3</div>
|
||||||
|
<p className="opacity-60 text-xs">Support the project</p>
|
||||||
</MobileLink>
|
</MobileLink>
|
||||||
{components.map(({title, href, description}) => (
|
{components.map(({title, href, description}) => (
|
||||||
<MobileLink
|
<MobileLink
|
||||||
@@ -69,7 +79,8 @@ export function MobileNav() {
|
|||||||
key={href}
|
key={href}
|
||||||
onOpenChange={setOpen}
|
onOpenChange={setOpen}
|
||||||
>
|
>
|
||||||
{title}
|
<div>{title}</div>
|
||||||
|
<p className='opacity-60 text-xs'>{description}</p>
|
||||||
</MobileLink>
|
</MobileLink>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -94,16 +105,16 @@ function MobileLink({
|
|||||||
}: MobileLinkProps) {
|
}: MobileLinkProps) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
return (
|
return (
|
||||||
<Link
|
<a
|
||||||
href={href}
|
href={href.toString()}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
router.push(href.toString())
|
router.push(href.toString())
|
||||||
onOpenChange?.(false)
|
onOpenChange?.(false)
|
||||||
}}
|
}}
|
||||||
className={ny(className)}
|
className={ny(className, "my-4")}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Link>
|
</a>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
import {useEffect, useState} from "react";
|
||||||
import { MoonIcon, SunIcon } from "@radix-ui/react-icons";
|
import { MoonIcon, SunIcon, Half2Icon } from "@radix-ui/react-icons";
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -12,14 +12,36 @@ import {
|
|||||||
} from "./ui/dropdown-menu";
|
} from "./ui/dropdown-menu";
|
||||||
|
|
||||||
export function ModeToggle() {
|
export function ModeToggle() {
|
||||||
|
const [mounted, setMounted] = useState(false);
|
||||||
const { theme, setTheme } = useTheme();
|
const { theme, setTheme } = useTheme();
|
||||||
const toggleTheme = () => {
|
const toggleTheme = () => {
|
||||||
setTheme(theme === "light" ? "dark" : "light");
|
switch (theme) {
|
||||||
|
case 'system':
|
||||||
|
setTheme("dark");
|
||||||
|
break;
|
||||||
|
case 'dark':
|
||||||
|
setTheme("light");
|
||||||
|
break;
|
||||||
|
case 'light':
|
||||||
|
setTheme('system');
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!mounted) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(theme);
|
||||||
return (
|
return (
|
||||||
<Button variant="ghost" size="icon" onClick={toggleTheme}>
|
<Button variant="ghost" size="icon" onClick={toggleTheme}>
|
||||||
<SunIcon className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
|
<MoonIcon className={`${ (theme === 'system') ? 'visible' : 'hidden'} h-[1.2rem] w-[1.2rem]`} />
|
||||||
<MoonIcon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
|
<SunIcon className={`${ (theme === 'light') ? 'visible' : 'hidden'} h-[1.2rem] w-[1.2rem]`} />
|
||||||
|
<MoonIcon className={`${ (theme === 'dark') ? 'visible' : 'hidden'} h-[1.2rem] w-[1.2rem]`} />
|
||||||
<span className="sr-only">Toggle theme</span>
|
<span className="sr-only">Toggle theme</span>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
|
|
||||||
@@ -23,27 +22,32 @@ export const components: { title: string; href: string; description: string }[]
|
|||||||
{
|
{
|
||||||
title: "Privacy Policy",
|
title: "Privacy Policy",
|
||||||
href: "/privacy-policy",
|
href: "/privacy-policy",
|
||||||
description: "Learn how we handle your data. Don't worry, we don't collect anything!",
|
description: "Read our privacy policy to learn more about how we handle your data."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Discord",
|
title: "Discord",
|
||||||
href: "https://discord.gg/nnShMQzR4b",
|
href: "https://discord.com/servers/mauro-s-little-sweatshop-1088172780480114748",
|
||||||
description: "Join our Discord server to chat with the community."
|
description: "Join our Discord server to chat with the community and get support."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Source Code",
|
title: "Source Code",
|
||||||
href: "https://github.com/zen-browser",
|
href: "https://github.com/zen-browser",
|
||||||
description: "Check out our source code on GitHub and leave a star!"
|
description: "View the source code on GitHub and contribute to the project."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Branding Assets",
|
title: "Branding Assets",
|
||||||
href: "/branding-assets",
|
href: "/branding-assets",
|
||||||
description: "Download Zen Browser branding assets for your website or project."
|
description: "Download our branding assets to use in your projects."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "About",
|
||||||
|
href: "/about",
|
||||||
|
description: "Learn more about the Zen Browser project and the team behind it."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Documentation",
|
title: "Documentation",
|
||||||
href: "https://docs.zen-browser.app/",
|
href: "https://docs.zen-browser.app/",
|
||||||
description: "Learn how to use Zen Browser and build your own themes."
|
description: "Read the documentation to learn more about Zen Browser."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -59,34 +63,34 @@ export function Navigation() {
|
|||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
</NavigationMenuItem>
|
</NavigationMenuItem>
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
<NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
|
<NavigationMenuTrigger>Getting Started</NavigationMenuTrigger>
|
||||||
<NavigationMenuContent>
|
<NavigationMenuContent>
|
||||||
<ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
|
<ul className="grid gap-3 p-6 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
|
||||||
<li className="row-span-3">
|
<li className="row-span-3">
|
||||||
<NavigationMenuLink asChild>
|
<NavigationMenuLink asChild>
|
||||||
<Link
|
<a
|
||||||
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
|
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
|
||||||
href="/"
|
href="/"
|
||||||
>
|
>
|
||||||
<Logo />
|
<Logo />
|
||||||
<div className="mb-2 mt-4 text-lg font-medium">
|
<div className="mb-2 mt-4 text-lg font-medium">
|
||||||
Zen Browser
|
Zen Browser
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm leading-tight text-muted-foreground">
|
<p className="text-sm leading-tight text-muted-foreground">
|
||||||
Firefox based browser with a focus on privacy and
|
Firefox based browser with a focus on privacy and
|
||||||
customization.
|
customization.
|
||||||
</p>
|
</p>
|
||||||
</Link>
|
</a>
|
||||||
</NavigationMenuLink>
|
</NavigationMenuLink>
|
||||||
</li>
|
</li>
|
||||||
<ListItem href="/download" title="Download">
|
<ListItem href="/download" title="Download">
|
||||||
Start using Zen Browser today with just a few clicks.
|
Start using Zen Browser today with just a few clicks.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem href="/themes" title="Themes Store">
|
<ListItem href="/themes" title="Themes Store">
|
||||||
Customize your browser with a variety of themes!
|
Customize your browser with a variety of themes!
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem href="/release-notes" title="Release Notes">
|
<ListItem href="/release-notes" title="Release Notes">
|
||||||
Stay up to date with the latest changes.
|
Stay up to date with the latest changes.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</ul>
|
</ul>
|
||||||
</NavigationMenuContent>
|
</NavigationMenuContent>
|
||||||
@@ -105,7 +109,7 @@ export function Navigation() {
|
|||||||
Support us on Patreon and get exclusive rewards and keep the project alive.
|
Support us on Patreon and get exclusive rewards and keep the project alive.
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem
|
<ListItem
|
||||||
title="Ko-fi"
|
title="Ko-Fi"
|
||||||
href="https://ko-fi.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
href="https://ko-fi.com/zen_browser?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink"
|
||||||
>
|
>
|
||||||
Ko-fi is a way to support us with a one-time donation and help us keep the project alive.
|
Ko-fi is a way to support us with a one-time donation and help us keep the project alive.
|
||||||
@@ -114,7 +118,7 @@ export function Navigation() {
|
|||||||
</NavigationMenuContent>
|
</NavigationMenuContent>
|
||||||
</NavigationMenuItem>
|
</NavigationMenuItem>
|
||||||
<NavigationMenuItem>
|
<NavigationMenuItem>
|
||||||
<NavigationMenuTrigger>Useful Links</NavigationMenuTrigger>
|
<NavigationMenuTrigger>{"Useful Links"}</NavigationMenuTrigger>
|
||||||
<NavigationMenuContent>
|
<NavigationMenuContent>
|
||||||
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
|
||||||
{components.map((component) => (
|
{components.map((component) => (
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ export default function ReleaseNoteElement({ data }: { data: ReleaseNote }) {
|
|||||||
</p>
|
</p>
|
||||||
<p className="text-md mt-4 text-muted-foreground">
|
<p className="text-md mt-4 text-muted-foreground">
|
||||||
If you encounter any issues, please report them on{" "}
|
If you encounter any issues, please report them on{" "}
|
||||||
<Link
|
<a
|
||||||
href="https://github.com/zen-browser/desktop/issues/"
|
href="https://github.com/zen-browser/desktop/issues/"
|
||||||
className="text-underline text-blue-500"
|
className="text-underline text-blue-500"
|
||||||
>
|
>
|
||||||
the issues page
|
the issues page
|
||||||
</Link>
|
</a>
|
||||||
. Thanks everyone for your feedback! ❤️
|
. Thanks everyone for your feedback! ❤️
|
||||||
</p>
|
</p>
|
||||||
{data.extra && (
|
{data.extra && (
|
||||||
@@ -81,13 +81,13 @@ export default function ReleaseNoteElement({ data }: { data: ReleaseNote }) {
|
|||||||
<li key={index} className="mt-1 text-muted-foreground">
|
<li key={index} className="mt-1 text-muted-foreground">
|
||||||
{fix.description}
|
{fix.description}
|
||||||
{fix.issue && (
|
{fix.issue && (
|
||||||
<Link
|
<a
|
||||||
href={`https://github.com/zen-browser/desktop/issues/${fix.issue}`}
|
href={`https://github.com/zen-browser/desktop/issues/${fix.issue}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="ml-1 text-blue-500"
|
className="ml-1 text-blue-500"
|
||||||
>
|
>
|
||||||
issue #{fix.issue}
|
issue #{fix.issue}
|
||||||
</Link>
|
</a>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
@@ -96,9 +96,9 @@ export default function ReleaseNoteElement({ data }: { data: ReleaseNote }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap items-center justify-center">
|
<div className="flex flex-wrap items-center justify-center">
|
||||||
<Link href="/download">
|
<a href="/download">
|
||||||
<Button className="mt-12 w-fit mx-auto">Download Zen now!</Button>
|
<Button className="mt-12 w-fit mx-auto">Download Zen now!</Button>
|
||||||
</Link>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
import Image from "next/image";
|
|
||||||
import { getThemeAuthorLink, ZenTheme } from "@/lib/themes";
|
import { getThemeAuthorLink, ZenTheme } from "@/lib/themes";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "./ui/dialog";import { Button } from "./ui/button";
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "./ui/dialog";import { Button } from "./ui/button";
|
||||||
|
import { ny } from "@/lib/utils";
|
||||||
|
|
||||||
const ThemeCardWrapper = styled.div`
|
const ThemeCardWrapper = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function ThemeCard({
|
export default function ThemeCard({
|
||||||
theme
|
theme,
|
||||||
|
className
|
||||||
}: {
|
}: {
|
||||||
theme: ZenTheme;
|
theme: ZenTheme;
|
||||||
|
className?: string;
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
const maxNameLen = 50;
|
const maxNameLen = 50;
|
||||||
@@ -19,7 +22,7 @@ export default function ThemeCard({
|
|||||||
<ThemeCardWrapper onClick={(event) => {
|
<ThemeCardWrapper onClick={(event) => {
|
||||||
if (event.target instanceof HTMLAnchorElement) return;
|
if (event.target instanceof HTMLAnchorElement) return;
|
||||||
window.open(`/themes/${theme.id}`, "_self");
|
window.open(`/themes/${theme.id}`, "_self");
|
||||||
}} className="flex flex-col justify-start p-5 rounded-lg shadow-sm bg-muted dark:bg-muted/50 border border-grey-900 dark:border-muted w-full hover:shadow-lg transition duration-300 ease-in-out hover:bg-muted/100 hover:border-blue-500 cursor-pointer select-none ">
|
}} className={ny("flex flex-col justify-start p-5 rounded-lg shadow-sm bg-muted dark:bg-muted/50 border border-grey-900 dark:border-muted w-full hover:shadow-lg transition duration-300 ease-in-out hover:bg-surface hover:border-blue-500 cursor-pointer select-none ", className)}>
|
||||||
<img src={theme.image} alt={theme.name} width={500} height={500}
|
<img src={theme.image} alt={theme.name} width={500} height={500}
|
||||||
className="w-full h-32 object-cover rounded-lg border shadow" />
|
className="w-full h-32 object-cover rounded-lg border shadow" />
|
||||||
<h2 className="text-xl font-bold mt-4 overflow-ellipsis text-start">{theme.name.substring(0, maxNameLen).trim() + (theme.name.length > maxNameLen ? "..." : "")}</h2>
|
<h2 className="text-xl font-bold mt-4 overflow-ellipsis text-start">{theme.name.substring(0, maxNameLen).trim() + (theme.name.length > maxNameLen ? "..." : "")}</h2>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
|
|
||||||
import Image from "next/image";
|
|
||||||
import { getThemeAuthorLink, getThemeFromId, getThemeMarkdown, ZenTheme } from "@/lib/themes";
|
import { getThemeAuthorLink, getThemeFromId, getThemeMarkdown, ZenTheme } from "@/lib/themes";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import Markdown from "react-markdown";
|
import Markdown from "react-markdown";
|
||||||
import '../app/privacy-policy/markdown.css';
|
import '../app/privacy-policy/markdown.css';
|
||||||
import { ChevronLeft, LoaderCircleIcon } from "lucide-react";
|
import { ChevronLeft, LoaderCircleIcon } from "lucide-react";
|
||||||
@@ -18,8 +17,8 @@ export default async function ThemePage({ themeID }: { themeID: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mt-24 lg:mt-56 flex-col lg:flex-row flex mx-auto items-start relative">
|
<div className="mt-24 lg:mt-56 flex-col lg:flex-row flex mx-auto items-start relative">
|
||||||
<div className="flex flex-col relative lg:sticky lg:top-0 w-md h-full p-5 lg:p-0 lg:pr-5 mr-5 w-full md:max-w-sm">
|
<div className="mx-auto md:mx-0 flex flex-col relative bg-surface rounded-lg border shadow lg:sticky lg:top-0 w-md h-full p-5 mr-5 w-full md:max-w-sm">
|
||||||
<a className="flex mt-2 mb-9 items-center cursor-pointer opacity-70" href="/themes">
|
<a className="flex mt-2 mb-4 items-center cursor-pointer opacity-70" href="/themes">
|
||||||
<ChevronLeft className="w-4 h-4 mr-1" />
|
<ChevronLeft className="w-4 h-4 mr-1" />
|
||||||
<h3 className="text-md">Go back</h3>
|
<h3 className="text-md">Go back</h3>
|
||||||
</a>
|
</a>
|
||||||
@@ -38,19 +37,18 @@ export default async function ThemePage({ themeID }: { themeID: string }) {
|
|||||||
)}
|
)}
|
||||||
<hr className="mt-4" />
|
<hr className="mt-4" />
|
||||||
<Button
|
<Button
|
||||||
className="mt-4 hidden"
|
className="mt-4 hidden !rounded-lg"
|
||||||
id="install-theme"
|
id="install-theme"
|
||||||
zen-theme-id={theme.id}
|
zen-theme-id={theme.id}
|
||||||
>Install Theme 🎉</Button>
|
>Install Theme 🎉</Button>
|
||||||
<Button
|
<Button
|
||||||
className="mt-4 hidden"
|
className="mt-4 hidden !rounded-lg"
|
||||||
id="install-theme-uninstall"
|
id="install-theme-uninstall"
|
||||||
zen-theme-id={theme.id}
|
zen-theme-id={theme.id}
|
||||||
>Uninstall Theme</Button>
|
>Uninstall Theme</Button>
|
||||||
<p id="install-theme-error" className="text-muted-foreground text-sm mt-2">You need to have Zen Browser installed to install this theme. <a href="/download" className="text-blue-500">Download now!</a></p>
|
<p id="install-theme-error" className="text-muted-foreground text-sm mt-2">You need to have Zen Browser installed to install this theme. <a href="/download" className="text-blue-500">Download now!</a></p>
|
||||||
</div>
|
</div>
|
||||||
<hr className="block my-4 lg:hidden" />
|
<div className="flex flex-col lg:min-h-[calc(100vh/2-2rem)] px-5 lg:pl-10 max-w-xl lg:min-w-96 w-full">
|
||||||
<div className="flex flex-col lg:border-l lg:min-h-96 px-5 lg:pl-10 max-w-xl lg:min-w-96 w-full">
|
|
||||||
<div id="policy" className="w-full">
|
<div id="policy" className="w-full">
|
||||||
{readme === null ? (
|
{readme === null ? (
|
||||||
<LoaderCircleIcon className="animate-spin w-12 h-12 mx-auto" />
|
<LoaderCircleIcon className="animate-spin w-12 h-12 mx-auto" />
|
||||||
|
|||||||
57
src/components/ui/accordion.tsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import * as React from 'react'
|
||||||
|
import * as AccordionPrimitive from '@radix-ui/react-accordion'
|
||||||
|
import { ChevronDownIcon } from '@radix-ui/react-icons'
|
||||||
|
|
||||||
|
import { ny } from '@/lib/utils'
|
||||||
|
|
||||||
|
const Accordion = AccordionPrimitive.Root
|
||||||
|
|
||||||
|
const AccordionItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AccordionPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<AccordionPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={ny('border-b', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
AccordionItem.displayName = 'AccordionItem'
|
||||||
|
|
||||||
|
const AccordionTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<AccordionPrimitive.Header className="flex">
|
||||||
|
<AccordionPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={ny(
|
||||||
|
'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<ChevronDownIcon className="text-muted-foreground size-4 shrink-0 transition-transform duration-200" />
|
||||||
|
</AccordionPrimitive.Trigger>
|
||||||
|
</AccordionPrimitive.Header>
|
||||||
|
))
|
||||||
|
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
|
||||||
|
|
||||||
|
const AccordionContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof AccordionPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<AccordionPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<div className={ny('pb-4 pt-0', className)}>{children}</div>
|
||||||
|
</AccordionPrimitive.Content>
|
||||||
|
))
|
||||||
|
AccordionContent.displayName = AccordionPrimitive.Content.displayName
|
||||||
|
|
||||||
|
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
|
||||||
@@ -5,7 +5,7 @@ import { type VariantProps, cva } from "class-variance-authority";
|
|||||||
import { ny } from "@/lib/utils";
|
import { ny } from "@/lib/utils";
|
||||||
|
|
||||||
const buttonVariants = cva(
|
const buttonVariants = cva(
|
||||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
"inline-flex items-center justify-center whitespace-nowrap rounded-full text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
||||||
{
|
{
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
@@ -21,7 +21,7 @@ const buttonVariants = cva(
|
|||||||
link: "text-primary underline-offset-4 hover:underline",
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: "h-9 px-4 py-2",
|
default: "h-12 px-8 py-4",
|
||||||
sm: "h-8 rounded-md px-3 text-xs",
|
sm: "h-8 rounded-md px-3 text-xs",
|
||||||
lg: "h-10 rounded-md px-8",
|
lg: "h-10 rounded-md px-8",
|
||||||
icon: "h-9 w-9",
|
icon: "h-9 w-9",
|
||||||
|
|||||||
@@ -83,10 +83,10 @@ const NavigationMenuViewport = React.forwardRef<
|
|||||||
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
|
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
|
||||||
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
|
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => (
|
||||||
<div className={ny("absolute left-0 top-full flex justify-center")}>
|
<div className={ny("absolute left-0 right-0 top-full flex justify-center")}>
|
||||||
<NavigationMenuPrimitive.Viewport
|
<NavigationMenuPrimitive.Viewport
|
||||||
className={ny(
|
className={ny(
|
||||||
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
|
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-fit overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -628,11 +628,10 @@ export const releaseNotes: ReleaseNote[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
version: "1.0.0-a.30",
|
version: "1.0.0-a.30",
|
||||||
date: "24/08/2024",
|
date: "26/08/2024",
|
||||||
extra: "This release is the thirtieth alpha release of the 1.0.0-alpha series.",
|
extra: "This release is the thirtieth alpha release of the 1.0.0-alpha series.",
|
||||||
features: [
|
features: [
|
||||||
"Added support for 24 more languages!",
|
"Added support for 24 more languages!",
|
||||||
"Better wordmark and icons for Private Browsing mode",
|
|
||||||
"Update installed themes from the browser settings"
|
"Update installed themes from the browser settings"
|
||||||
],
|
],
|
||||||
fixes: [
|
fixes: [
|
||||||
@@ -655,9 +654,71 @@ export const releaseNotes: ReleaseNote[] = [
|
|||||||
{
|
{
|
||||||
description: "Can't rename created workspace",
|
description: "Can't rename created workspace",
|
||||||
issue: 604
|
issue: 604
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "JavaScript won't execute in the browser console",
|
||||||
|
issue: 913
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
version: "1.0.0-a.33",
|
||||||
|
date: "30/08/2024",
|
||||||
|
extra: "This release is the thirty-third alpha release of the 1.0.0-alpha series.",
|
||||||
|
features: [
|
||||||
|
"Fixed policies for updates",
|
||||||
|
"Enforce HTTPS-Only Mode",
|
||||||
|
"URL bar improvements",
|
||||||
|
"Fixed issue with opening links from external apps",
|
||||||
|
"Compact mode now takes element separation into account",
|
||||||
|
"Added labels to buttons during expand-on-hover"
|
||||||
|
],
|
||||||
|
fixes: [
|
||||||
|
{
|
||||||
|
description: "Tab bar stuck on right side",
|
||||||
|
issue: 1115
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: "1.0.0-a.35",
|
||||||
|
date: "02/09/2024",
|
||||||
|
extra: "This release is the thirty-fifth alpha release of the 1.0.0-alpha series. Things are getting stable!",
|
||||||
|
features: [
|
||||||
|
"Added option to restore legacy toolbar interface",
|
||||||
|
"Added profile-guided optimization (Windows)",
|
||||||
|
"Added Apple developer certificate (macOS)",
|
||||||
|
"Added experimental Zen Labs settings",
|
||||||
|
"Changed interface colors",
|
||||||
|
"Disabled efficiency-mode by default (Windows)",
|
||||||
|
"Enabled GPU-accelerated web rendering by default",
|
||||||
|
"Enabled Video Acceleration API for media decoding",
|
||||||
|
"Improved support for translations",
|
||||||
|
"Added Identical Code Folding compiler optimization",
|
||||||
|
],
|
||||||
|
fixes: [
|
||||||
|
{
|
||||||
|
description: "Zen Browser is damaged and can't be opened on macOS",
|
||||||
|
issue: 53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Can't reorganize tabs in compact mode",
|
||||||
|
issue: 1168
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Theme Store settings page doesn't display installed themes",
|
||||||
|
issue: 1125
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "No Homebrew support",
|
||||||
|
issue: 273
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Remember last active workspaces on startup",
|
||||||
|
issue: 240
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
].reverse();
|
].reverse();
|
||||||
|
|
||||||
export function releaseNoteIsAlpha(note: ReleaseNote) {
|
export function releaseNoteIsAlpha(note: ReleaseNote) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const config = {
|
|||||||
ring: 'hsl(var(--ring))',
|
ring: 'hsl(var(--ring))',
|
||||||
background: 'hsl(var(--background))',
|
background: 'hsl(var(--background))',
|
||||||
foreground: 'hsl(var(--foreground))',
|
foreground: 'hsl(var(--foreground))',
|
||||||
|
surface: "var(--surface)",
|
||||||
primary: {
|
primary: {
|
||||||
DEFAULT: 'hsl(var(--primary))',
|
DEFAULT: 'hsl(var(--primary))',
|
||||||
foreground: 'hsl(var(--primary-foreground))',
|
foreground: 'hsl(var(--primary-foreground))',
|
||||||
|
|||||||
4
wrangler.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
name = "zenbrowser-www"
|
||||||
|
compatibility_date = "2024-07-29"
|
||||||
|
compatibility_flags = ["nodejs_compat"]
|
||||||
|
pages_build_output_dir = "out"
|
||||||