mirror of
https://github.com/zen-browser/www.git
synced 2025-07-08 17:30:01 +02:00
Merge pull request #596 from zen-browser/refactor/app
This commit is contained in:
commit
bdf9bb81d5
38 changed files with 453 additions and 351 deletions
20
biome.json
20
biome.json
|
@ -20,16 +20,26 @@
|
||||||
"useEditorconfig": true
|
"useEditorconfig": true
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"ignore": [
|
"ignore": ["node_modules", ".git", "dist"]
|
||||||
"node_modules",
|
|
||||||
".git",
|
|
||||||
"dist"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"javascript": {
|
"javascript": {
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"quoteStyle": "single",
|
"quoteStyle": "single",
|
||||||
"semicolons": "asNeeded"
|
"semicolons": "asNeeded"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"assists": {
|
||||||
|
"actions": {
|
||||||
|
"source": {
|
||||||
|
"sortJsxProps": "on"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vcs": {
|
||||||
|
"enabled": true,
|
||||||
|
"clientKind": "git",
|
||||||
|
"defaultBranch": "main",
|
||||||
|
"root": ".",
|
||||||
|
"useIgnoreFile": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"wrangler": "wrangler",
|
"wrangler": "wrangler",
|
||||||
"astro": "astro",
|
"astro": "astro",
|
||||||
"lint": "biome lint ./src",
|
"lint": "biome lint ./src",
|
||||||
"format": "biome format ./src --write",
|
"format": "biome format ./src",
|
||||||
"prepare": "husky"
|
"prepare": "husky"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -45,8 +45,6 @@
|
||||||
"wrangler": "^3.94.0"
|
"wrangler": "^3.94.0"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"src/**/*.{ts,tsx,astro,js,jsx}": [
|
"src/**/*.{ts,tsx,astro,js,jsx}": ["biome check --write ./src"]
|
||||||
"biome check --write ./src"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +1,70 @@
|
||||||
{
|
{
|
||||||
"version": "v1.0.0",
|
"version": "v1.0.0",
|
||||||
"entity": {
|
"entity": {
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
"role": "owner",
|
"role": "owner",
|
||||||
"name": "Mauro",
|
"name": "Mauro",
|
||||||
"email": "funding@zen-browser.com",
|
"email": "funding@zen-browser.com",
|
||||||
"description": "Im the developer of Zen Browser, a web browser that is fast, secure, and easy to use. I am passionate about creating software that makes people's lives easier and more enjoyable.",
|
"description": "Im the developer of Zen Browser, a web browser that is fast, secure, and easy to use. I am passionate about creating software that makes people's lives easier and more enjoyable.",
|
||||||
"webpageUrl": {
|
"webpageUrl": {
|
||||||
"url": "https://cheff.dev",
|
"url": "https://cheff.dev",
|
||||||
"wellKnown": "https://cheff.dev/.well-known/funding-manifest-urls"
|
"wellKnown": "https://cheff.dev/.well-known/funding-manifest-urls"
|
||||||
}
|
|
||||||
},
|
|
||||||
"projects": [{
|
|
||||||
"guid": "zen-browser",
|
|
||||||
"name": "Zen",
|
|
||||||
"description": "Zen is a beautiful, fast, and productive web browser. It is designed to be packed with features that make it easy to use and navigate. Zen is built on the latest Firefox engine, providing speed, privacy, and security.",
|
|
||||||
"webpageUrl": {
|
|
||||||
"url": "https://zen-browser.app"
|
|
||||||
},
|
|
||||||
"repositoryUrl": {
|
|
||||||
"url": "https://github.com/zen-browser/desktop",
|
|
||||||
"wellKnown": "https://github.com/zen-browser/desktop/blob/dev/.well-known/funding-manifest-urls"
|
|
||||||
},
|
|
||||||
"licenses": ["MPL-2.0"],
|
|
||||||
"tags": ["browser", "web", "desktop", "open-source"]
|
|
||||||
}],
|
|
||||||
"funding": {
|
|
||||||
"channels": [
|
|
||||||
{
|
|
||||||
"guid": "patreon",
|
|
||||||
"name": "Patreon",
|
|
||||||
"description": "Patreon is a membership platform that makes it easy for artists and creators to get paid.",
|
|
||||||
"url": "https://www.patreon.com/zen_browser",
|
|
||||||
"type": "other"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"guid": "ko-fi",
|
|
||||||
"name": "Ko-fi",
|
|
||||||
"description": "Ko-fi is a platform that allows creators to receive donations from their fans.",
|
|
||||||
"url": "https://ko-fi.com/zen_browser",
|
|
||||||
"type": "other"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"plans": [
|
|
||||||
{
|
|
||||||
"guid": "licenses-and-hosting",
|
|
||||||
"status": "active",
|
|
||||||
"name": "Licenses and hosting",
|
|
||||||
"description": "Help me pay for the licenses and hosting of the project. This includes self-hosting build servers, cloudflare services, and software lienses.",
|
|
||||||
"amount": 420,
|
|
||||||
"currency": "EUR",
|
|
||||||
"frequency": "yearly",
|
|
||||||
"channels": ["patreon", "ko-fi"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"guid": "angel-plan",
|
|
||||||
"status": "active",
|
|
||||||
"name": "Goodwill plan",
|
|
||||||
"description": "Pay anything you wish to show your goodwill for the project.",
|
|
||||||
"amount": 0,
|
|
||||||
"currency": "EUR",
|
|
||||||
"frequency": "one-time",
|
|
||||||
"channels": ["patreon", "ko-fi"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"projects": [
|
||||||
|
{
|
||||||
|
"guid": "zen-browser",
|
||||||
|
"name": "Zen",
|
||||||
|
"description": "Zen is a beautiful, fast, and productive web browser. It is designed to be packed with features that make it easy to use and navigate. Zen is built on the latest Firefox engine, providing speed, privacy, and security.",
|
||||||
|
"webpageUrl": {
|
||||||
|
"url": "https://zen-browser.app"
|
||||||
|
},
|
||||||
|
"repositoryUrl": {
|
||||||
|
"url": "https://github.com/zen-browser/desktop",
|
||||||
|
"wellKnown": "https://github.com/zen-browser/desktop/blob/dev/.well-known/funding-manifest-urls"
|
||||||
|
},
|
||||||
|
"licenses": ["MPL-2.0"],
|
||||||
|
"tags": ["browser", "web", "desktop", "open-source"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"funding": {
|
||||||
|
"channels": [
|
||||||
|
{
|
||||||
|
"guid": "patreon",
|
||||||
|
"name": "Patreon",
|
||||||
|
"description": "Patreon is a membership platform that makes it easy for artists and creators to get paid.",
|
||||||
|
"url": "https://www.patreon.com/zen_browser",
|
||||||
|
"type": "other"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"guid": "ko-fi",
|
||||||
|
"name": "Ko-fi",
|
||||||
|
"description": "Ko-fi is a platform that allows creators to receive donations from their fans.",
|
||||||
|
"url": "https://ko-fi.com/zen_browser",
|
||||||
|
"type": "other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"plans": [
|
||||||
|
{
|
||||||
|
"guid": "licenses-and-hosting",
|
||||||
|
"status": "active",
|
||||||
|
"name": "Licenses and hosting",
|
||||||
|
"description": "Help me pay for the licenses and hosting of the project. This includes self-hosting build servers, cloudflare services, and software lienses.",
|
||||||
|
"amount": 420,
|
||||||
|
"currency": "EUR",
|
||||||
|
"frequency": "yearly",
|
||||||
|
"channels": ["patreon", "ko-fi"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"guid": "angel-plan",
|
||||||
|
"status": "active",
|
||||||
|
"name": "Goodwill plan",
|
||||||
|
"description": "Pay anything you wish to show your goodwill for the project.",
|
||||||
|
"amount": 0,
|
||||||
|
"currency": "EUR",
|
||||||
|
"frequency": "one-time",
|
||||||
|
"channels": ["patreon", "ko-fi"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
import { ArrowLeft } from 'lucide-astro'
|
import ArrowLeftIcon from '~/icons/ArrowLeftIcon.astro'
|
||||||
import { getLocale, getUI } from '~/utils/i18n'
|
import { getLocale, getUI } from '~/utils/i18n'
|
||||||
|
|
||||||
const locale = getLocale(Astro)
|
const locale = getLocale(Astro)
|
||||||
|
@ -15,6 +15,6 @@ const {
|
||||||
onclick="window.history.back()"
|
onclick="window.history.back()"
|
||||||
class="mb-8 flex w-min items-center gap-2"
|
class="mb-8 flex w-min items-center gap-2"
|
||||||
>
|
>
|
||||||
<ArrowLeft class="size-4" />
|
<ArrowLeftIcon class="size-4" />
|
||||||
{slug.back}
|
{slug.back}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
---
|
---
|
||||||
import Image from 'astro/components/Image.astro'
|
import Image from 'astro/components/Image.astro'
|
||||||
import { Check, Github } from 'lucide-astro'
|
|
||||||
import { motion } from 'motion/react'
|
import { motion } from 'motion/react'
|
||||||
import { getTitleAnimation } from '~/animations'
|
import { getTitleAnimation } from '~/animations'
|
||||||
import ComImage from '~/assets/ComImage.png'
|
import ComImage from '~/assets/ComImage.png'
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
|
import CheckIcon from '~/icons/CheckIcon.astro'
|
||||||
|
import GitHubIcon from '~/icons/GitHubIcon.astro'
|
||||||
import { getLocale, getUI } from '~/utils/i18n'
|
import { getLocale, getUI } from '~/utils/i18n'
|
||||||
|
|
||||||
const locale = getLocale(Astro)
|
const locale = getLocale(Astro)
|
||||||
|
@ -19,9 +20,9 @@ const {
|
||||||
|
|
||||||
<section
|
<section
|
||||||
id="Community"
|
id="Community"
|
||||||
class="relative flex w-full flex-col items-center px-4 text-start md:px-0 md:text-center lg:pt-36"
|
class="relative flex w-full flex-col items-center gap-6 py-12 text-start md:text-center lg:py-36"
|
||||||
>
|
>
|
||||||
<Description class="mb-2 px-4 text-6xl font-bold">
|
<Description class="mb-2 text-6xl font-bold">
|
||||||
<motion.span client:load {...getTitleAnimation(0.2)}>
|
<motion.span client:load {...getTitleAnimation(0.2)}>
|
||||||
{community.title[0]}
|
{community.title[0]}
|
||||||
</motion.span>
|
</motion.span>
|
||||||
|
@ -35,16 +36,14 @@ const {
|
||||||
<motion.p
|
<motion.p
|
||||||
client:load
|
client:load
|
||||||
{...getTitleAnimation(0.6)}
|
{...getTitleAnimation(0.6)}
|
||||||
className="px-4 md:px-24 lg:w-1/2 lg:px-0"
|
className="lg:w-1/2 lg:px-0"
|
||||||
>
|
>
|
||||||
{community.description}
|
{community.description}
|
||||||
</motion.p>
|
</motion.p>
|
||||||
<div
|
<div class="flex w-full flex-wrap gap-3 sm:gap-10 md:justify-center">
|
||||||
class="mt-6 flex w-full flex-wrap gap-3 px-4 sm:gap-10 sm:px-0 md:justify-center"
|
|
||||||
>
|
|
||||||
<motion.span client:load {...getTitleAnimation(0.8)}>
|
<motion.span client:load {...getTitleAnimation(0.8)}>
|
||||||
<Button class:list={['px-4']} href="https://github.com/zen-browser">
|
<Button class:list={['px-4']} href="https://github.com/zen-browser">
|
||||||
<Github class="size-4" />
|
<GitHubIcon class="size-4" />
|
||||||
<span>{community.lists.freeAndOpenSource.title}</span>
|
<span>{community.lists.freeAndOpenSource.title}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</motion.span>
|
</motion.span>
|
||||||
|
@ -53,7 +52,7 @@ const {
|
||||||
{...getTitleAnimation(1)}
|
{...getTitleAnimation(1)}
|
||||||
className="flex items-center gap-4"
|
className="flex items-center gap-4"
|
||||||
>
|
>
|
||||||
<Check class="size-4" />
|
<CheckIcon class="size-4" />
|
||||||
<span>{community.lists.simpleYetPowerful.title}</span>
|
<span>{community.lists.simpleYetPowerful.title}</span>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
@ -61,19 +60,19 @@ const {
|
||||||
{...getTitleAnimation(1.2)}
|
{...getTitleAnimation(1.2)}
|
||||||
className="flex items-center gap-4"
|
className="flex items-center gap-4"
|
||||||
>
|
>
|
||||||
<Check class="size-4" />
|
<CheckIcon class="size-4" />
|
||||||
<span>{community.lists.privateAndAlwaysUpToDate.title}</span>
|
<span>{community.lists.privateAndAlwaysUpToDate.title}</span>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
<motion.span
|
<motion.span
|
||||||
className="flex max-w-full px-8 lg:max-w-none lg:flex-none lg:px-0"
|
className="flex max-w-full lg:max-w-none lg:flex-none"
|
||||||
client:load
|
client:load
|
||||||
{...getTitleAnimation(1.4)}
|
{...getTitleAnimation(1.4)}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
src={ComImage}
|
src={ComImage}
|
||||||
alt={community.images.community.alt}
|
alt={community.images.community.alt}
|
||||||
class="my-24 rounded-3xl shadow-md lg:mx-auto lg:w-3/4 dark:opacity-80"
|
class="rounded-3xl shadow-md lg:mx-auto dark:opacity-80"
|
||||||
/>
|
/>
|
||||||
</motion.span>
|
</motion.span>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -26,7 +26,7 @@ const descriptions = Object.values(features.featureTabs).map((tab) => tab.descri
|
||||||
|
|
||||||
<section
|
<section
|
||||||
id="Features"
|
id="Features"
|
||||||
class="relative flex w-full flex-col px-4 text-start md:px-24 lg:mx-auto lg:w-3/4 lg:px-0 lg:py-36"
|
class="relative flex w-full flex-col py-12 text-start lg:py-36"
|
||||||
>
|
>
|
||||||
<Description class="mb-2 text-6xl font-bold">
|
<Description class="mb-2 text-6xl font-bold">
|
||||||
<motion.span client:load {...getTitleAnimation(0.2)}>
|
<motion.span client:load {...getTitleAnimation(0.2)}>
|
||||||
|
@ -42,9 +42,7 @@ const descriptions = Object.values(features.featureTabs).map((tab) => tab.descri
|
||||||
<motion.p client:load {...getTitleAnimation(0.6)} className="lg:w-1/2">
|
<motion.p client:load {...getTitleAnimation(0.6)} className="lg:w-1/2">
|
||||||
{features.description}
|
{features.description}
|
||||||
</motion.p>
|
</motion.p>
|
||||||
<div
|
<div class="mt-6 flex flex-col gap-6 lg:flex-row lg:justify-between lg:gap-2">
|
||||||
class="mb-12 mt-6 flex flex-col gap-6 lg:flex-row lg:justify-between lg:gap-2"
|
|
||||||
>
|
|
||||||
<div class="flex w-full flex-col lg:w-1/3">
|
<div class="flex w-full flex-col lg:w-1/3">
|
||||||
<!-- Mobile tabs -->
|
<!-- Mobile tabs -->
|
||||||
<div class="flex gap-2 overflow-x-auto overflow-y-clip lg:hidden">
|
<div class="flex gap-2 overflow-x-auto overflow-y-clip lg:hidden">
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
import { ArrowRight } from 'lucide-astro'
|
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
import Circles from '~/components/Circles.astro'
|
import Circles from '~/components/Circles.astro'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
import SocialMediaStrip from '~/components/SocialMediaStrip.astro'
|
import SocialMediaStrip from '~/components/SocialMediaStrip.astro'
|
||||||
|
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||||
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
||||||
|
|
||||||
const locale = getLocale(Astro)
|
const locale = getLocale(Astro)
|
||||||
|
@ -15,11 +15,13 @@ const {
|
||||||
|
|
||||||
<footer
|
<footer
|
||||||
id="footer"
|
id="footer"
|
||||||
class="relative flex w-full flex-col gap-16 overflow-hidden border-t border-dark bg-dark px-4 py-12 text-paper lg:p-24"
|
class="relative flex w-full flex-col items-center gap-16 overflow-hidden border-t border-dark bg-dark px-4 py-12 text-paper lg:p-24"
|
||||||
role="contentinfo"
|
role="contentinfo"
|
||||||
aria-label="Site footer"
|
aria-label="Site footer"
|
||||||
>
|
>
|
||||||
<div class="flex w-full flex-col items-start justify-between gap-12">
|
<div
|
||||||
|
class="container flex w-full flex-col items-start justify-between gap-12"
|
||||||
|
>
|
||||||
<section
|
<section
|
||||||
class="w-full text-center lg:w-1/2 lg:text-left"
|
class="w-full text-center lg:w-1/2 lg:text-left"
|
||||||
aria-labelledby="footer-title"
|
aria-labelledby="footer-title"
|
||||||
|
@ -39,7 +41,7 @@ const {
|
||||||
aria-label={footer.download}
|
aria-label={footer.download}
|
||||||
>
|
>
|
||||||
{footer.download}
|
{footer.download}
|
||||||
<ArrowRight class="size-4" aria-hidden="true" />
|
<ArrowRightIcon class="size-4" aria-hidden="true" />
|
||||||
</Button>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
<section
|
<section
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
---
|
---
|
||||||
import { ArrowRight } from 'lucide-astro'
|
|
||||||
import { motion } from 'motion/react'
|
import { motion } from 'motion/react'
|
||||||
import { getTitleAnimation } from '~/animations'
|
import { getTitleAnimation } from '~/animations'
|
||||||
import HomePageVideo from '~/assets/HomePageVideo.webm'
|
import HomePageVideo from '~/assets/HomePageVideo.webm'
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
import Title from '~/components/Title.astro'
|
import Title from '~/components/Title.astro'
|
||||||
|
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||||
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
||||||
import SocialMediaStrip from './SocialMediaStrip.astro'
|
import SocialMediaStrip from './SocialMediaStrip.astro'
|
||||||
import Video from './Video.astro'
|
import Video from './Video.astro'
|
||||||
|
@ -37,7 +37,7 @@ const {
|
||||||
>
|
>
|
||||||
<div class="flex h-full flex-col items-center justify-center">
|
<div class="flex h-full flex-col items-center justify-center">
|
||||||
<Title
|
<Title
|
||||||
class="relative px-12 text-center !font-normal !leading-8 leading-[108px] md:!text-7xl lg:px-0 lg:!text-9xl"
|
class="relative px-12 text-center !font-normal leading-8 md:text-7xl lg:px-0 lg:text-9xl"
|
||||||
>
|
>
|
||||||
<motion.span client:load {...getHeroTitleAnimation()}>
|
<motion.span client:load {...getHeroTitleAnimation()}>
|
||||||
{hero.title[0]}
|
{hero.title[0]}
|
||||||
|
@ -71,7 +71,7 @@ const {
|
||||||
<motion.span client:load {...getHeroTitleAnimation()}>
|
<motion.span client:load {...getHeroTitleAnimation()}>
|
||||||
<Button class="w-full" href={getLocalePath('/download')} isPrimary>
|
<Button class="w-full" href={getLocalePath('/download')} isPrimary>
|
||||||
{hero.buttons.beta}
|
{hero.buttons.beta}
|
||||||
<ArrowRight class="size-4" />
|
<ArrowRightIcon class="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</motion.span>
|
</motion.span>
|
||||||
<motion.span client:load {...getHeroTitleAnimation()}>
|
<motion.span client:load {...getHeroTitleAnimation()}>
|
||||||
|
@ -88,7 +88,7 @@ const {
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<motion.span
|
<motion.span
|
||||||
className="flex max-w-full px-8 lg:max-w-none lg:flex-none lg:px-0"
|
className="flex max-w-full lg:max-w-none lg:flex-none"
|
||||||
client:load
|
client:load
|
||||||
{...getHeroTitleAnimation()}
|
{...getHeroTitleAnimation()}
|
||||||
>
|
>
|
||||||
|
@ -99,6 +99,6 @@ const {
|
||||||
muted
|
muted
|
||||||
playsinline
|
playsinline
|
||||||
preload="none"
|
preload="none"
|
||||||
class="mb-24 rounded-3xl shadow-md lg:mx-auto lg:w-3/4 dark:opacity-80"
|
class="mb-24 rounded-3xl shadow-md dark:opacity-80"
|
||||||
/>
|
/>
|
||||||
</motion.span>
|
</motion.span>
|
||||||
|
|
|
@ -89,36 +89,36 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto mb-12 flex items-center justify-center gap-4 px-8">
|
<div className="mx-auto mb-12 flex items-center justify-center gap-4 px-8">
|
||||||
<button
|
<button
|
||||||
type="button"
|
|
||||||
onClick={() => navigatePage(page - 1)}
|
|
||||||
className={`px-3 py-2 ${page === 1 ? 'pointer-events-none text-gray-400' : 'text-dark hover:text-gray-600'}`}
|
className={`px-3 py-2 ${page === 1 ? 'pointer-events-none text-gray-400' : 'text-dark hover:text-gray-600'}`}
|
||||||
|
onClick={() => navigatePage(page - 1)}
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
<
|
<
|
||||||
</button>
|
</button>
|
||||||
<form onSubmit={handlePageSubmit} className="flex items-center gap-2">
|
<form className="flex items-center gap-2" onSubmit={handlePageSubmit}>
|
||||||
{mods.pagination.pagination.split('{input}').map((value, index) => {
|
{mods.pagination.pagination.split('{input}').map((value, index) => {
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
|
aria-label="Page number"
|
||||||
|
className="w-16 rounded border border-dark bg-transparent px-2 py-1 text-center text-sm"
|
||||||
|
onInput={handlePageInputChange}
|
||||||
type="text"
|
type="text"
|
||||||
value={pageInput}
|
value={pageInput}
|
||||||
onInput={handlePageInputChange}
|
|
||||||
className="w-16 rounded border border-dark bg-transparent px-2 py-1 text-center text-sm"
|
|
||||||
aria-label="Page number"
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<span key={value} className="text-sm">
|
<span className="text-sm" key={value}>
|
||||||
{value.replace('{totalPages}', totalPages.toString()).replace('{totalItems}', totalItems.toString())}
|
{value.replace('{totalPages}', totalPages.toString()).replace('{totalItems}', totalItems.toString())}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</form>
|
</form>
|
||||||
<button
|
<button
|
||||||
type="button"
|
|
||||||
onClick={() => navigatePage(page + 1)}
|
|
||||||
className={`px-3 py-2 ${page === totalPages ? 'pointer-events-none text-gray-400' : 'text-dark hover:text-gray-600'}`}
|
className={`px-3 py-2 ${page === totalPages ? 'pointer-events-none text-gray-400' : 'text-dark hover:text-gray-600'}`}
|
||||||
|
onClick={() => navigatePage(page + 1)}
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
|
@ -128,24 +128,24 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="mx-auto flex flex-col items-start gap-4 px-8 lg:w-1/2">
|
<div className="flex flex-col items-center gap-4">
|
||||||
<div className="flex w-full flex-col items-center gap-6">
|
<div className="flex w-full flex-col items-center justify-center gap-6">
|
||||||
<input
|
<input
|
||||||
type="text"
|
|
||||||
id="search"
|
|
||||||
className="w-full rounded-full border-2 border-dark bg-transparent px-6 py-2 text-lg outline-none"
|
className="w-full rounded-full border-2 border-dark bg-transparent px-6 py-2 text-lg outline-none"
|
||||||
placeholder={mods.search}
|
id="search"
|
||||||
value={search}
|
|
||||||
onInput={handleSearch}
|
onInput={handleSearch}
|
||||||
|
placeholder={mods.search}
|
||||||
|
type="text"
|
||||||
|
value={search}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid w-full grid-cols-2 place-items-center gap-4 sm:grid-cols-3">
|
<div className="grid w-full grid-cols-2 place-items-center gap-4 sm:grid-cols-3">
|
||||||
<div className="flex flex-col items-start gap-2">
|
<div className="flex flex-col items-start gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
|
||||||
onClick={toggleCreatedSort}
|
|
||||||
className="flex items-center gap-2 px-4 py-2 font-semibold text-md"
|
className="flex items-center gap-2 px-4 py-2 font-semibold text-md"
|
||||||
|
onClick={toggleCreatedSort}
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
{mods.sort.lastCreated}
|
{mods.sort.lastCreated}
|
||||||
<span
|
<span
|
||||||
|
@ -159,9 +159,9 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
||||||
|
|
||||||
<div className="flex flex-col items-center gap-2">
|
<div className="flex flex-col items-center gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
|
||||||
onClick={toggleUpdatedSort}
|
|
||||||
className="flex items-center gap-2 px-4 py-2 font-semibold text-md"
|
className="flex items-center gap-2 px-4 py-2 font-semibold text-md"
|
||||||
|
onClick={toggleUpdatedSort}
|
||||||
|
type="button"
|
||||||
>
|
>
|
||||||
{mods.sort.lastUpdated}
|
{mods.sort.lastUpdated}
|
||||||
<span
|
<span
|
||||||
|
@ -174,14 +174,14 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 px-4 py-2">
|
<div className="flex items-center gap-2 px-4 py-2">
|
||||||
<label htmlFor="limit" className="font-semibold text-md">
|
<label className="font-semibold text-md" htmlFor="limit">
|
||||||
{mods.sort.perPage}
|
{mods.sort.perPage}
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="limit"
|
|
||||||
value={limit}
|
|
||||||
onInput={handleLimitChange}
|
|
||||||
className="rounded border border-dark bg-transparent px-2 py-1 text-sm [&>option]:text-black"
|
className="rounded border border-dark bg-transparent px-2 py-1 text-sm [&>option]:text-black"
|
||||||
|
id="limit"
|
||||||
|
onInput={handleLimitChange}
|
||||||
|
value={limit}
|
||||||
>
|
>
|
||||||
<option value="12">12</option>
|
<option value="12">12</option>
|
||||||
<option value="24">24</option>
|
<option value="24">24</option>
|
||||||
|
@ -192,20 +192,20 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx-auto grid grid-cols-1 place-items-start gap-12 p-10 md:grid-cols-2 lg:grid-cols-3 lg:p-24 lg:px-24 2xl:grid-cols-4">
|
<div className="grid w-full grid-cols-1 place-items-start gap-12 py-6 md:grid-cols-2 xl:grid-cols-3">
|
||||||
{paginatedMods.length > 0 ? (
|
{paginatedMods.length > 0 ? (
|
||||||
paginatedMods.map((mod) => (
|
paginatedMods.map((mod) => (
|
||||||
<a
|
<a
|
||||||
key={mod.id}
|
className="flex w-full flex-col gap-4 border-transparent transition-colors duration-100 hover:opacity-90"
|
||||||
href={`/mods/${mod.id}`}
|
href={`/mods/${mod.id}`}
|
||||||
className="flex flex-col gap-4 border-transparent transition-colors duration-100 hover:opacity-90"
|
key={mod.id}
|
||||||
>
|
>
|
||||||
<div className="relative mb-0 block aspect-[1.85/1] h-48 overflow-hidden rounded-md border-2 border-dark object-cover shadow-md">
|
<div className="relative mb-0 block aspect-[1.85/1] h-48 overflow-hidden rounded-md border-2 border-dark object-cover shadow-md">
|
||||||
<img
|
<img
|
||||||
src={mod.image}
|
|
||||||
alt={mod.name}
|
alt={mod.name}
|
||||||
loading="lazy"
|
|
||||||
className="h-full w-full object-cover transition-transform duration-100 hover:scale-105"
|
className="h-full w-full object-cover transition-transform duration-100 hover:scale-105"
|
||||||
|
loading="lazy"
|
||||||
|
src={mod.image}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
---
|
---
|
||||||
import { Astronav, Dropdown, DropdownItems, MenuItems } from 'astro-navbar'
|
import { Astronav, Dropdown, DropdownItems, MenuItems } from 'astro-navbar'
|
||||||
import { ArrowRight, ChevronDown, Download, Menu } from 'lucide-astro'
|
|
||||||
import { motion } from 'motion/react'
|
import { motion } from 'motion/react'
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
|
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||||
|
import ChevronDownIcon from '~/icons/ChevronDownIcon.astro'
|
||||||
|
import DownloadIcon from '~/icons/DownloadIcon.astro'
|
||||||
|
import MenuIcon from '~/icons/MenuIcon.astro'
|
||||||
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
||||||
import { getTitleAnimation } from '../animations.ts'
|
import { getTitleAnimation } from '../animations.ts'
|
||||||
import Logo from './Logo.astro'
|
import Logo from './Logo.astro'
|
||||||
|
@ -21,7 +24,7 @@ const {
|
||||||
<!-- Desktop Navigation -->
|
<!-- Desktop Navigation -->
|
||||||
<Astronav>
|
<Astronav>
|
||||||
<MenuItems
|
<MenuItems
|
||||||
class="relative z-20 mx-auto grid w-full grid-cols-2 items-center gap-2 bg-paper px-4 py-3 lg:grid lg:min-w-fit lg:grid-cols-[auto_1fr_auto] lg:p-6 xl:w-3/4"
|
class="container relative z-20 grid w-full grid-cols-2 items-center gap-2 bg-paper py-3 lg:grid lg:grid-cols-[auto_1fr_auto] lg:py-6"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
class="flex items-center gap-2 text-lg font-bold"
|
class="flex items-center gap-2 text-lg font-bold"
|
||||||
|
@ -36,7 +39,7 @@ const {
|
||||||
<Dropdown class="group">
|
<Dropdown class="group">
|
||||||
<button class="flex items-center">
|
<button class="flex items-center">
|
||||||
<span>{menu.gettingStarted}</span>
|
<span>{menu.gettingStarted}</span>
|
||||||
<ChevronDown
|
<ChevronDownIcon
|
||||||
class="size-4 transform transition-transform duration-200 group-open:rotate-180 md:ml-2"
|
class="size-4 transform transition-transform duration-200 group-open:rotate-180 md:ml-2"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -56,7 +59,7 @@ const {
|
||||||
</div>
|
</div>
|
||||||
<Button isPrimary class="mt-auto">
|
<Button isPrimary class="mt-auto">
|
||||||
{menu.tryZenMods}
|
{menu.tryZenMods}
|
||||||
<ArrowRight class="size-4" />
|
<ArrowRightIcon class="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</a>
|
</a>
|
||||||
<a class="dropdown-item" href={getLocalePath('/release-notes')}>
|
<a class="dropdown-item" href={getLocalePath('/release-notes')}>
|
||||||
|
@ -77,7 +80,7 @@ const {
|
||||||
<Dropdown class="group">
|
<Dropdown class="group">
|
||||||
<button class="flex items-center">
|
<button class="flex items-center">
|
||||||
<span>{menu.usefulLinks}</span>
|
<span>{menu.usefulLinks}</span>
|
||||||
<ChevronDown
|
<ChevronDownIcon
|
||||||
class="size-4 transform transition-transform duration-200 group-open:rotate-180 md:ml-2"
|
class="size-4 transform transition-transform duration-200 group-open:rotate-180 md:ml-2"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -129,10 +132,10 @@ const {
|
||||||
<Button href="/download" class="hidden lg:flex" isPrimary>
|
<Button href="/download" class="hidden lg:flex" isPrimary>
|
||||||
<span class="hidden items-center gap-2 lg:flex">
|
<span class="hidden items-center gap-2 lg:flex">
|
||||||
{menu.download}
|
{menu.download}
|
||||||
<ArrowRight class="size-4" />
|
<ArrowRightIcon class="size-4" />
|
||||||
</span>
|
</span>
|
||||||
<span class="flex items-center gap-2 lg:hidden">
|
<span class="flex items-center gap-2 lg:hidden">
|
||||||
<Download class="size-4" />
|
<DownloadIcon class="size-4" />
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
<label
|
<label
|
||||||
|
@ -140,7 +143,7 @@ const {
|
||||||
class="cursor-pointer p-2 text-dark lg:hidden"
|
class="cursor-pointer p-2 text-dark lg:hidden"
|
||||||
aria-label="Open menu"
|
aria-label="Open menu"
|
||||||
>
|
>
|
||||||
<Menu class="h-6 w-6" />
|
<MenuIcon class="h-6 w-6" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</MenuItems>
|
</MenuItems>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
import { Accordion, AccordionItem } from 'free-astro-components'
|
import { Accordion, AccordionItem } from 'free-astro-components'
|
||||||
import { Info } from 'lucide-astro'
|
import InfoIcon from '~/icons/InfoIcon.astro'
|
||||||
|
|
||||||
import { releaseNotes as releaseNotesData } from '~/release-notes'
|
import { releaseNotes as releaseNotesData } from '~/release-notes'
|
||||||
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
||||||
|
@ -112,7 +112,7 @@ if (prevReleaseNote && !isTwilight) {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-muted-forground mt-6 flex text-sm opacity-70">
|
<div class="text-muted-forground mt-6 flex text-sm opacity-70">
|
||||||
{isTwilight ? <Info class="mx-4 my-0 size-6 text-yellow-500" /> : null}
|
{isTwilight ? <InfoIcon class="mx-4 my-0 size-6 text-yellow-500" /> : null}
|
||||||
<p class="m-0">
|
<p class="m-0">
|
||||||
{isTwilight ? <>{releaseNoteItem.twilightWarning}</> : null}
|
{isTwilight ? <>{releaseNoteItem.twilightWarning}</> : null}
|
||||||
<span set:html={releaseNoteItem.reportIssues} />
|
<span set:html={releaseNoteItem.reportIssues} />
|
||||||
|
|
|
@ -18,12 +18,10 @@ const {
|
||||||
} = getUI(locale)
|
} = getUI(locale)
|
||||||
---
|
---
|
||||||
|
|
||||||
<section id="sponsors" class:list={['mb-32 px-4', !showSponsors && 'hidden']}>
|
<section id="sponsors" class:list={['py-12', !showSponsors && 'hidden']}>
|
||||||
<div class="mx-auto flex flex-col px-6 text-center">
|
<div class="mx-auto flex flex-col text-center">
|
||||||
<motion.span client:load {...getTitleAnimation(0.2)}>
|
<motion.span client:load {...getTitleAnimation(0.2)}>
|
||||||
<Description class="mb-2 px-4 text-6xl font-bold"
|
<Description class="mb-2 text-6xl font-bold">Our Sponsors</Description>
|
||||||
>Our Sponsors</Description
|
|
||||||
>
|
|
||||||
</motion.span>
|
</motion.span>
|
||||||
<motion.span client:load {...getTitleAnimation(0.4)}>
|
<motion.span client:load {...getTitleAnimation(0.4)}>
|
||||||
<Description set:html={sponsors.description} />
|
<Description set:html={sponsors.description} />
|
||||||
|
|
|
@ -2,18 +2,6 @@
|
||||||
const { class: className } = Astro.props
|
const { class: className } = Astro.props
|
||||||
---
|
---
|
||||||
|
|
||||||
<h1 class:list={['title text-dark', className]}>
|
<h1 class:list={['text-dark leading-[0.9] mb-[0.4rem] font-junicode font-semibold text-5xl xl:text-6xl', className]}>
|
||||||
<slot />
|
<slot />
|
||||||
</h1>
|
</h1>
|
||||||
<style>
|
|
||||||
.title {
|
|
||||||
line-height: 0.9;
|
|
||||||
margin-bottom: 0.4rem;
|
|
||||||
font-family: 'Junicode', serif;
|
|
||||||
font-weight: 600;
|
|
||||||
font-style: normal;
|
|
||||||
font-feature-settings: 'swsh' 1;
|
|
||||||
|
|
||||||
@apply text-5xl xl:text-6xl;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -85,12 +85,22 @@ import DownloadCard from './ButtonCard.astro'
|
||||||
checksum={releases.universal.checksum}
|
checksum={releases.universal.checksum}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{releases.x86_64 && 'tarball' in releases.x86_64 && releases.x86_64.tarball && releases.x86_64.tarball.label && (
|
{releases.x86_64 && (
|
||||||
<DownloadCard
|
'tarball' in releases.x86_64
|
||||||
label={releases.x86_64.tarball.label}
|
? releases.x86_64.tarball.label && (
|
||||||
href={releases.x86_64.tarball.link}
|
<DownloadCard
|
||||||
checksum={releases.x86_64.tarball.checksum}
|
label={releases.x86_64.tarball.label}
|
||||||
/>
|
href={releases.x86_64.tarball.link}
|
||||||
|
checksum={releases.x86_64.tarball.checksum}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
: releases.x86_64.label && (
|
||||||
|
<DownloadCard
|
||||||
|
label={releases.x86_64.label}
|
||||||
|
href={releases.x86_64.link}
|
||||||
|
checksum={releases.x86_64.checksum}
|
||||||
|
/>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
{releases.arm64 && releases.arm64.label && (
|
{releases.arm64 && releases.arm64.label && (
|
||||||
<DownloadCard
|
<DownloadCard
|
||||||
|
|
|
@ -144,86 +144,107 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "About - Zen Browser",
|
"title": "About Zen",
|
||||||
"description": "We are simply a group of developers and designers who care about your experience on the web. We believe that the internet should be a place where you can explore, learn, and connect without worrying about your data being collected.",
|
"description": "We are simply a group of developers and designers who care about your experience on the web. We believe that the internet should be a place where you can explore, learn, and connect without worrying about your data being collected.",
|
||||||
"littleHelp": "A little help?",
|
"littleHelp": "A little help?",
|
||||||
"mainTeam": {
|
"mainTeam": {
|
||||||
"title": "Main Team",
|
"title": "Main Team",
|
||||||
"description": "This list shows the main team members who are working hard to bring you the best browsing experience.",
|
"description": "This list shows the main team members who are working hard to bring you the best browsing experience.",
|
||||||
|
"subTitle": {
|
||||||
|
"browser": "Browser",
|
||||||
|
"website": "Website and Branding"
|
||||||
|
},
|
||||||
"members": {
|
"members": {
|
||||||
"mauro": {
|
"browser": {
|
||||||
"name": "Mauro B.",
|
"mauro": {
|
||||||
"description": "Creator, Main Developer",
|
"name": "Mauro B.",
|
||||||
"link": "https://cheff.dev/"
|
"description": "Creator, Main Developer",
|
||||||
|
"link": "https://cheff.dev/"
|
||||||
|
},
|
||||||
|
"jan": {
|
||||||
|
"name": "Jan Heres",
|
||||||
|
"description": "Active contributor and helps with MacOS builds",
|
||||||
|
"link": "https://janheres.eu/"
|
||||||
|
},
|
||||||
|
"bryan": {
|
||||||
|
"name": "Bryan Galdámez",
|
||||||
|
"description": "Huge contributor on theme functionalities",
|
||||||
|
"link": "https://josuegalre.netlify.app/"
|
||||||
|
},
|
||||||
|
"oscar": {
|
||||||
|
"name": "Oscar Gonzalez",
|
||||||
|
"description": "Site Reliability Engineer (SRE) and code signing.",
|
||||||
|
"link": false
|
||||||
|
},
|
||||||
|
"daniel": {
|
||||||
|
"name": "Daniel García",
|
||||||
|
"description": "MacOS certificate and app notarization maintainer",
|
||||||
|
"link": false
|
||||||
|
},
|
||||||
|
"brhm": {
|
||||||
|
"name": "BrhmDev",
|
||||||
|
"description": "Active contributor with great contributions",
|
||||||
|
"link": "https://github.com/BrhmDev"
|
||||||
|
},
|
||||||
|
"kristijanribaric": {
|
||||||
|
"name": "Kristijan Ribaric",
|
||||||
|
"description": "Active contributor",
|
||||||
|
"link": "https://github.com/kristijanribaric"
|
||||||
|
},
|
||||||
|
"larvey": {
|
||||||
|
"name": "Larvey",
|
||||||
|
"description": "AUR maintainer",
|
||||||
|
"link": "https://github.com/LarveyOfficial/"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"oscar": {
|
"website": {
|
||||||
"name": "Oscar Gonzalez",
|
"taroj1205": {
|
||||||
"description": "Site Reliability Engineer (SRE) and code signing.",
|
"name": "Shintaro Jokagi",
|
||||||
"link": false
|
"description": "Core Website Architect, Spearheading Refactoring and Technical Enhancements",
|
||||||
},
|
"link": "https://github.com/taroj1205"
|
||||||
"jan": {
|
},
|
||||||
"name": "Jan Heres",
|
"jace": {
|
||||||
"description": "Active contributor and helps with MacOS builds",
|
"name": "Jace",
|
||||||
"link": "https://janheres.eu/"
|
"description": "Contributes to website design and branding",
|
||||||
},
|
"link": "https://x.com/JaceThings"
|
||||||
"brhm": {
|
},
|
||||||
"name": "BrhmDev",
|
"canoa": {
|
||||||
"description": "Active contributor with great contributions",
|
"name": "Canoa",
|
||||||
"link": "https://github.com/BrhmDev"
|
"description": "Active contributor, and very active in issue handling and website management",
|
||||||
},
|
"link": "https://thatcanoa.org/"
|
||||||
"canoa": {
|
},
|
||||||
"name": "Canoa",
|
"adam": {
|
||||||
"description": "Active contributor, and very active in issue handling and website management",
|
"name": "Adam",
|
||||||
"link": "https://thatcanoa.org/"
|
"description": "Branding and design",
|
||||||
},
|
"link": "https://cybrneon.xyz/"
|
||||||
"adam": {
|
},
|
||||||
"name": "Adam",
|
"n7itro": {
|
||||||
"description": "Branding and design",
|
"name": "n7itro",
|
||||||
"link": "https://cybrneon.xyz/"
|
"description": "Active contributor and release notes writer",
|
||||||
},
|
"link": "https://github.com/n7itro"
|
||||||
"kristijanribaric": {
|
},
|
||||||
"name": "Kristijan Ribaric",
|
"jafeth": {
|
||||||
"description": "Active contributor",
|
"name": "Jafeth Garro",
|
||||||
"link": "https://github.com/kristijanribaric"
|
"description": "Documentation writer",
|
||||||
},
|
"link": "https://iamjafeth.com/"
|
||||||
"n7itro": {
|
}
|
||||||
"name": "n7itro",
|
|
||||||
"description": "Active contributor and release notes writer",
|
|
||||||
"link": "https://github.com/n7itro"
|
|
||||||
},
|
|
||||||
"bryan": {
|
|
||||||
"name": "Bryan Galdámez",
|
|
||||||
"description": "Huge contributor on theme functionalities",
|
|
||||||
"link": "https://josuegalre.netlify.app/"
|
|
||||||
},
|
|
||||||
"jafeth": {
|
|
||||||
"name": "Jafeth Garro",
|
|
||||||
"description": "Documentation writer",
|
|
||||||
"link": "https://iamjafeth.com/"
|
|
||||||
},
|
|
||||||
"larvey": {
|
|
||||||
"name": "Larvey",
|
|
||||||
"description": "AUR maintainer",
|
|
||||||
"link": "https://github.com/LarveyOfficial/"
|
|
||||||
},
|
|
||||||
"daniel": {
|
|
||||||
"name": "Daniel García",
|
|
||||||
"description": "MacOS certificate and app notarization maintainer",
|
|
||||||
"link": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"contributors": {
|
"contributors": {
|
||||||
"title": "Contributors",
|
"title": "Contributors",
|
||||||
"description": "This list shows the contributors who have helped us to make Zen Browser the best it can be."
|
"description": "This list shows the contributors who have helped us to make Zen Browser the best it can be.",
|
||||||
|
"browser": "Browser",
|
||||||
|
"website": "Website"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"donate": {
|
"donate": {
|
||||||
"title": "Donate - Zen Browser",
|
"title": "Donate",
|
||||||
"description": "We are a small team of developers working hard to bring you the best browsing experience. If you like what we do, please consider supporting us.",
|
"description": "We are a small team of developers working hard to bring you the best browsing experience. If you like what we do, please consider supporting us.",
|
||||||
"patreon": {
|
"patreon": {
|
||||||
"title": "Patreon",
|
"title": "Patreon",
|
||||||
"description": "Patreon allows you to support us with a monthly donation. You can choose the level of support that works best for you."
|
"description": "Patreon allows you to support us with a monthly donation. You can choose the level of support that works best for you.",
|
||||||
|
"button": "Go to Patreon"
|
||||||
},
|
},
|
||||||
"koFi": {
|
"koFi": {
|
||||||
"title": "Ko-fi",
|
"title": "Ko-fi",
|
||||||
|
@ -395,7 +416,7 @@
|
||||||
"description": "Stay up to date with the latest changes to Zen Browser! Since the first release till {latestVersion}, we've been working hard to make Zen Browser the best it can be. Thanks everyone for your feedback! ❤️"
|
"description": "Stay up to date with the latest changes to Zen Browser! Since the first release till {latestVersion}, we've been working hard to make Zen Browser the best it can be. Thanks everyone for your feedback! ❤️"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "About - Zen",
|
"title": "About Zen",
|
||||||
"description": "We are simply a group of developers and designers who care about your experience on the web. We believe that the internet should be a place where you can explore, learn, and connect without worrying about your data being collected."
|
"description": "We are simply a group of developers and designers who care about your experience on the web. We believe that the internet should be a place where you can explore, learn, and connect without worrying about your data being collected."
|
||||||
},
|
},
|
||||||
"donate": {
|
"donate": {
|
||||||
|
|
5
src/icons/ArrowLeftIcon.astro
Normal file
5
src/icons/ArrowLeftIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-arrow-left-icon lucide-arrow-left", className]} {...props}><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg>
|
5
src/icons/ArrowRightIcon.astro
Normal file
5
src/icons/ArrowRightIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-arrow-right-icon lucide-arrow-right", className]} {...props}><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
5
src/icons/ArrowUp.astro
Normal file
5
src/icons/ArrowUp.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-arrow-up-icon lucide-arrow-up", className]} {...props}><path d="m5 12 7-7 7 7"/><path d="M12 19V5"/></svg>
|
5
src/icons/CheckIcon.astro
Normal file
5
src/icons/CheckIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-check-icon lucide-check", className]} {...props}><path d="M20 6 9 17l-5-5"/></svg>
|
5
src/icons/ChevronDownIcon.astro
Normal file
5
src/icons/ChevronDownIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-chevron-down-icon lucide-chevron-down", className]} {...props}><path d="m6 9 6 6 6-6"/></svg>
|
5
src/icons/DownloadIcon.astro
Normal file
5
src/icons/DownloadIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-download-icon lucide-download", className]} {...props}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>
|
5
src/icons/ExternalLink.astro
Normal file
5
src/icons/ExternalLink.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-external-link-icon lucide-external-link", className]} {...props}><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
|
5
src/icons/GitHubIcon.astro
Normal file
5
src/icons/GitHubIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-github-icon lucide-github", className]} {...props}><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></svg>
|
5
src/icons/InfoIcon.astro
Normal file
5
src/icons/InfoIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-info-icon lucide-info", className]} {...props}><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
|
5
src/icons/LockIcon.astro
Normal file
5
src/icons/LockIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-lock-icon lucide-lock", className]} {...props}><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
5
src/icons/MenuIcon.astro
Normal file
5
src/icons/MenuIcon.astro
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
const { class: className, ...props } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class:list={["lucide lucide-menu-icon lucide-menu", className]} {...props}><path d="M4 12h16"/><path d="M4 18h16"/><path d="M4 6h16"/></svg>
|
|
@ -89,7 +89,7 @@ const locale = getLocale(Astro)
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
console.log(
|
console.log(
|
||||||
'%c✌️ Zen-Browser%c\nWelcome to a calmer internet!%c',
|
'%c✌️ Zen-Browser%c\nWelcome to a calmer internet!',
|
||||||
'filter: invert(1); font-size: 28px; font-weight: bolder; font-family: "Rubik"; margin-top: 20px; margin-bottom: 8px;',
|
'filter: invert(1); font-size: 28px; font-weight: bolder; font-family: "Rubik"; margin-top: 20px; margin-bottom: 8px;',
|
||||||
'color: #f76f53; font-size: 16px; font-family: "Rubik"; margin-bottom: 20px;'
|
'color: #f76f53; font-size: 16px; font-family: "Rubik"; margin-bottom: 20px;'
|
||||||
);
|
);
|
||||||
|
@ -97,7 +97,7 @@ const locale = getLocale(Astro)
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
class="overflow-x-hidden bg-paper font-['bricolage-grotesque'] text-dark"
|
class="overflow-x-hidden bg-paper font-['bricolage-grotesque'] text-dark text-balance"
|
||||||
>
|
>
|
||||||
<NavBar />
|
<NavBar />
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -15,17 +15,19 @@ const {
|
||||||
|
|
||||||
<Layout title={notFound.title}>
|
<Layout title={notFound.title}>
|
||||||
<main
|
<main
|
||||||
class="flex min-h-[70vh] flex-col items-center justify-center py-24 text-center"
|
class="container flex min-h-[70vh] flex-col items-center justify-center gap-6 py-24 text-center"
|
||||||
>
|
>
|
||||||
<Title class="mb-4 text-7xl font-bold text-coral md:text-9xl">404</Title>
|
<Title class="text-7xl font-bold text-coral md:text-9xl">404</Title>
|
||||||
<Description class="mb-6 text-xl md:text-2xl">
|
<div class="flex flex-col items-center gap-6">
|
||||||
{notFound.title}
|
<Description class="text-xl md:text-2xl">
|
||||||
</Description>
|
{notFound.title}
|
||||||
<p class="mb-8 max-w-xl text-lg text-gray-500 dark:text-gray-400">
|
</Description>
|
||||||
{notFound.description}
|
<p class="max-w-xl text-lg text-gray-500 dark:text-gray-400">
|
||||||
</p>
|
{notFound.description}
|
||||||
<Button href={getLocalePath('/')} isPrimary>
|
</p>
|
||||||
{notFound.button}
|
<Button href={getLocalePath('/')} isPrimary class="w-fit">
|
||||||
</Button>
|
{notFound.button}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
---
|
---
|
||||||
import Button from '~/components/Button.astro'
|
import { Image } from 'astro:assets'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
import Layout from '~/layouts/Layout.astro'
|
import Layout from '~/layouts/Layout.astro'
|
||||||
import { getLocale, getUI } from '~/utils/i18n'
|
import { getLocale, getUI } from '~/utils/i18n'
|
||||||
export { getStaticPaths } from '~/utils/i18n'
|
export { getStaticPaths } from '~/utils/i18n'
|
||||||
|
import Button from '~/components/Button.astro'
|
||||||
|
|
||||||
const locale = getLocale(Astro)
|
const locale = getLocale(Astro)
|
||||||
|
|
||||||
|
@ -18,65 +19,67 @@ const {
|
||||||
description={layout.about.description}
|
description={layout.about.description}
|
||||||
>
|
>
|
||||||
<main
|
<main
|
||||||
class="relative flex min-h-screen flex-col items-center justify-center py-24"
|
class="flex min-h-screen flex-col py-24 container w-full gap-24"
|
||||||
>
|
>
|
||||||
<div class="mb-24 p-4 text-center lg:w-1/2">
|
<div class="w-full flex flex-col gap-6">
|
||||||
<Description class="text-6xl font-bold">{about.title}</Description>
|
<Description class="text-6xl font-bold leading-none">{about.title}</Description>
|
||||||
<Description>
|
<Description class="max-w-4xl">
|
||||||
{about.description}
|
{about.description}
|
||||||
</Description>
|
</Description>
|
||||||
<Button href="/donate" class="mx-auto mt-4 w-fit" isPrimary
|
<Button href="/donate" class="w-fit" isPrimary
|
||||||
>{about.littleHelp}</Button
|
>{about.littleHelp}</Button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="flex flex-col gap-4 w-full">
|
||||||
class="relative flex w-full flex-col items-center justify-center lg:flex-row"
|
<div class="text-4xl lg:text-5xl font-bold leading-none">{about.mainTeam.title}</div>
|
||||||
>
|
|
||||||
<div class="flex flex-col p-8 lg:w-1/3 lg:pr-24">
|
|
||||||
<div class="text-4xl font-bold lg:text-6xl">{about.mainTeam.title}</div>
|
|
||||||
<Description>
|
<Description>
|
||||||
{about.mainTeam.description}
|
{about.mainTeam.description}
|
||||||
</Description>
|
</Description>
|
||||||
<div class="mt-4">
|
<div class="flex flex-col gap-6">
|
||||||
<ul>
|
{Object.entries(about.mainTeam.members).map(([team, members]) => (
|
||||||
{Object.entries(about.mainTeam.members).map(([_key, member]) => (
|
<div class="flex flex-col gap-2">
|
||||||
<li class="text-sm">
|
<div class="text-3xl font-semibold">{about.mainTeam.subTitle[team as keyof typeof about.mainTeam.subTitle]}</div>
|
||||||
{member.link ? (
|
<ul class="flex flex-col gap-2">
|
||||||
<a href={member.link === true ? '' : member.link}>
|
{Object.entries(members).map(([_key, member]) => (
|
||||||
<strong class="zen-link font-bold">{member.name}</strong>
|
<li class="text-sm">
|
||||||
</a>
|
{member.link && typeof member.link === 'string' ? (
|
||||||
<span class="opacity-60"> : {member.description}</span>
|
<a href={member.link}>
|
||||||
) : (
|
<strong class="zen-link font-bold">{member.name}</strong>
|
||||||
<strong class="font-bold">{member.name}</strong>
|
</a>
|
||||||
<span class="opacity-60"> : {member.description}</span>
|
) : (
|
||||||
)}
|
<strong class="font-bold">{member.name}</strong>
|
||||||
</li>
|
)}
|
||||||
))}
|
<span class="opacity-80">: {member.description}</span>
|
||||||
</ul>
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute hidden h-full w-[1px] bg-dark opacity-15 lg:block">
|
<div class="flex flex-col gap-4 w-full">
|
||||||
</div>
|
<div class="text-4xl lg:text-5xl font-bold leading-none">{about.contributors.title}</div>
|
||||||
<div class="flex flex-col p-8 lg:w-1/3 lg:pl-24">
|
|
||||||
<div class="text-4xl font-bold lg:text-6xl">{about.contributors.title}</div>
|
|
||||||
<Description>
|
<Description>
|
||||||
{about.contributors.description}
|
{about.contributors.description}
|
||||||
</Description>
|
</Description>
|
||||||
<a href="https://github.com/zen-browser/desktop/graphs/contributors"
|
<div class="flex flex-col gap-4 w-fit"><Description class="text-3xl font-semibold lg:text-4xl">{about.contributors.browser}</Description>
|
||||||
><img
|
<a href="https://github.com/zen-browser/desktop/graphs/contributors"
|
||||||
|
><Image
|
||||||
src="https://contributors-img.web.app/image?repo=zen-browser/desktop"
|
src="https://contributors-img.web.app/image?repo=zen-browser/desktop"
|
||||||
alt="Contributors"
|
alt="Contributors"
|
||||||
class="mt-8"
|
width={500}
|
||||||
|
height={500}
|
||||||
/></a
|
/></a
|
||||||
>
|
></div>
|
||||||
|
<div class="flex flex-col gap-4 w-fit"><Description class="text-3xl font-semibold lg:text-4xl">{about.contributors.website}</Description>
|
||||||
<a href="https://github.com/zen-browser/www/graphs/contributors"
|
<a href="https://github.com/zen-browser/www/graphs/contributors"
|
||||||
><img
|
><Image
|
||||||
src="https://contributors-img.web.app/image?repo=zen-browser/www"
|
src="https://contributors-img.web.app/image?repo=zen-browser/www"
|
||||||
alt="Contributors (website)"
|
alt="Contributors (website)"
|
||||||
class="mt-8"
|
width={500}
|
||||||
|
height={500}
|
||||||
/></a
|
/></a
|
||||||
>
|
></div></div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
import { ArrowRight } from 'lucide-astro'
|
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
|
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||||
import Layout from '~/layouts/Layout.astro'
|
import Layout from '~/layouts/Layout.astro'
|
||||||
import { getLocale, getUI } from '~/utils/i18n'
|
import { getLocale, getUI } from '~/utils/i18n'
|
||||||
export { getStaticPaths } from '~/utils/i18n'
|
export { getStaticPaths } from '~/utils/i18n'
|
||||||
|
@ -14,51 +14,41 @@ const {
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={layout.donate.title} description={layout.donate.description}>
|
<Layout title={layout.donate.title} description={layout.donate.description}>
|
||||||
<main class="pb-52 pt-36">
|
<main class="container pb-52 pt-24 flex flex-col items-center gap-12">
|
||||||
<div
|
<div class="flex flex-col gap-4 lg:text-center">
|
||||||
class="relative flex w-full flex-col items-center justify-center gap-12"
|
|
||||||
>
|
|
||||||
<div class="px-8 lg:w-2/5 lg:text-center xl:px-0">
|
|
||||||
<Description class="text-6xl font-bold">{donate.title}</Description>
|
<Description class="text-6xl font-bold">{donate.title}</Description>
|
||||||
<Description>
|
<Description class="max-w-3xl">
|
||||||
{donate.description}
|
{donate.description}
|
||||||
</Description>
|
</Description>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex w-full flex-col items-center justify-center lg:flex-row">
|
<div
|
||||||
<div class="flex flex-col p-8 lg:w-1/3 lg:pr-24">
|
class="grid max-w-5xl grid-cols-1 gap-12 text-center lg:grid-cols-[1fr_1px_1fr]"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col items-center gap-4">
|
||||||
<div class="text-6xl font-bold">{donate.patreon.title}</div>
|
<div class="text-6xl font-bold">{donate.patreon.title}</div>
|
||||||
<Description>
|
<Description>
|
||||||
{donate.patreon.description}
|
{donate.patreon.description}
|
||||||
</Description>
|
</Description>
|
||||||
<div class="mt-6">
|
<Button
|
||||||
<Button
|
isPrimary
|
||||||
isPrimary
|
href="https://www.patreon.com/zen_browser"
|
||||||
href="https://www.patreon.com/zen_browser"
|
class="w-fit"
|
||||||
class="w-fit"
|
>
|
||||||
>
|
{donate.patreon.button}
|
||||||
Go to Patreon
|
<ArrowRightIcon class="size-4" />
|
||||||
<ArrowRight class="size-4" />
|
</Button>
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden h-72 w-[1px] bg-dark opacity-15 lg:block"></div>
|
<hr class="hidden h-72 w-[1px] bg-dark opacity-15 lg:block" />
|
||||||
<div class="flex flex-col p-8 lg:w-1/3 lg:pl-24">
|
<div class="flex flex-col items-center gap-4">
|
||||||
<div class="text-6xl font-bold">{donate.koFi.title}</div>
|
<div class="text-6xl font-bold">{donate.koFi.title}</div>
|
||||||
<Description>
|
<Description>
|
||||||
{donate.koFi.description}
|
{donate.koFi.description}
|
||||||
</Description>
|
</Description>
|
||||||
<div class="mt-6">
|
<Button href="https://ko-fi.com/zen_browser" isPrimary class="w-fit">
|
||||||
<Button
|
{donate.koFi.button}
|
||||||
href="https://ko-fi.com/zen_browser"
|
<ArrowRightIcon class="size-4" />
|
||||||
isPrimary
|
</Button>
|
||||||
class="w-fit"
|
|
||||||
>
|
|
||||||
{donate.koFi.button}
|
|
||||||
<ArrowRight class="size-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -9,7 +9,8 @@ import { getLocale, getUI } from '~/utils/i18n'
|
||||||
|
|
||||||
import { icon, library } from '@fortawesome/fontawesome-svg-core'
|
import { icon, library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import { faApple, faGithub, faLinux, faWindows } from '@fortawesome/free-brands-svg-icons'
|
import { faApple, faGithub, faLinux, faWindows } from '@fortawesome/free-brands-svg-icons'
|
||||||
import { ExternalLink, Lock } from 'lucide-astro'
|
import ExternalLinkIcon from '~/icons/ExternalLink.astro'
|
||||||
|
import LockIcon from '~/icons/LockIcon.astro'
|
||||||
|
|
||||||
export { getStaticPaths } from '~/utils/i18n'
|
export { getStaticPaths } from '~/utils/i18n'
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ const platformDescriptions = download.platformDescriptions
|
||||||
|
|
||||||
<Layout title={layout.download.title} description={layout.download.description}>
|
<Layout title={layout.download.title} description={layout.download.description}>
|
||||||
<main class="flex min-h-screen flex-col px-6 data-[os='windows']:bg-zen-blue">
|
<main class="flex min-h-screen flex-col px-6 data-[os='windows']:bg-zen-blue">
|
||||||
<div class="container relative mx-auto max-w-5xl py-12">
|
<div class="container relative mx-auto py-12">
|
||||||
<div class="mb-6 mt-12 flex flex-col gap-4">
|
<div class="mb-6 mt-12 flex flex-col gap-4">
|
||||||
<Description id="download-title" class="text-6xl font-bold"
|
<Description id="download-title" class="text-6xl font-bold"
|
||||||
>{download.title}</Description
|
>{download.title}</Description
|
||||||
|
@ -180,7 +181,7 @@ const platformDescriptions = download.platformDescriptions
|
||||||
<div
|
<div
|
||||||
class="rounded-xl border border-subtle p-3 transition-all duration-100 hover:bg-coral hover:bg-opacity-10 group-hover:border-coral group-hover:border-opacity-20"
|
class="rounded-xl border border-subtle p-3 transition-all duration-100 hover:bg-coral hover:bg-opacity-10 group-hover:border-coral group-hover:border-opacity-20"
|
||||||
>
|
>
|
||||||
<ExternalLink
|
<ExternalLinkIcon
|
||||||
class="h-5 w-5 transition-all duration-200 group-hover:text-coral"
|
class="h-5 w-5 transition-all duration-200 group-hover:text-coral"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -194,7 +195,7 @@ const platformDescriptions = download.platformDescriptions
|
||||||
class="bg-opaicty-10 grid grid-cols-[auto,1fr] gap-4 rounded-2xl bg-subtle p-6"
|
class="bg-opaicty-10 grid grid-cols-[auto,1fr] gap-4 rounded-2xl bg-subtle p-6"
|
||||||
>
|
>
|
||||||
<div class="h-fit rounded-xl bg-subtle p-3">
|
<div class="h-fit rounded-xl bg-subtle p-3">
|
||||||
<Lock class="h-5 w-5" />
|
<LockIcon class="h-5 w-5" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -17,7 +17,7 @@ const { layout } = getUI(locale)
|
||||||
description={layout.index.description}
|
description={layout.index.description}
|
||||||
isHome
|
isHome
|
||||||
>
|
>
|
||||||
<main>
|
<main class="container">
|
||||||
<Hero />
|
<Hero />
|
||||||
<Features />
|
<Features />
|
||||||
<Sponsors showSponsors />
|
<Sponsors showSponsors />
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
---
|
---
|
||||||
import { ArrowRight, Info } from 'lucide-astro'
|
|
||||||
import BackButton from '~/components/BackButton.astro'
|
import BackButton from '~/components/BackButton.astro'
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
|
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||||
|
import InfoIcon from '~/icons/InfoIcon.astro'
|
||||||
import Layout from '~/layouts/Layout.astro'
|
import Layout from '~/layouts/Layout.astro'
|
||||||
import { getAllMods, getAuthorLink, getLocalizedDate } from '~/mods'
|
import { getAllMods, getAuthorLink, getLocalizedDate } from '~/mods'
|
||||||
import { getUI } from '~/utils/i18n'
|
import { getUI } from '~/utils/i18n'
|
||||||
|
@ -64,7 +65,7 @@ const {
|
||||||
class="flex flex-col items-center justify-center gap-2 rounded-xl bg-red-200 p-2 px-4 md:flex-row md:justify-between dark:bg-red-700"
|
class="flex flex-col items-center justify-center gap-2 rounded-xl bg-red-200 p-2 px-4 md:flex-row md:justify-between dark:bg-red-700"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-2 text-center md:text-left">
|
<div class="flex items-center gap-2 text-center md:text-left">
|
||||||
<Info />
|
<InfoIcon />
|
||||||
<p class="text-sm">
|
<p class="text-sm">
|
||||||
{slug.alert.description}
|
{slug.alert.description}
|
||||||
</p>
|
</p>
|
||||||
|
@ -75,7 +76,7 @@ const {
|
||||||
isAlert
|
isAlert
|
||||||
>
|
>
|
||||||
{slug.alert.button}
|
{slug.alert.button}
|
||||||
<ArrowRight class="size-4" />
|
<ArrowRightIcon class="size-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<BackButton />
|
<BackButton />
|
||||||
|
|
|
@ -18,16 +18,12 @@ const allMods = (await getAllMods()) || []
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={layout.mods.title}>
|
<Layout title={layout.mods.title}>
|
||||||
<main class="mx-auto mt-32 max-w-[120rem] 2xl:mt-0">
|
<main class="container mt-32 flex flex-col gap-10 2xl:mt-32">
|
||||||
<header class="mb-10 mt-32 flex w-full flex-col justify-center border-dark">
|
<header class="flex w-full flex-col gap-8 border-dark">
|
||||||
<div class="mx-auto flex flex-col gap-6 px-8 lg:w-1/2">
|
<Description class="text-6xl font-bold">{mods.title}</Description>
|
||||||
<div>
|
<Description class="max-w-3xl">
|
||||||
<Description class="text-6xl font-bold">{mods.title}</Description>
|
{mods.description}
|
||||||
<Description>
|
</Description>
|
||||||
{mods.description}
|
|
||||||
</Description>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Importing ModList component -->
|
<!-- Importing ModList component -->
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
import { Modal, ModalBody, ModalHeader } from 'free-astro-components'
|
import { Modal, ModalBody, ModalHeader } from 'free-astro-components'
|
||||||
import { ArrowUp } from 'lucide-astro'
|
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
import ReleaseNoteItem from '~/components/ReleaseNoteItem.astro'
|
import ReleaseNoteItem from '~/components/ReleaseNoteItem.astro'
|
||||||
|
import ArrowUpIcon from '~/icons/ArrowUp.astro'
|
||||||
import Layout from '~/layouts/Layout.astro'
|
import Layout from '~/layouts/Layout.astro'
|
||||||
import { releaseNotes as releaseNotesData, releaseNotesTwilight } from '~/release-notes'
|
import { releaseNotes as releaseNotesData, releaseNotesTwilight } from '~/release-notes'
|
||||||
import { getLocale, getUI } from '~/utils/i18n'
|
import { getLocale, getUI } from '~/utils/i18n'
|
||||||
|
@ -19,11 +19,11 @@ const {
|
||||||
|
|
||||||
<Layout title={layout.releaseNotes.title}>
|
<Layout title={layout.releaseNotes.title}>
|
||||||
<main
|
<main
|
||||||
class="flex h-full min-h-[1000px] flex-1 flex-col items-center justify-center py-4"
|
class="container flex h-full min-h-[1000px] flex-1 flex-col items-center justify-center py-4"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="release-notes"
|
id="release-notes"
|
||||||
class="py-42 flex min-h-screen flex-col justify-center px-10 lg:px-10 xl:px-10 2xl:w-3/5"
|
class="py-42 flex min-h-screen w-full flex-col justify-center"
|
||||||
>
|
>
|
||||||
<Description class="mt-48 text-4xl font-bold">Release Notes</Description>
|
<Description class="mt-48 text-4xl font-bold">Release Notes</Description>
|
||||||
<p
|
<p
|
||||||
|
@ -58,9 +58,9 @@ const {
|
||||||
<Button href="#" id="scroll-top" isPrimary class="fixed bottom-8 right-8">
|
<Button href="#" id="scroll-top" isPrimary class="fixed bottom-8 right-8">
|
||||||
<p class="hidden items-center gap-2 sm:flex">
|
<p class="hidden items-center gap-2 sm:flex">
|
||||||
{releaseNotes.backToTop}
|
{releaseNotes.backToTop}
|
||||||
<ArrowUp aria-hidden="true" class="size-4" />
|
<ArrowUpIcon aria-hidden="true" class="size-4" />
|
||||||
</p>
|
</p>
|
||||||
<ArrowUp aria-label="Back to the top" class="size-4 sm:hidden" />
|
<ArrowUpIcon aria-label="Back to the top" class="size-4 sm:hidden" />
|
||||||
</Button>
|
</Button>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Modal id="version-modal" class="m-auto border border-[--zen-dark] !bg-paper">
|
<Modal id="version-modal" class="m-auto border border-[--zen-dark] !bg-paper">
|
||||||
|
|
|
@ -13,9 +13,7 @@ const {
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={layout.welcome.title} description={layout.welcome.description}>
|
<Layout title={layout.welcome.title} description={layout.welcome.description}>
|
||||||
<main
|
<main class="container">
|
||||||
class="relative mx-auto flex flex-col items-center gap-24 px-6 lg:gap-0 lg:px-24"
|
|
||||||
>
|
|
||||||
<Features
|
<Features
|
||||||
title1={welcome.title[0]}
|
title1={welcome.title[0]}
|
||||||
title2={welcome.title[1]}
|
title2={welcome.title[1]}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
---
|
---
|
||||||
import { ArrowRight } from 'lucide-astro'
|
|
||||||
import Button from '~/components/Button.astro'
|
import Button from '~/components/Button.astro'
|
||||||
import Description from '~/components/Description.astro'
|
import Description from '~/components/Description.astro'
|
||||||
import SocialMediaStrip from '~/components/SocialMediaStrip.astro'
|
import SocialMediaStrip from '~/components/SocialMediaStrip.astro'
|
||||||
|
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||||
import Layout from '~/layouts/Layout.astro'
|
import Layout from '~/layouts/Layout.astro'
|
||||||
|
|
||||||
import whatsNewVideo from '~/assets/whats-new.mp4'
|
import whatsNewVideo from '~/assets/whats-new.mp4'
|
||||||
|
@ -34,7 +34,7 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<main
|
<main
|
||||||
class="relative mx-auto flex flex-col items-center gap-24 px-6 pb-52 pt-36 lg:px-24 xl:flex-row"
|
class="xl:mt-22 container flex flex-col gap-12 py-12 xl:grid xl:min-h-[calc(100vh-12rem)] xl:grid-cols-[2fr_3fr]"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col gap-8">
|
<div class="flex flex-col gap-8">
|
||||||
<div>
|
<div>
|
||||||
|
@ -51,37 +51,38 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
|
||||||
<div>
|
<div>
|
||||||
<Fragment set:html={whatsNewText[0].replace(/\n/g, '<br>')} />
|
<Fragment set:html={whatsNewText[0].replace(/\n/g, '<br>')} />
|
||||||
</div>
|
</div>
|
||||||
<ul class="hidden flex-col gap-2 md:flex">
|
<ul class="hidden list-disc flex-col gap-2 xl:container xl:flex">
|
||||||
<a
|
<a
|
||||||
href="https://github.com/zen-browser/desktop/issues/new/choose"
|
href="https://github.com/zen-browser/desktop/issues/new/choose"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<li class="ml-3 list-disc">
|
<li>
|
||||||
<Description class="text-base font-bold"
|
<Description class="text-base font-bold">
|
||||||
>{whatsNew.reportIssue}</Description
|
{whatsNew.reportIssue}
|
||||||
>
|
</Description>
|
||||||
</li>
|
</li>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/zen-browser" target="_blank">
|
<a href="https://discord.gg/zen-browser" target="_blank">
|
||||||
<li class="ml-3 list-disc">
|
<li>
|
||||||
<Description class="text-base font-bold"
|
<Description class="text-base font-bold">
|
||||||
>{whatsNew.joinDiscord}</Description
|
{whatsNew.joinDiscord}
|
||||||
>
|
</Description>
|
||||||
</li>
|
</li>
|
||||||
</a>
|
</a>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="flex flex-col gap-8 md:flex-row">
|
<div class="flex flex-wrap gap-8 place-self-start xl:place-self-center">
|
||||||
<Button
|
<Button
|
||||||
href={`/release-notes#${latestVersion.version}`}
|
href={`/release-notes#${latestVersion.version}`}
|
||||||
isPrimary
|
isPrimary
|
||||||
class="flex w-fit items-center gap-2"
|
class="flex w-fit items-center gap-2"
|
||||||
>
|
>
|
||||||
<span>{whatsNew.readFullReleaseNotes}</span>
|
<span>{whatsNew.readFullReleaseNotes}</span>
|
||||||
<ArrowRight />
|
<ArrowRightIcon />
|
||||||
</Button>
|
</Button>
|
||||||
<SocialMediaStrip gap="6" />
|
<SocialMediaStrip gap="6" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Video
|
<Video
|
||||||
src={whatsNewVideo}
|
src={whatsNewVideo}
|
||||||
autoplay
|
autoplay
|
||||||
|
@ -89,7 +90,7 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
|
||||||
muted
|
muted
|
||||||
playsinline
|
playsinline
|
||||||
preload="none"
|
preload="none"
|
||||||
class="w-full rounded-3xl object-cover shadow-lg"
|
class="rounded-3xl object-cover shadow-lg"
|
||||||
/>
|
/>
|
||||||
</main>
|
</main>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
@ -3,6 +3,32 @@ export default {
|
||||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||||
darkMode: ['selector', '[data-theme="dark"]'],
|
darkMode: ['selector', '[data-theme="dark"]'],
|
||||||
theme: {
|
theme: {
|
||||||
|
container: {
|
||||||
|
screens: {
|
||||||
|
sm: '100%',
|
||||||
|
md: '100%',
|
||||||
|
lg: '1024px',
|
||||||
|
xl: '1280px',
|
||||||
|
},
|
||||||
|
padding: {
|
||||||
|
DEFAULT: '1rem',
|
||||||
|
sm: '1.5rem',
|
||||||
|
md: '1.5rem',
|
||||||
|
lg: '1.5rem',
|
||||||
|
xl: '2rem',
|
||||||
|
},
|
||||||
|
center: true,
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
junicode: [
|
||||||
|
'Junicode, serif',
|
||||||
|
{
|
||||||
|
fontFeatureSettings: {
|
||||||
|
swsh: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
extend: {
|
extend: {
|
||||||
screens: {
|
screens: {
|
||||||
'-sm': '@media (max-width: 639px)',
|
'-sm': '@media (max-width: 639px)',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue