mirror of
https://github.com/zen-browser/www.git
synced 2025-07-08 01:10:02 +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
|
||||
},
|
||||
"files": {
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
".git",
|
||||
"dist"
|
||||
]
|
||||
"ignore": ["node_modules", ".git", "dist"]
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "single",
|
||||
"semicolons": "asNeeded"
|
||||
}
|
||||
},
|
||||
"assists": {
|
||||
"actions": {
|
||||
"source": {
|
||||
"sortJsxProps": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"defaultBranch": "main",
|
||||
"root": ".",
|
||||
"useIgnoreFile": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"wrangler": "wrangler",
|
||||
"astro": "astro",
|
||||
"lint": "biome lint ./src",
|
||||
"format": "biome format ./src --write",
|
||||
"format": "biome format ./src",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -45,8 +45,6 @@
|
|||
"wrangler": "^3.94.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{ts,tsx,astro,js,jsx}": [
|
||||
"biome check --write ./src"
|
||||
]
|
||||
"src/**/*.{ts,tsx,astro,js,jsx}": ["biome check --write ./src"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,68 +1,70 @@
|
|||
{
|
||||
"version": "v1.0.0",
|
||||
"entity": {
|
||||
"type": "individual",
|
||||
"role": "owner",
|
||||
"name": "Mauro",
|
||||
"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.",
|
||||
"webpageUrl": {
|
||||
"url": "https://cheff.dev",
|
||||
"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"]
|
||||
}
|
||||
]
|
||||
"version": "v1.0.0",
|
||||
"entity": {
|
||||
"type": "individual",
|
||||
"role": "owner",
|
||||
"name": "Mauro",
|
||||
"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.",
|
||||
"webpageUrl": {
|
||||
"url": "https://cheff.dev",
|
||||
"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"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { ArrowLeft } from 'lucide-astro'
|
||||
import ArrowLeftIcon from '~/icons/ArrowLeftIcon.astro'
|
||||
import { getLocale, getUI } from '~/utils/i18n'
|
||||
|
||||
const locale = getLocale(Astro)
|
||||
|
@ -15,6 +15,6 @@ const {
|
|||
onclick="window.history.back()"
|
||||
class="mb-8 flex w-min items-center gap-2"
|
||||
>
|
||||
<ArrowLeft class="size-4" />
|
||||
<ArrowLeftIcon class="size-4" />
|
||||
{slug.back}
|
||||
</button>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
---
|
||||
import Image from 'astro/components/Image.astro'
|
||||
import { Check, Github } from 'lucide-astro'
|
||||
import { motion } from 'motion/react'
|
||||
import { getTitleAnimation } from '~/animations'
|
||||
import ComImage from '~/assets/ComImage.png'
|
||||
import Button from '~/components/Button.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'
|
||||
|
||||
const locale = getLocale(Astro)
|
||||
|
@ -19,9 +20,9 @@ const {
|
|||
|
||||
<section
|
||||
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)}>
|
||||
{community.title[0]}
|
||||
</motion.span>
|
||||
|
@ -35,16 +36,14 @@ const {
|
|||
<motion.p
|
||||
client:load
|
||||
{...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}
|
||||
</motion.p>
|
||||
<div
|
||||
class="mt-6 flex w-full flex-wrap gap-3 px-4 sm:gap-10 sm:px-0 md:justify-center"
|
||||
>
|
||||
<div class="flex w-full flex-wrap gap-3 sm:gap-10 md:justify-center">
|
||||
<motion.span client:load {...getTitleAnimation(0.8)}>
|
||||
<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>
|
||||
</Button>
|
||||
</motion.span>
|
||||
|
@ -53,7 +52,7 @@ const {
|
|||
{...getTitleAnimation(1)}
|
||||
className="flex items-center gap-4"
|
||||
>
|
||||
<Check class="size-4" />
|
||||
<CheckIcon class="size-4" />
|
||||
<span>{community.lists.simpleYetPowerful.title}</span>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
|
@ -61,19 +60,19 @@ const {
|
|||
{...getTitleAnimation(1.2)}
|
||||
className="flex items-center gap-4"
|
||||
>
|
||||
<Check class="size-4" />
|
||||
<CheckIcon class="size-4" />
|
||||
<span>{community.lists.privateAndAlwaysUpToDate.title}</span>
|
||||
</motion.div>
|
||||
</div>
|
||||
<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
|
||||
{...getTitleAnimation(1.4)}
|
||||
>
|
||||
<Image
|
||||
src={ComImage}
|
||||
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>
|
||||
</section>
|
||||
|
|
|
@ -26,7 +26,7 @@ const descriptions = Object.values(features.featureTabs).map((tab) => tab.descri
|
|||
|
||||
<section
|
||||
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">
|
||||
<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">
|
||||
{features.description}
|
||||
</motion.p>
|
||||
<div
|
||||
class="mb-12 mt-6 flex flex-col gap-6 lg:flex-row lg:justify-between lg:gap-2"
|
||||
>
|
||||
<div class="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">
|
||||
<!-- Mobile tabs -->
|
||||
<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 Circles from '~/components/Circles.astro'
|
||||
import Description from '~/components/Description.astro'
|
||||
import SocialMediaStrip from '~/components/SocialMediaStrip.astro'
|
||||
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
||||
|
||||
const locale = getLocale(Astro)
|
||||
|
@ -15,11 +15,13 @@ const {
|
|||
|
||||
<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"
|
||||
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
|
||||
class="w-full text-center lg:w-1/2 lg:text-left"
|
||||
aria-labelledby="footer-title"
|
||||
|
@ -39,7 +41,7 @@ const {
|
|||
aria-label={footer.download}
|
||||
>
|
||||
{footer.download}
|
||||
<ArrowRight class="size-4" aria-hidden="true" />
|
||||
<ArrowRightIcon class="size-4" aria-hidden="true" />
|
||||
</Button>
|
||||
</section>
|
||||
<section
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
import { ArrowRight } from 'lucide-astro'
|
||||
import { motion } from 'motion/react'
|
||||
import { getTitleAnimation } from '~/animations'
|
||||
import HomePageVideo from '~/assets/HomePageVideo.webm'
|
||||
import Button from '~/components/Button.astro'
|
||||
import Description from '~/components/Description.astro'
|
||||
import Title from '~/components/Title.astro'
|
||||
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||
import { getLocale, getPath, getUI } from '~/utils/i18n'
|
||||
import SocialMediaStrip from './SocialMediaStrip.astro'
|
||||
import Video from './Video.astro'
|
||||
|
@ -37,7 +37,7 @@ const {
|
|||
>
|
||||
<div class="flex h-full flex-col items-center justify-center">
|
||||
<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()}>
|
||||
{hero.title[0]}
|
||||
|
@ -71,7 +71,7 @@ const {
|
|||
<motion.span client:load {...getHeroTitleAnimation()}>
|
||||
<Button class="w-full" href={getLocalePath('/download')} isPrimary>
|
||||
{hero.buttons.beta}
|
||||
<ArrowRight class="size-4" />
|
||||
<ArrowRightIcon class="size-4" />
|
||||
</Button>
|
||||
</motion.span>
|
||||
<motion.span client:load {...getHeroTitleAnimation()}>
|
||||
|
@ -88,7 +88,7 @@ const {
|
|||
</div>
|
||||
</header>
|
||||
<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
|
||||
{...getHeroTitleAnimation()}
|
||||
>
|
||||
|
@ -99,6 +99,6 @@ const {
|
|||
muted
|
||||
playsinline
|
||||
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>
|
||||
|
|
|
@ -89,36 +89,36 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
|||
return (
|
||||
<div className="mx-auto mb-12 flex items-center justify-center gap-4 px-8">
|
||||
<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'}`}
|
||||
onClick={() => navigatePage(page - 1)}
|
||||
type="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) => {
|
||||
if (index === 0) {
|
||||
return (
|
||||
<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"
|
||||
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 (
|
||||
<span key={value} className="text-sm">
|
||||
<span className="text-sm" key={value}>
|
||||
{value.replace('{totalPages}', totalPages.toString()).replace('{totalItems}', totalItems.toString())}
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</form>
|
||||
<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'}`}
|
||||
onClick={() => navigatePage(page + 1)}
|
||||
type="button"
|
||||
>
|
||||
>
|
||||
</button>
|
||||
|
@ -128,24 +128,24 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<div className="mx-auto flex flex-col items-start gap-4 px-8 lg:w-1/2">
|
||||
<div className="flex w-full flex-col items-center gap-6">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex w-full flex-col items-center justify-center gap-6">
|
||||
<input
|
||||
type="text"
|
||||
id="search"
|
||||
className="w-full rounded-full border-2 border-dark bg-transparent px-6 py-2 text-lg outline-none"
|
||||
placeholder={mods.search}
|
||||
value={search}
|
||||
id="search"
|
||||
onInput={handleSearch}
|
||||
placeholder={mods.search}
|
||||
type="text"
|
||||
value={search}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
<button
|
||||
type="button"
|
||||
onClick={toggleCreatedSort}
|
||||
className="flex items-center gap-2 px-4 py-2 font-semibold text-md"
|
||||
onClick={toggleCreatedSort}
|
||||
type="button"
|
||||
>
|
||||
{mods.sort.lastCreated}
|
||||
<span
|
||||
|
@ -159,9 +159,9 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
|||
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={toggleUpdatedSort}
|
||||
className="flex items-center gap-2 px-4 py-2 font-semibold text-md"
|
||||
onClick={toggleUpdatedSort}
|
||||
type="button"
|
||||
>
|
||||
{mods.sort.lastUpdated}
|
||||
<span
|
||||
|
@ -174,14 +174,14 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
|||
</div>
|
||||
|
||||
<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}
|
||||
</label>
|
||||
<select
|
||||
id="limit"
|
||||
value={limit}
|
||||
onInput={handleLimitChange}
|
||||
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="24">24</option>
|
||||
|
@ -192,20 +192,20 @@ export default function ModsList({ allMods, locale }: ModsListProps) {
|
|||
</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.map((mod) => (
|
||||
<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}`}
|
||||
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">
|
||||
<img
|
||||
src={mod.image}
|
||||
alt={mod.name}
|
||||
loading="lazy"
|
||||
className="h-full w-full object-cover transition-transform duration-100 hover:scale-105"
|
||||
loading="lazy"
|
||||
src={mod.image}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
---
|
||||
import { Astronav, Dropdown, DropdownItems, MenuItems } from 'astro-navbar'
|
||||
import { ArrowRight, ChevronDown, Download, Menu } from 'lucide-astro'
|
||||
import { motion } from 'motion/react'
|
||||
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 { getTitleAnimation } from '../animations.ts'
|
||||
import Logo from './Logo.astro'
|
||||
|
@ -21,7 +24,7 @@ const {
|
|||
<!-- Desktop Navigation -->
|
||||
<Astronav>
|
||||
<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
|
||||
class="flex items-center gap-2 text-lg font-bold"
|
||||
|
@ -36,7 +39,7 @@ const {
|
|||
<Dropdown class="group">
|
||||
<button class="flex items-center">
|
||||
<span>{menu.gettingStarted}</span>
|
||||
<ChevronDown
|
||||
<ChevronDownIcon
|
||||
class="size-4 transform transition-transform duration-200 group-open:rotate-180 md:ml-2"
|
||||
/>
|
||||
</button>
|
||||
|
@ -56,7 +59,7 @@ const {
|
|||
</div>
|
||||
<Button isPrimary class="mt-auto">
|
||||
{menu.tryZenMods}
|
||||
<ArrowRight class="size-4" />
|
||||
<ArrowRightIcon class="size-4" />
|
||||
</Button>
|
||||
</a>
|
||||
<a class="dropdown-item" href={getLocalePath('/release-notes')}>
|
||||
|
@ -77,7 +80,7 @@ const {
|
|||
<Dropdown class="group">
|
||||
<button class="flex items-center">
|
||||
<span>{menu.usefulLinks}</span>
|
||||
<ChevronDown
|
||||
<ChevronDownIcon
|
||||
class="size-4 transform transition-transform duration-200 group-open:rotate-180 md:ml-2"
|
||||
/>
|
||||
</button>
|
||||
|
@ -129,10 +132,10 @@ const {
|
|||
<Button href="/download" class="hidden lg:flex" isPrimary>
|
||||
<span class="hidden items-center gap-2 lg:flex">
|
||||
{menu.download}
|
||||
<ArrowRight class="size-4" />
|
||||
<ArrowRightIcon class="size-4" />
|
||||
</span>
|
||||
<span class="flex items-center gap-2 lg:hidden">
|
||||
<Download class="size-4" />
|
||||
<DownloadIcon class="size-4" />
|
||||
</span>
|
||||
</Button>
|
||||
<label
|
||||
|
@ -140,7 +143,7 @@ const {
|
|||
class="cursor-pointer p-2 text-dark lg:hidden"
|
||||
aria-label="Open menu"
|
||||
>
|
||||
<Menu class="h-6 w-6" />
|
||||
<MenuIcon class="h-6 w-6" />
|
||||
</label>
|
||||
</div>
|
||||
</MenuItems>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
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 { getLocale, getPath, getUI } from '~/utils/i18n'
|
||||
|
@ -112,7 +112,7 @@ if (prevReleaseNote && !isTwilight) {
|
|||
}
|
||||
</div>
|
||||
<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">
|
||||
{isTwilight ? <>{releaseNoteItem.twilightWarning}</> : null}
|
||||
<span set:html={releaseNoteItem.reportIssues} />
|
||||
|
|
|
@ -18,12 +18,10 @@ const {
|
|||
} = getUI(locale)
|
||||
---
|
||||
|
||||
<section id="sponsors" class:list={['mb-32 px-4', !showSponsors && 'hidden']}>
|
||||
<div class="mx-auto flex flex-col px-6 text-center">
|
||||
<section id="sponsors" class:list={['py-12', !showSponsors && 'hidden']}>
|
||||
<div class="mx-auto flex flex-col text-center">
|
||||
<motion.span client:load {...getTitleAnimation(0.2)}>
|
||||
<Description class="mb-2 px-4 text-6xl font-bold"
|
||||
>Our Sponsors</Description
|
||||
>
|
||||
<Description class="mb-2 text-6xl font-bold">Our Sponsors</Description>
|
||||
</motion.span>
|
||||
<motion.span client:load {...getTitleAnimation(0.4)}>
|
||||
<Description set:html={sponsors.description} />
|
||||
|
|
|
@ -2,18 +2,6 @@
|
|||
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 />
|
||||
</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}
|
||||
/>
|
||||
)}
|
||||
{releases.x86_64 && 'tarball' in releases.x86_64 && releases.x86_64.tarball && releases.x86_64.tarball.label && (
|
||||
<DownloadCard
|
||||
label={releases.x86_64.tarball.label}
|
||||
href={releases.x86_64.tarball.link}
|
||||
checksum={releases.x86_64.tarball.checksum}
|
||||
/>
|
||||
{releases.x86_64 && (
|
||||
'tarball' in releases.x86_64
|
||||
? releases.x86_64.tarball.label && (
|
||||
<DownloadCard
|
||||
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 && (
|
||||
<DownloadCard
|
||||
|
|
|
@ -144,86 +144,107 @@
|
|||
}
|
||||
},
|
||||
"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.",
|
||||
"littleHelp": "A little help?",
|
||||
"mainTeam": {
|
||||
"title": "Main Team",
|
||||
"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": {
|
||||
"mauro": {
|
||||
"name": "Mauro B.",
|
||||
"description": "Creator, Main Developer",
|
||||
"link": "https://cheff.dev/"
|
||||
"browser": {
|
||||
"mauro": {
|
||||
"name": "Mauro B.",
|
||||
"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": {
|
||||
"name": "Oscar Gonzalez",
|
||||
"description": "Site Reliability Engineer (SRE) and code signing.",
|
||||
"link": false
|
||||
},
|
||||
"jan": {
|
||||
"name": "Jan Heres",
|
||||
"description": "Active contributor and helps with MacOS builds",
|
||||
"link": "https://janheres.eu/"
|
||||
},
|
||||
"brhm": {
|
||||
"name": "BrhmDev",
|
||||
"description": "Active contributor with great contributions",
|
||||
"link": "https://github.com/BrhmDev"
|
||||
},
|
||||
"canoa": {
|
||||
"name": "Canoa",
|
||||
"description": "Active contributor, and very active in issue handling and website management",
|
||||
"link": "https://thatcanoa.org/"
|
||||
},
|
||||
"adam": {
|
||||
"name": "Adam",
|
||||
"description": "Branding and design",
|
||||
"link": "https://cybrneon.xyz/"
|
||||
},
|
||||
"kristijanribaric": {
|
||||
"name": "Kristijan Ribaric",
|
||||
"description": "Active contributor",
|
||||
"link": "https://github.com/kristijanribaric"
|
||||
},
|
||||
"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
|
||||
"website": {
|
||||
"taroj1205": {
|
||||
"name": "Shintaro Jokagi",
|
||||
"description": "Core Website Architect, Spearheading Refactoring and Technical Enhancements",
|
||||
"link": "https://github.com/taroj1205"
|
||||
},
|
||||
"jace": {
|
||||
"name": "Jace",
|
||||
"description": "Contributes to website design and branding",
|
||||
"link": "https://x.com/JaceThings"
|
||||
},
|
||||
"canoa": {
|
||||
"name": "Canoa",
|
||||
"description": "Active contributor, and very active in issue handling and website management",
|
||||
"link": "https://thatcanoa.org/"
|
||||
},
|
||||
"adam": {
|
||||
"name": "Adam",
|
||||
"description": "Branding and design",
|
||||
"link": "https://cybrneon.xyz/"
|
||||
},
|
||||
"n7itro": {
|
||||
"name": "n7itro",
|
||||
"description": "Active contributor and release notes writer",
|
||||
"link": "https://github.com/n7itro"
|
||||
},
|
||||
"jafeth": {
|
||||
"name": "Jafeth Garro",
|
||||
"description": "Documentation writer",
|
||||
"link": "https://iamjafeth.com/"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"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.",
|
||||
"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": {
|
||||
"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! ❤️"
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"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>
|
||||
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;',
|
||||
'color: #f76f53; font-size: 16px; font-family: "Rubik"; margin-bottom: 20px;'
|
||||
);
|
||||
|
@ -97,7 +97,7 @@ const locale = getLocale(Astro)
|
|||
|
||||
</head>
|
||||
<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 />
|
||||
<slot />
|
||||
|
|
|
@ -15,17 +15,19 @@ const {
|
|||
|
||||
<Layout title={notFound.title}>
|
||||
<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>
|
||||
<Description class="mb-6 text-xl md:text-2xl">
|
||||
{notFound.title}
|
||||
</Description>
|
||||
<p class="mb-8 max-w-xl text-lg text-gray-500 dark:text-gray-400">
|
||||
{notFound.description}
|
||||
</p>
|
||||
<Button href={getLocalePath('/')} isPrimary>
|
||||
{notFound.button}
|
||||
</Button>
|
||||
<Title class="text-7xl font-bold text-coral md:text-9xl">404</Title>
|
||||
<div class="flex flex-col items-center gap-6">
|
||||
<Description class="text-xl md:text-2xl">
|
||||
{notFound.title}
|
||||
</Description>
|
||||
<p class="max-w-xl text-lg text-gray-500 dark:text-gray-400">
|
||||
{notFound.description}
|
||||
</p>
|
||||
<Button href={getLocalePath('/')} isPrimary class="w-fit">
|
||||
{notFound.button}
|
||||
</Button>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
---
|
||||
import Button from '~/components/Button.astro'
|
||||
import { Image } from 'astro:assets'
|
||||
import Description from '~/components/Description.astro'
|
||||
import Layout from '~/layouts/Layout.astro'
|
||||
import { getLocale, getUI } from '~/utils/i18n'
|
||||
export { getStaticPaths } from '~/utils/i18n'
|
||||
import Button from '~/components/Button.astro'
|
||||
|
||||
const locale = getLocale(Astro)
|
||||
|
||||
|
@ -18,65 +19,67 @@ const {
|
|||
description={layout.about.description}
|
||||
>
|
||||
<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">
|
||||
<Description class="text-6xl font-bold">{about.title}</Description>
|
||||
<Description>
|
||||
<div class="w-full flex flex-col gap-6">
|
||||
<Description class="text-6xl font-bold leading-none">{about.title}</Description>
|
||||
<Description class="max-w-4xl">
|
||||
{about.description}
|
||||
</Description>
|
||||
<Button href="/donate" class="mx-auto mt-4 w-fit" isPrimary
|
||||
<Button href="/donate" class="w-fit" isPrimary
|
||||
>{about.littleHelp}</Button
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="relative flex w-full flex-col items-center justify-center lg:flex-row"
|
||||
>
|
||||
<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>
|
||||
<div class="flex flex-col gap-4 w-full">
|
||||
<div class="text-4xl lg:text-5xl font-bold leading-none">{about.mainTeam.title}</div>
|
||||
<Description>
|
||||
{about.mainTeam.description}
|
||||
</Description>
|
||||
<div class="mt-4">
|
||||
<ul>
|
||||
{Object.entries(about.mainTeam.members).map(([_key, member]) => (
|
||||
<li class="text-sm">
|
||||
{member.link ? (
|
||||
<a href={member.link === true ? '' : member.link}>
|
||||
<strong class="zen-link font-bold">{member.name}</strong>
|
||||
</a>
|
||||
<span class="opacity-60"> : {member.description}</span>
|
||||
) : (
|
||||
<strong class="font-bold">{member.name}</strong>
|
||||
<span class="opacity-60"> : {member.description}</span>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div class="flex flex-col gap-6">
|
||||
{Object.entries(about.mainTeam.members).map(([team, members]) => (
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="text-3xl font-semibold">{about.mainTeam.subTitle[team as keyof typeof about.mainTeam.subTitle]}</div>
|
||||
<ul class="flex flex-col gap-2">
|
||||
{Object.entries(members).map(([_key, member]) => (
|
||||
<li class="text-sm">
|
||||
{member.link && typeof member.link === 'string' ? (
|
||||
<a href={member.link}>
|
||||
<strong class="zen-link font-bold">{member.name}</strong>
|
||||
</a>
|
||||
) : (
|
||||
<strong class="font-bold">{member.name}</strong>
|
||||
)}
|
||||
<span class="opacity-80">: {member.description}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute hidden h-full w-[1px] bg-dark opacity-15 lg:block">
|
||||
</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>
|
||||
<div class="flex flex-col gap-4 w-full">
|
||||
<div class="text-4xl lg:text-5xl font-bold leading-none">{about.contributors.title}</div>
|
||||
<Description>
|
||||
{about.contributors.description}
|
||||
</Description>
|
||||
<a href="https://github.com/zen-browser/desktop/graphs/contributors"
|
||||
><img
|
||||
<div class="flex flex-col gap-4 w-fit"><Description class="text-3xl font-semibold lg:text-4xl">{about.contributors.browser}</Description>
|
||||
<a href="https://github.com/zen-browser/desktop/graphs/contributors"
|
||||
><Image
|
||||
src="https://contributors-img.web.app/image?repo=zen-browser/desktop"
|
||||
alt="Contributors"
|
||||
class="mt-8"
|
||||
width={500}
|
||||
height={500}
|
||||
/></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"
|
||||
><img
|
||||
><Image
|
||||
src="https://contributors-img.web.app/image?repo=zen-browser/www"
|
||||
alt="Contributors (website)"
|
||||
class="mt-8"
|
||||
width={500}
|
||||
height={500}
|
||||
/></a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
></div></div>
|
||||
|
||||
</main>
|
||||
</Layout>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
import { ArrowRight } from 'lucide-astro'
|
||||
import Button from '~/components/Button.astro'
|
||||
import Description from '~/components/Description.astro'
|
||||
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||
import Layout from '~/layouts/Layout.astro'
|
||||
import { getLocale, getUI } from '~/utils/i18n'
|
||||
export { getStaticPaths } from '~/utils/i18n'
|
||||
|
@ -14,51 +14,41 @@ const {
|
|||
---
|
||||
|
||||
<Layout title={layout.donate.title} description={layout.donate.description}>
|
||||
<main class="pb-52 pt-36">
|
||||
<div
|
||||
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">
|
||||
<main class="container pb-52 pt-24 flex flex-col items-center gap-12">
|
||||
<div class="flex flex-col gap-4 lg:text-center">
|
||||
<Description class="text-6xl font-bold">{donate.title}</Description>
|
||||
<Description>
|
||||
<Description class="max-w-3xl">
|
||||
{donate.description}
|
||||
</Description>
|
||||
</div>
|
||||
<div class="flex w-full flex-col items-center justify-center lg:flex-row">
|
||||
<div class="flex flex-col p-8 lg:w-1/3 lg:pr-24">
|
||||
<div
|
||||
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>
|
||||
<Description>
|
||||
{donate.patreon.description}
|
||||
</Description>
|
||||
<div class="mt-6">
|
||||
<Button
|
||||
isPrimary
|
||||
href="https://www.patreon.com/zen_browser"
|
||||
class="w-fit"
|
||||
>
|
||||
Go to Patreon
|
||||
<ArrowRight class="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
isPrimary
|
||||
href="https://www.patreon.com/zen_browser"
|
||||
class="w-fit"
|
||||
>
|
||||
{donate.patreon.button}
|
||||
<ArrowRightIcon class="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<div class="hidden h-72 w-[1px] bg-dark opacity-15 lg:block"></div>
|
||||
<div class="flex flex-col p-8 lg:w-1/3 lg:pl-24">
|
||||
<hr class="hidden h-72 w-[1px] bg-dark opacity-15 lg:block" />
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<div class="text-6xl font-bold">{donate.koFi.title}</div>
|
||||
<Description>
|
||||
{donate.koFi.description}
|
||||
</Description>
|
||||
<div class="mt-6">
|
||||
<Button
|
||||
href="https://ko-fi.com/zen_browser"
|
||||
isPrimary
|
||||
class="w-fit"
|
||||
>
|
||||
{donate.koFi.button}
|
||||
<ArrowRight class="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<Button href="https://ko-fi.com/zen_browser" isPrimary class="w-fit">
|
||||
{donate.koFi.button}
|
||||
<ArrowRightIcon class="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</Layout>
|
||||
|
|
|
@ -9,7 +9,8 @@ import { getLocale, getUI } from '~/utils/i18n'
|
|||
|
||||
import { icon, library } from '@fortawesome/fontawesome-svg-core'
|
||||
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'
|
||||
|
||||
|
@ -36,7 +37,7 @@ const platformDescriptions = download.platformDescriptions
|
|||
|
||||
<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">
|
||||
<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">
|
||||
<Description id="download-title" class="text-6xl font-bold"
|
||||
>{download.title}</Description
|
||||
|
@ -180,7 +181,7 @@ const platformDescriptions = download.platformDescriptions
|
|||
<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"
|
||||
>
|
||||
<ExternalLink
|
||||
<ExternalLinkIcon
|
||||
class="h-5 w-5 transition-all duration-200 group-hover:text-coral"
|
||||
/>
|
||||
</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"
|
||||
>
|
||||
<div class="h-fit rounded-xl bg-subtle p-3">
|
||||
<Lock class="h-5 w-5" />
|
||||
<LockIcon class="h-5 w-5" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -17,7 +17,7 @@ const { layout } = getUI(locale)
|
|||
description={layout.index.description}
|
||||
isHome
|
||||
>
|
||||
<main>
|
||||
<main class="container">
|
||||
<Hero />
|
||||
<Features />
|
||||
<Sponsors showSponsors />
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
import { ArrowRight, Info } from 'lucide-astro'
|
||||
import BackButton from '~/components/BackButton.astro'
|
||||
import Button from '~/components/Button.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 { getAllMods, getAuthorLink, getLocalizedDate } from '~/mods'
|
||||
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"
|
||||
>
|
||||
<div class="flex items-center gap-2 text-center md:text-left">
|
||||
<Info />
|
||||
<InfoIcon />
|
||||
<p class="text-sm">
|
||||
{slug.alert.description}
|
||||
</p>
|
||||
|
@ -75,7 +76,7 @@ const {
|
|||
isAlert
|
||||
>
|
||||
{slug.alert.button}
|
||||
<ArrowRight class="size-4" />
|
||||
<ArrowRightIcon class="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<BackButton />
|
||||
|
|
|
@ -18,16 +18,12 @@ const allMods = (await getAllMods()) || []
|
|||
---
|
||||
|
||||
<Layout title={layout.mods.title}>
|
||||
<main class="mx-auto mt-32 max-w-[120rem] 2xl:mt-0">
|
||||
<header class="mb-10 mt-32 flex w-full flex-col justify-center border-dark">
|
||||
<div class="mx-auto flex flex-col gap-6 px-8 lg:w-1/2">
|
||||
<div>
|
||||
<Description class="text-6xl font-bold">{mods.title}</Description>
|
||||
<Description>
|
||||
{mods.description}
|
||||
</Description>
|
||||
</div>
|
||||
</div>
|
||||
<main class="container mt-32 flex flex-col gap-10 2xl:mt-32">
|
||||
<header class="flex w-full flex-col gap-8 border-dark">
|
||||
<Description class="text-6xl font-bold">{mods.title}</Description>
|
||||
<Description class="max-w-3xl">
|
||||
{mods.description}
|
||||
</Description>
|
||||
</header>
|
||||
|
||||
<!-- Importing ModList component -->
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
import { Modal, ModalBody, ModalHeader } from 'free-astro-components'
|
||||
import { ArrowUp } from 'lucide-astro'
|
||||
import Button from '~/components/Button.astro'
|
||||
import Description from '~/components/Description.astro'
|
||||
import ReleaseNoteItem from '~/components/ReleaseNoteItem.astro'
|
||||
import ArrowUpIcon from '~/icons/ArrowUp.astro'
|
||||
import Layout from '~/layouts/Layout.astro'
|
||||
import { releaseNotes as releaseNotesData, releaseNotesTwilight } from '~/release-notes'
|
||||
import { getLocale, getUI } from '~/utils/i18n'
|
||||
|
@ -19,11 +19,11 @@ const {
|
|||
|
||||
<Layout title={layout.releaseNotes.title}>
|
||||
<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
|
||||
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>
|
||||
<p
|
||||
|
@ -58,9 +58,9 @@ const {
|
|||
<Button href="#" id="scroll-top" isPrimary class="fixed bottom-8 right-8">
|
||||
<p class="hidden items-center gap-2 sm:flex">
|
||||
{releaseNotes.backToTop}
|
||||
<ArrowUp aria-hidden="true" class="size-4" />
|
||||
<ArrowUpIcon aria-hidden="true" class="size-4" />
|
||||
</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>
|
||||
</Layout>
|
||||
<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}>
|
||||
<main
|
||||
class="relative mx-auto flex flex-col items-center gap-24 px-6 lg:gap-0 lg:px-24"
|
||||
>
|
||||
<main class="container">
|
||||
<Features
|
||||
title1={welcome.title[0]}
|
||||
title2={welcome.title[1]}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
import { ArrowRight } from 'lucide-astro'
|
||||
import Button from '~/components/Button.astro'
|
||||
import Description from '~/components/Description.astro'
|
||||
import SocialMediaStrip from '~/components/SocialMediaStrip.astro'
|
||||
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||
import Layout from '~/layouts/Layout.astro'
|
||||
|
||||
import whatsNewVideo from '~/assets/whats-new.mp4'
|
||||
|
@ -34,7 +34,7 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
|
|||
)}
|
||||
>
|
||||
<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>
|
||||
|
@ -51,37 +51,38 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
|
|||
<div>
|
||||
<Fragment set:html={whatsNewText[0].replace(/\n/g, '<br>')} />
|
||||
</div>
|
||||
<ul class="hidden flex-col gap-2 md:flex">
|
||||
<ul class="hidden list-disc flex-col gap-2 xl:container xl:flex">
|
||||
<a
|
||||
href="https://github.com/zen-browser/desktop/issues/new/choose"
|
||||
target="_blank"
|
||||
>
|
||||
<li class="ml-3 list-disc">
|
||||
<Description class="text-base font-bold"
|
||||
>{whatsNew.reportIssue}</Description
|
||||
>
|
||||
<li>
|
||||
<Description class="text-base font-bold">
|
||||
{whatsNew.reportIssue}
|
||||
</Description>
|
||||
</li>
|
||||
</a>
|
||||
<a href="https://discord.gg/zen-browser" target="_blank">
|
||||
<li class="ml-3 list-disc">
|
||||
<Description class="text-base font-bold"
|
||||
>{whatsNew.joinDiscord}</Description
|
||||
>
|
||||
<li>
|
||||
<Description class="text-base font-bold">
|
||||
{whatsNew.joinDiscord}
|
||||
</Description>
|
||||
</li>
|
||||
</a>
|
||||
</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
|
||||
href={`/release-notes#${latestVersion.version}`}
|
||||
isPrimary
|
||||
class="flex w-fit items-center gap-2"
|
||||
>
|
||||
<span>{whatsNew.readFullReleaseNotes}</span>
|
||||
<ArrowRight />
|
||||
<ArrowRightIcon />
|
||||
</Button>
|
||||
<SocialMediaStrip gap="6" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Video
|
||||
src={whatsNewVideo}
|
||||
autoplay
|
||||
|
@ -89,7 +90,7 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
|
|||
muted
|
||||
playsinline
|
||||
preload="none"
|
||||
class="w-full rounded-3xl object-cover shadow-lg"
|
||||
class="rounded-3xl object-cover shadow-lg"
|
||||
/>
|
||||
</main>
|
||||
</Layout>
|
||||
|
|
|
@ -3,6 +3,32 @@ export default {
|
|||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||
darkMode: ['selector', '[data-theme="dark"]'],
|
||||
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: {
|
||||
screens: {
|
||||
'-sm': '@media (max-width: 639px)',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue