This commit is contained in:
Bryan Galdámez 2025-06-19 10:32:03 +12:00 committed by GitHub
commit e9fac71a9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 899 additions and 750 deletions

View file

@ -40,5 +40,6 @@
},
"files.associations": {
"*.astro": "astro"
}
}
},
"css.customData": [".vscode/tailwind-extra-data.json"]
}

150
.vscode/tailwind-extra-data.json vendored Normal file
View file

@ -0,0 +1,150 @@
{
"version": 1.1,
"properties": [
{
"name": "--alpha()",
"description": "Use the `--alpha()` function to adjust the opacity of a color at build time.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "--spacing()",
"description": "Use the `--spacing()` function to generate a spacing value based on your themes scale.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "theme()",
"description": "Use the deprecated `theme()` function to access theme values using dot notation (v3 compatibility).",
"status": "deprecated",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
}
],
"atDirectives": [
{
"name": "@import",
"description": "Inline import CSS files, including Tailwind itself.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@theme",
"description": "Define custom design tokens (fonts, colors, breakpoints, etc.).",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@source",
"description": "Specify additional source files for Tailwinds content detection.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@utility",
"description": "Add custom utilities that work with variants like `hover`, `focus`, etc.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@variant",
"description": "Apply a Tailwind variant to CSS inside a rule.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@custom-variant",
"description": "Define your own variant for use in utility class names.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@apply",
"description": "Inline existing utility classes into your custom CSS rules.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@reference",
"description": "Reference (but not output) another stylesheet for use in `@apply`/`@variant`.",
"status": "standard",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@config",
"description": "Load a legacy JavaScript-based Tailwind config (v3 compatibility).",
"status": "compat",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
},
{
"name": "@plugin",
"description": "Load a legacy JavaScript-based Tailwind plugin (v3 compatibility).",
"status": "compat",
"references": [
{
"name": "Tailwind CSS: Functions and Directives",
"url": "https://tailwindcss.com/docs/functions-and-directives"
}
]
}
]
}

View file

@ -1,11 +1,12 @@
import react from '@astrojs/react'
import sitemap from '@astrojs/sitemap'
import tailwind from '@astrojs/tailwind'
import { defineConfig } from 'astro/config'
import tailwindcss from '@tailwindcss/vite'
// https://astro.build/config
export default defineConfig({
integrations: [tailwind(), react(), sitemap()],
integrations: [react(), sitemap()],
site: 'https://zen-browser.app',
i18n: {
defaultLocale: 'en',
@ -26,5 +27,7 @@ export default defineConfig({
},
},
},
plugins: [tailwindcss()],
},
})

View file

@ -18,6 +18,7 @@
"createdDesc",
"daniel",
"FMPEG",
"esbenp",
"ferrocyante",
"flatpaks",
"Galdámez",
@ -83,7 +84,8 @@
"*.bundle.js",
"package-lock.json",
"yarn.lock",
"pnpm-lock.yaml"
"pnpm-lock.yaml",
"pnpm-workspace.yaml"
],
"allowCompoundWords": true,
"dictionaries": ["typescript", "node", "html", "css", "bash", "npm", "es-es"],

View file

@ -28,7 +28,7 @@ eslint:
- playwright-report/**
- test-results/**
run: |
pnpm eslint {staged_files} --max-warnings=0 --fix --cache
pnpm eslint {staged_files} --max-warnings=0 --fix --cache --no-warn-ignored
stage_fixed: true
cspell:

View file

@ -30,11 +30,11 @@
"@astrojs/react": "^4.3.0",
"@astrojs/rss": "4.0.11",
"@astrojs/sitemap": "3.3.1",
"@astrojs/tailwind": "6.0.2",
"@fontsource/bricolage-grotesque": "5.1.0",
"@fortawesome/fontawesome-svg-core": "6.7.1",
"@fortawesome/free-brands-svg-icons": "6.7.1",
"@fortawesome/free-solid-svg-icons": "6.7.1",
"@tailwindcss/vite": "^4.1.8",
"@types/react": "^19.1.6",
"@types/react-dom": "^19.1.5",
"astro": "5.7.10",
@ -52,7 +52,7 @@
"react-dom": "^19.1.0",
"sharp": "0.33.5",
"tailwind-merge": "3.3.0",
"tailwindcss": "3.4.15",
"tailwindcss": "4.1.8",
"typescript": "5.6.3"
},
"devDependencies": {

702
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,7 @@
onlyBuiltDependencies:
- "@tailwindcss/oxide"
- esbuild
- lefthook
- sharp
- unrs-resolver
- workerd

View file

@ -23,15 +23,16 @@ const {
{...extra}
href={localePath ? getLocalePath(href) : href}
class:list={[
'text-sm disabled:cursor-not-allowed disabled:opacity-50',
'transition-bg flex items-center justify-center gap-2 rounded-xl px-6 py-4 transition-transform duration-150 hover:scale-[1.02] active:scale-[0.98]',
className,
isPrimary
? 'border-dark bg-dark text-paper shadow-lg'
: isAlert
? 'bg-red-300 text-dark'
? 'text-dark bg-red-300'
: !isBordered
? 'bg-subtle'
: '!transition-bg border-2 border-dark hover:bg-dark hover:text-paper hover:shadow-sm',
: '!transition-bg border-dark hover:bg-dark hover:text-paper border-2 hover:shadow-xs',
]}
{...props}
>
@ -42,15 +43,16 @@ const {
id={id}
{...extra}
class:list={[
'text-sm disabled:cursor-not-allowed disabled:opacity-50',
'transition-bg flex items-center justify-center gap-2 rounded-lg px-6 py-3 transition-transform duration-150 hover:scale-[1.02]',
className,
isPrimary
? 'border-dark bg-dark text-paper shadow-md'
: isAlert
? 'bg-red-300 text-dark'
? 'text-dark bg-red-300'
: !isBordered
? ''
: '!transition-bg border-2 border-dark hover:bg-dark hover:text-paper hover:shadow-sm',
: '!transition-bg border-dark hover:bg-dark hover:text-paper border-2 hover:shadow-xs',
]}
{...props}
>
@ -58,14 +60,3 @@ const {
</button>
)
}
<style>
button,
a {
font-size: 0.9rem;
&[disabled] {
cursor: not-allowed;
opacity: 0.5;
}
}
</style>

View file

@ -239,71 +239,3 @@ const descriptions = Object.values(features.featureTabs).map(tab => tab.descript
changeToFeature({ target: features[0] })
</script>
<style>
.feature {
@apply w-full cursor-pointer select-none rounded-lg p-4 opacity-0 hover:bg-subtle;
transition: background 0.2s ease-in-out;
&[data-active='true'] {
@apply bg-subtle;
}
}
.feature-tab {
@apply rounded-lg px-4 py-2 text-lg font-medium opacity-0 hover:bg-subtle;
transition: background 0.2s ease-in-out;
&[data-active='true'] {
@apply bg-subtle;
}
}
.feature-description {
@apply px-4 text-sm;
}
.video-stack {
@apply aspect-video;
perspective: 2000px;
transform-style: preserve-3d;
}
.feature-video {
@apply left-1/2 hidden transform rounded-3xl shadow-md lg:absolute lg:mx-auto lg:block lg:w-full dark:opacity-80;
max-width: 800px;
transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
position: absolute;
top: 0;
transform-origin: top center;
backface-visibility: hidden;
will-change: transform, opacity;
transform: translate3d(-50%, 0, -100px) scale(0.95);
}
/* Don't animate translation on small screens */
@media (max-width: 1024px) {
.feature-video {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
transform: none !important;
display: none;
object-fit: cover;
&[data-active='true'] {
display: block;
opacity: 1;
}
}
.video-stack {
@apply overflow-hidden rounded-xl;
position: relative;
width: 100%;
aspect-ratio: 16/9;
}
}
</style>

View file

@ -15,7 +15,7 @@ const {
<footer
id="footer"
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"
class="border-dark bg-dark text-paper relative flex w-full flex-col items-center gap-16 overflow-hidden border-t px-4 py-12 lg:p-24"
role="contentinfo"
aria-label="Site footer"
>
@ -24,7 +24,7 @@ const {
class="flex w-full flex-col gap-4 text-center lg:w-1/2 lg:text-left"
aria-labelledby="footer-title"
>
<Description id="footer-title" class="text-6xl font-bold !text-paper"
<Description id="footer-title" class="!text-paper text-6xl font-bold"
>{footer.title}</Description
>
<Description class="mx-auto max-w-xl lg:mx-0">
@ -35,7 +35,7 @@ const {
<Button
href="/download"
isPrimary
class="h-fit w-fit bg-paper !text-dark"
class="bg-paper !text-dark h-fit w-fit"
aria-label={footer.download}
>
{footer.download}
@ -128,8 +128,8 @@ const {
set:html={footer.madeWith.replace('{link}', getLocalePath('/about'))}
/>
</section>
<section class="absolute bottom-0 right-0">
<Circles white multiplier={0.7} class="mb-[-100px] ml-auto mr-[-80px] hidden lg:block" />
<section class="absolute right-0 bottom-0">
<Circles white multiplier={0.7} class="mr-[-80px] mb-[-100px] ml-auto hidden lg:block" />
</section>
</div>
</footer>

View file

@ -42,7 +42,7 @@ const {
<motion.span
client:load
{...getHeroTitleAnimation()}
className={title.highlight ? 'italic text-coral' : ''}
className={title.highlight ? 'text-coral italic' : ''}
>
{title.text}
</motion.span>

View file

@ -16,12 +16,12 @@ const {
<!-- Mobile Slide Menu -->
<div
id="mobile-menu"
class="fixed inset-y-0 right-0 z-40 w-64 translate-x-full transform bg-paper shadow-lg transition-transform duration-300 peer-checked:translate-x-0 lg:hidden"
class="bg-paper fixed inset-y-0 right-0 z-40 w-64 translate-x-full transform shadow-lg transition-transform duration-300 peer-checked:translate-x-0 lg:hidden"
>
<div class="flex items-center justify-between border-b border-dark px-4 py-2">
<div class="border-dark flex items-center justify-between border-b px-4 py-2">
<div class="text-lg font-bold">{menu.menu}</div>
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label for="mobile-menu-toggle" class="cursor-pointer p-2 text-dark">
<label for="mobile-menu-toggle" class="text-dark cursor-pointer p-2">
<span class="sr-only">Close menu</span>
<svg
xmlns="http://www.w3.org/2000/svg"
@ -46,17 +46,17 @@ const {
<div class="mb-2 font-bold">{menu.gettingStarted}</div>
<ul class="ml-4 space-y-2">
<li>
<a href={getLocalePath('/mods')} class="block text-dark hover:text-coral"
<a href={getLocalePath('/mods')} class="text-dark hover:text-coral block"
>{menu.zenMods}</a
>
</li>
<li>
<a href={getLocalePath('/release-notes')} class="block text-dark hover:text-coral"
<a href={getLocalePath('/release-notes')} class="text-dark hover:text-coral block"
>{menu.releaseNotes}</a
>
</li>
<li>
<a href="https://discord.gg/zen-browser" class="block text-dark hover:text-coral"
<a href="https://discord.gg/zen-browser" class="text-dark hover:text-coral block"
>{menu.discord}</a
>
</li>
@ -67,17 +67,17 @@ const {
<div class="mb-2 font-bold">{menu.usefulLinks}</div>
<ul class="ml-4 space-y-2">
<li>
<a href={getLocalePath('/donate')} class="block text-dark hover:text-coral"
<a href={getLocalePath('/donate')} class="text-dark hover:text-coral block"
>{menu.donate}</a
>
</li>
<li>
<a href={getLocalePath('/about')} class="block text-dark hover:text-coral"
<a href={getLocalePath('/about')} class="text-dark hover:text-coral block"
>{menu.aboutUs}</a
>
</li>
<li>
<a href="https://docs.zen-browser.app" class="block text-dark hover:text-coral"
<a href="https://docs.zen-browser.app" class="text-dark hover:text-coral block"
>{menu.documentation}</a
>
</li>
@ -85,19 +85,19 @@ const {
<a
href="https://github.com/zen-browser"
target="_blank"
class="block text-dark hover:text-coral">{menu.github}</a
class="text-dark hover:text-coral block">{menu.github}</a
>
</li>
</ul>
</li>
<!-- Extra Links -->
<li>
<a href={getLocalePath('/mods')} class="block font-bold text-dark hover:text-coral"
<a href={getLocalePath('/mods')} class="text-dark hover:text-coral block font-bold"
>{menu.mods}</a
>
</li>
<li>
<a href={getLocalePath('/download')} class="block font-bold text-dark hover:text-coral"
<a href={getLocalePath('/download')} class="text-dark hover:text-coral block font-bold"
>{menu.download}</a
>
</li>

View file

@ -33,10 +33,10 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
<div id="mods-list-container" class="flex flex-1 flex-col">
<div class="flex flex-col items-center gap-4">
<div
class="flex w-full flex-row items-center justify-center rounded-full border-2 border-dark pr-6"
class="border-dark flex w-full flex-row items-center justify-center rounded-full border-2 pr-6"
>
<input
class="w-full rounded-full bg-transparent py-2 pl-6 pr-4 text-lg outline-none"
class="w-full rounded-full bg-transparent py-2 pr-4 pl-6 text-lg outline-hidden"
id="search"
placeholder={translations.search}
type="text"
@ -44,7 +44,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
<button
id="clear-search"
title="Clear search"
class="hidden rounded-full p-1 transition-colors duration-150 hover:bg-subtle"
class="hover:bg-subtle hidden rounded-full p-1 transition-colors duration-150"
aria-label="Clear search"
tabindex="0"
>
@ -55,7 +55,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
<div class="mb-1 flex w-full items-center justify-between gap-4 sm:mb-2">
<div class="flex items-start gap-4">
<button
class="flex items-center gap-2 rounded-full border border-subtle px-5 py-1 text-sm font-semibold shadow-sm transition-colors hover:bg-muted focus:bg-coral/10 sm:text-base"
class="border-subtle hover:bg-muted focus:bg-coral/10 flex items-center gap-2 rounded-full border px-5 py-1 text-sm font-semibold shadow-xs transition-colors sm:text-base"
id="created-sort"
type="button"
>
@ -67,7 +67,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
</span>
</button>
<button
class="flex items-center gap-2 rounded-full border border-subtle px-5 py-1 text-sm font-semibold shadow-sm transition-colors hover:bg-muted focus:bg-coral/10 sm:text-base"
class="border-subtle hover:bg-muted focus:bg-coral/10 flex items-center gap-2 rounded-full border px-5 py-1 text-sm font-semibold shadow-xs transition-colors sm:text-base"
id="updated-sort"
type="button"
>
@ -84,7 +84,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
<label class="text-md font-semibold" for="limit">
{translations.sort.perPage}
</label>
<select class="rounded border border-dark bg-paper px-2 py-1 text-sm" id="limit">
<select class="border-dark bg-paper rounded-xs border px-2 py-1 text-sm" id="limit">
<option value="12">12</option>
<option value="24">24</option>
<option value="48">48</option>
@ -103,7 +103,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
class="mod-card flex w-full flex-col gap-4 border-transparent transition-colors duration-100 hover:opacity-90"
href={getLocalePath(`/mods/${mod.id}`)}
>
<div class="relative mb-0 block aspect-[1.85/1] h-48 overflow-hidden rounded-md border-2 border-dark object-cover shadow-md">
<div class="border-dark relative mb-0 block aspect-[1.85/1] h-48 overflow-hidden rounded-md border-2 object-cover shadow-md">
<img
alt={mod.name}
class="h-full w-full object-cover transition-transform duration-100 hover:scale-105"
@ -140,7 +140,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
<input
id="page-input"
aria-label="Page number"
class="w-16 rounded border border-dark bg-transparent px-2 py-1 text-center text-sm"
class="border-dark w-16 rounded-xs border bg-transparent px-2 py-1 text-center text-sm"
type="text"
value="1"
/>
@ -152,7 +152,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
</span>
</form>
<a
class="px-3 py-2 text-dark hover:text-gray-600"
class="text-dark px-3 py-2 hover:text-gray-600"
href={getLocalePath('/mods?page=2')}
data-page="2"
>
@ -660,7 +660,7 @@ const totalPages = Math.ceil(allMods.length / defaultLimit)
<input
id="page-input"
aria-label="Page number"
class="w-16 rounded border border-dark bg-transparent px-2 py-1 text-center text-sm"
class="w-16 rounded-xs border border-dark bg-transparent px-2 py-1 text-center text-sm"
type="text"
value="${this.state.page}"
/>

View file

@ -22,7 +22,7 @@ const {
<!-- Desktop Navigation -->
<Astronav>
<MenuItems
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"
class="bg-paper relative z-20 container grid w-full grid-cols-2 items-center gap-2 py-3 lg:grid lg:grid-cols-[auto_1fr_auto] lg:py-6"
>
<a class="flex items-center gap-2 text-lg font-bold" href={getLocalePath('/')}>
<Logo class="text-coral" />
@ -121,7 +121,7 @@ const {
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label
for="mobile-menu-toggle"
class="cursor-pointer p-2 text-dark lg:hidden"
class="text-dark cursor-pointer p-2 lg:hidden"
aria-label="Open menu"
>
<MenuIcon class="h-6 w-6" />
@ -132,29 +132,3 @@ const {
<!-- Mobile Hamburger Menu Content -->
<MobileMenu />
<style>
.navbar-dropdown {
@apply absolute left-1/2 mt-2 grid !-translate-x-1/2 !transform grid-cols-2 gap-2 rounded-lg border-2 border-dark bg-paper p-3 shadow-sm;
& .dropdown-item {
@apply flex cursor-pointer select-none flex-col gap-2 rounded-lg p-4 transition-colors duration-200;
&:hover {
@apply bg-muted;
}
& .dropdown-title {
@apply font-bold;
}
& .dropdown-description {
@apply text-sm;
}
}
}
</style>
<style is:global>
#theme-switcher * {
@apply text-dark;
}
</style>

View file

@ -115,7 +115,7 @@ generateItems(props.knownIssues, 'known')
{
isTwilight ? (
<a
class="!mb-2 block w-fit rounded-full bg-coral px-3 py-1 text-xs text-paper"
class="bg-coral text-paper !mb-2 block w-fit rounded-full px-3 py-1 text-xs"
href={getLocalePath('/download?twilight')}
>
{releaseNoteItem.twilight}
@ -142,7 +142,7 @@ generateItems(props.knownIssues, 'known')
<span class="text-muted-foreground mx-3 hidden sm:block">•</span>
<a
rel="noopener noreferrer"
class="text-xs text-coral underline decoration-wavy opacity-80"
class="text-coral text-xs underline decoration-wavy opacity-80"
href={`https://www.mozilla.org/en-US/firefox/${ffVersion}/releasenotes/`}
target="_blank"
rel="noopener noreferrer"
@ -155,7 +155,7 @@ generateItems(props.knownIssues, 'known')
<span class="text-muted-foreground mx-3 hidden sm:block">•</span>
<a
rel="noopener noreferrer"
class="zen-link whitespace-nowrap text-xs !no-underline opacity-80"
class="zen-link text-xs whitespace-nowrap !no-underline opacity-80"
target="_blank"
href={`https://github.com/zen-browser/desktop/releases/tag/${isTwilight ? 'twilight' : props.version}`}
>{releaseNoteItem.githubRelease}</a
@ -166,7 +166,7 @@ generateItems(props.knownIssues, 'known')
<span class="text-muted-foreground mx-3 hidden sm:block">•</span>
<a
rel="noopener noreferrer"
class="zen-link whitespace-nowrap text-xs !no-underline opacity-80"
class="zen-link text-xs whitespace-nowrap !no-underline opacity-80"
target="_blank"
href={`https://github.com/zen-browser/desktop/actions/runs/${props.workflowId}`}
>
@ -181,7 +181,7 @@ generateItems(props.knownIssues, 'known')
<span class="text-muted-foreground mx-3 hidden sm:block">•</span>
<a
rel="noopener noreferrer"
class="zen-link whitespace-nowrap text-xs !no-underline opacity-80"
class="zen-link text-xs whitespace-nowrap !no-underline opacity-80"
target="_blank"
href={compareLink}
>
@ -230,44 +230,4 @@ generateItems(props.knownIssues, 'known')
}
</div>
</div>
<style is:global>
.ac-accordion-item-title {
@apply !text-dark;
flex-direction: row-reverse !important;
&:hover {
opacity: 0.8 !important;
}
& > svg {
color: var(--zen-dark) !important;
}
}
.ac-accordion-item {
transition: height 0.2s ease-in-out !important;
& li {
opacity: 0.5;
}
}
.ac-accordion {
&.ac-accordion--light {
> * + * {
border-color: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1)) !important;
width: 100%;
}
}
}
.extra {
& a {
@apply !text-coral underline underline-offset-4;
}
}
.release-note-item {
border-color: light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
}
</style>
</section>

View file

@ -4,7 +4,7 @@ const { class: className } = Astro.props
---
<h1
class={cn('mb-[0.4rem] font-junicode text-5xl font-semibold leading-[0.9] text-dark', className)}
class={cn('font-junicode text-dark mb-[0.4rem] text-5xl leading-[0.9] font-semibold', className)}
>
<slot />
</h1>

View file

@ -1,4 +1,6 @@
---
import { cn } from '~/utils/merge'
type Props = {
name: string
class?: string
@ -9,7 +11,7 @@ const { name, class: className, ...rest }: Props = Astro.props
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
<video
class:list={['w-fit', className]}
class:list={cn('w-full', className)}
preload="none"
poster={`/media/${name}/poster.webp`}
{...rest}

View file

@ -21,7 +21,7 @@ const { label, href, checksum } = Astro.props
<div class="relative flex flex-col">
<a
href={href}
class="download-link group flex flex-1 items-center justify-between rounded-2xl border border-subtle p-4 transition-all duration-200 hover:border-coral hover:shadow-sm data-[twilight='true']:hover:border-zen-blue dark:hover:shadow-md"
class="download-link group border-subtle hover:border-coral data-[twilight='true']:hover:border-zen-blue flex flex-1 items-center justify-between rounded-2xl border p-4 transition-all duration-200 hover:shadow-xs dark:hover:shadow-md"
rel="noopener noreferrer"
tabindex="0"
>
@ -32,7 +32,7 @@ const { label, href, checksum } = Astro.props
<span class="group/checksum relative hidden items-center md:flex">
<button
type="button"
class="checksum-icon-btn text-muted-foreground flex items-center justify-center rounded-full p-1 transition-colors duration-150 hover:text-coral focus:outline-none focus:ring-2 focus:ring-coral data-[twilight='true']:hover:text-zen-blue data-[twilight='true']:focus:ring-zen-blue"
class="checksum-icon-btn text-muted-foreground hover:text-coral focus:ring-coral data-[twilight='true']:hover:text-zen-blue data-[twilight='true']:focus:ring-zen-blue flex items-center justify-center rounded-full p-1 transition-colors duration-150 focus:ring-2 focus:outline-hidden"
aria-label="Show SHA-256 checksum"
tabindex="0"
>
@ -50,14 +50,14 @@ const { label, href, checksum } = Astro.props
<path d="M9 12l2 2 4-4" />
</svg>
</button>
<span class="absolute -top-10 left-1/2 z-50 hidden min-w-[120px] -translate-x-1/2 select-none whitespace-nowrap rounded-md border border-subtle bg-[rgba(255,255,255,0.98)] px-3 py-2 text-xs text-gray-700 opacity-100 shadow transition-opacity duration-150 group-focus-within/checksum:hidden group-hover/checksum:flex group-focus-within/checksum:group-hover/checksum:hidden dark:bg-[rgba(24,24,27,0.98)] dark:text-gray-100">
<span class="border-subtle absolute -top-10 left-1/2 z-50 hidden min-w-[120px] -translate-x-1/2 rounded-md border bg-[rgba(255,255,255,0.98)] px-3 py-2 text-xs whitespace-nowrap text-gray-700 opacity-100 shadow-sm transition-opacity duration-150 select-none group-focus-within/checksum:hidden group-hover/checksum:flex group-focus-within/checksum:group-hover/checksum:hidden dark:bg-[rgba(24,24,27,0.98)] dark:text-gray-100">
{buttonCard.showChecksum}
</span>
<span class="checksum-tooltip popover absolute -left-14 -top-12 z-50 hidden min-w-[220px] items-center gap-2 whitespace-nowrap rounded-md border border-subtle bg-[rgba(255,255,255,0.98)] px-3 py-2 text-xs text-gray-700 opacity-100 shadow transition-opacity duration-150 group-focus-within/checksum:flex dark:bg-[rgba(24,24,27,0.98)] dark:text-gray-100">
<span class="font-mono flex-1 truncate text-xs">{checksum}</span>
<span class="checksum-tooltip popover border-subtle absolute -top-12 -left-14 z-50 hidden min-w-[220px] items-center gap-2 rounded-md border bg-[rgba(255,255,255,0.98)] px-3 py-2 text-xs whitespace-nowrap text-gray-700 opacity-100 shadow-sm transition-opacity duration-150 group-focus-within/checksum:flex dark:bg-[rgba(24,24,27,0.98)] dark:text-gray-100">
<span class="flex-1 truncate font-mono text-xs">{checksum}</span>
<button
type="button"
class="copy-btn rounded bg-coral px-2 py-1 text-xs text-white hover:bg-coral/80 data-[twilight='true']:bg-zen-blue data-[twilight='true']:hover:bg-zen-blue/80"
class="copy-btn bg-coral hover:bg-coral/80 data-[twilight='true']:bg-zen-blue data-[twilight='true']:hover:bg-zen-blue/80 rounded-xs px-2 py-1 text-xs text-white"
>
{buttonCard.copy}
</button>
@ -69,12 +69,12 @@ const { label, href, checksum } = Astro.props
<div class="flex flex-col items-end gap-2">
<div class="flex items-center gap-2">
<span
class="release-type-tag rounded-full bg-coral/10 px-2 py-1 text-xs font-medium text-coral transition-colors duration-200 group-hover:bg-coral/20 data-[twilight='true']:bg-zen-blue/10 data-[twilight='true']:text-zen-blue data-[twilight='true']:group-hover:bg-zen-blue/20"
class="release-type-tag bg-coral/10 text-coral group-hover:bg-coral/20 data-[twilight='true']:bg-zen-blue/10 data-[twilight='true']:text-zen-blue data-[twilight='true']:group-hover:bg-zen-blue/20 rounded-full px-2 py-1 text-xs font-medium transition-colors duration-200"
>
{buttonCard.beta}
</span>
<div
class="download-arrow-icon text-muted-foreground rounded-xl border border-subtle p-2 transition-colors duration-200 group-hover:border-coral group-hover:text-coral data-[twilight='true']:group-hover:border-zen-blue data-[twilight='true']:group-hover:text-zen-blue"
class="download-arrow-icon text-muted-foreground border-subtle group-hover:border-coral group-hover:text-coral data-[twilight='true']:group-hover:border-zen-blue data-[twilight='true']:group-hover:text-zen-blue rounded-xl border p-2 transition-colors duration-200"
>
<svg
width="16"

View file

@ -140,7 +140,7 @@ function isFlatReleaseInfo(obj: unknown): obj is ReleaseInfo {
</div>
</div>
<div
class="download-browser-logo flex justify-center text-coral transition-colors data-[twilight='true']:text-zen-blue md:w-1/3"
class="download-browser-logo text-coral data-[twilight='true']:text-zen-blue flex justify-center transition-colors md:w-1/3"
>
<Image src={AppIconDark} alt="Zen Browser" class="w-32 translate-y-6 transform dark:hidden" />
<Image

View file

@ -1,4 +1,6 @@
---
import '~/styles/global.css'
interface Props {
title: string
description?: string
@ -97,77 +99,10 @@ const locale = getLocale(Astro)
</script>
</head>
<body
class="min-h-[max(100dvh,_64rem)] overflow-x-hidden text-balance bg-paper font-['bricolage-grotesque'] text-dark"
class="bg-paper text-dark font-bricolage min-h-[max(100dvh,_64rem)] overflow-x-hidden text-balance"
>
<NavBar />
<slot />
<Footer />
</body>
</html>
<style is:global>
@font-face {
font-family: 'Junicode';
src: url('/fonts/JunicodeVF-Roman-subset.woff2') format('woff2');
font-display: swap;
}
@font-face {
font-family: 'Junicode-Italic';
src: url('/fonts/JunicodeVF-Italic-subset.woff2') format('woff2');
font-display: swap;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--zen-paper: #f2f0e3;
--zen-dark: #2e2e2e;
--zen-muted: rgba(0, 0, 0, 0.05);
--zen-subtle: rgba(0, 0, 0, 0.05);
&[data-theme='dark'] {
--zen-paper: #1f1f1f;
--zen-dark: #d1cfc0;
--zen-muted: rgba(255, 255, 255, 0.05);
--zen-subtle: rgba(255, 255, 255, 0.1);
}
}
html {
scroll-behavior: smooth;
}
body,
body > * {
font-family: 'Bricolage Grotesque', sans-serif;
font-optical-sizing: auto;
font-style: normal;
font-weight: 500;
font-variation-settings: 'width' 100;
}
h1 .italic {
font-family: 'Junicode-Italic', serif;
font-weight: 400;
font-feature-settings: 'swsh' 0;
font-style: normal;
}
.zen-link {
@apply text-coral underline underline-offset-4;
}
</style>
<style is:global>
/* Declare a custom CSS class to make the icon look right */
.svg-inline--fa {
overflow: visible;
box-sizing: content-box;
display: inline-block;
height: 1em;
vertical-align: -0.125em;
}
</style>

View file

@ -17,7 +17,7 @@ const {
<main
class="container flex min-h-[70vh] flex-col items-center justify-center gap-6 py-24 text-center"
>
<Title class="text-7xl font-bold text-coral md:text-9xl xl:text-9xl"> 404 </Title>
<Title class="text-coral text-7xl font-bold md:text-9xl xl:text-9xl"> 404 </Title>
<div class="flex flex-col items-center gap-6">
<Description class="text-xl md:text-2xl">
{notFound.title}

View file

@ -17,14 +17,14 @@ const {
<Layout title={layout.about.title} description={layout.about.description}>
<main class="container flex min-h-screen w-full flex-col gap-24 py-24">
<div class="flex w-full flex-col gap-6">
<Description class="text-6xl font-bold leading-none">{about.title}</Description>
<Description class="text-6xl leading-none font-bold">{about.title}</Description>
<Description class="max-w-4xl">
{about.description}
</Description>
<Button href="/donate" class="w-fit" isPrimary>{about.littleHelp}</Button>
</div>
<div class="flex w-full flex-col gap-4">
<div class="text-4xl font-bold leading-none lg:text-5xl">{about.mainTeam.title}</div>
<div class="text-4xl leading-none font-bold lg:text-5xl">{about.mainTeam.title}</div>
<Description>
{about.mainTeam.description}
</Description>
@ -55,7 +55,7 @@ const {
</div>
</div>
<div class="flex w-full flex-col gap-4">
<div class="text-4xl font-bold leading-none lg:text-5xl">{about.contributors.title}</div>
<div class="text-4xl leading-none font-bold lg:text-5xl">{about.contributors.title}</div>
<Description>
{about.contributors.description}
</Description>

View file

@ -14,7 +14,7 @@ const {
---
<Layout title={layout.donate.title} description={layout.donate.description}>
<main class="container flex flex-col items-center gap-12 pb-52 pt-24">
<main class="container flex flex-col items-center gap-12 pt-24 pb-52">
<div class="flex flex-col gap-4 lg:text-center">
<Description class="text-6xl font-bold">{donate.title}</Description>
<Description class="max-w-3xl">
@ -32,7 +32,7 @@ const {
<ArrowRightIcon class="size-4" />
</Button>
</div>
<hr class="hidden h-72 w-[1px] bg-dark opacity-15 lg:block" />
<hr class="bg-dark hidden h-72 w-[1px] opacity-15 lg:block" />
<div class="flex flex-col items-center gap-4">
<div class="text-6xl font-bold">{donate.koFi.title}</div>
<Description>

View file

@ -36,20 +36,20 @@ const platformDescriptions = download.platformDescriptions
<DownloadScript />
<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 py-12">
<div class="mb-6 mt-12 flex flex-col gap-4">
<main class="data-[os='windows']:bg-zen-blue flex min-h-screen flex-col px-6">
<div class="relative container mx-auto py-12">
<div class="mt-12 mb-6 flex flex-col gap-4">
<Description id="download-title" class="text-6xl font-bold">{download.title}</Description>
<Description class="max-w-xl text-pretty">
{download.description}
</Description>
<div
id="twilight-info"
class="hidden max-w-xl items-center justify-center gap-3 text-pretty rounded-xl border border-zen-blue/20 bg-zen-blue/5 p-4 text-left data-[twilight='true']:flex"
class="border-zen-blue/20 bg-zen-blue/5 hidden max-w-xl items-center justify-center gap-3 rounded-xl border p-4 text-left text-pretty data-[twilight='true']:flex"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="mt-0.5 h-5 w-5 flex-shrink-0 text-zen-blue"
class="text-zen-blue mt-0.5 h-5 w-5 shrink-0"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
@ -68,10 +68,10 @@ const platformDescriptions = download.platformDescriptions
<!-- Platform selector -->
<div class="mb-6 flex">
<div
class="inline-flex rounded-3xl bg-[rgba(255,255,255,0.4)] p-2 shadow-md dark:bg-[rgba(0,0,0,0.3)] dark:shadow-sm"
class="inline-flex rounded-3xl bg-[rgba(255,255,255,0.4)] p-2 shadow-md dark:bg-[rgba(0,0,0,0.3)] dark:shadow-xs"
>
<button
class="platform-selector rounded-2xl px-5 py-2.5 transition-all duration-200 data-[active='true']:bg-subtle"
class="platform-selector data-[active='true']:bg-subtle rounded-2xl px-5 py-2.5 transition-all duration-200"
data-platform="mac"
>
<span class="flex items-center gap-2">
@ -80,7 +80,7 @@ const platformDescriptions = download.platformDescriptions
</span>
</button>
<button
class="platform-selector rounded-2xl px-5 py-2.5 transition-all duration-200 data-[active='true']:bg-subtle"
class="platform-selector data-[active='true']:bg-subtle rounded-2xl px-5 py-2.5 transition-all duration-200"
data-platform="windows"
>
<span class="flex items-center gap-2">
@ -89,7 +89,7 @@ const platformDescriptions = download.platformDescriptions
</span>
</button>
<button
class="platform-selector rounded-2xl px-5 py-2.5 transition-all duration-200 data-[active='true']:bg-subtle"
class="platform-selector data-[active='true']:bg-subtle rounded-2xl px-5 py-2.5 transition-all duration-200"
data-platform="linux"
>
<span class="flex items-center gap-2">
@ -152,10 +152,10 @@ const platformDescriptions = download.platformDescriptions
</p>
</div>
<div
class="grid aspect-square h-12 w-12 place-items-center rounded-xl border border-subtle transition-all duration-100 hover:bg-coral hover:bg-opacity-10 group-hover:border-coral group-hover:border-opacity-10"
class="border-subtle hover:bg-coral/10 group-hover:border-coral/10 grid aspect-square h-12 w-12 place-items-center rounded-xl border transition-all duration-100"
>
<div
class="text-muted-foreground transition-all duration-200 group-hover:text-coral"
class="text-muted-foreground group-hover:text-coral transition-all duration-200"
>
<Fragment set:html={githubIcon.html} />
</div>
@ -177,10 +177,10 @@ const platformDescriptions = download.platformDescriptions
</p>
</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="border-subtle hover:bg-coral/10 group-hover:border-coral/20 rounded-xl border p-3 transition-all duration-100"
>
<ExternalLinkIcon
class="h-5 w-5 transition-all duration-200 group-hover:text-coral"
class="group-hover:text-coral h-5 w-5 transition-all duration-200"
/>
</div>
</div>
@ -189,8 +189,8 @@ const platformDescriptions = download.platformDescriptions
</section>
<!-- Security Notice -->
<div class="grid grid-cols-[auto,1fr] gap-4 rounded-2xl bg-subtle bg-opacity-10 p-6">
<div class="h-fit rounded-xl bg-subtle p-3">
<div class="bg-subtle grid grid-cols-[auto_1fr] gap-4 rounded-2xl p-6">
<div class="bg-subtle h-fit rounded-xl p-3">
<LockIcon class="h-5 w-5" />
</div>
@ -204,23 +204,3 @@ const platformDescriptions = download.platformDescriptions
</div>
</main>
</Layout>
<style is:global>
/* Download card icon */
.download-card__icon {
@apply flex h-10 w-10 items-center justify-center rounded-full bg-subtle p-2 text-coral data-[twilight='true']:text-zen-blue;
}
/* Make FontAwesome icons match size */
.download-card__icon svg {
width: 1.5rem;
height: 1.5rem;
}
</style>
<style is:global>
.os-icon svg {
height: 3rem;
width: 3rem;
}
</style>

View file

@ -20,18 +20,3 @@ const { layout } = getUI(locale)
<Community />
</main>
</Layout>
<style>
@keyframes headerSlideIn {
0% {
transform: translateY(100%);
}
100% {
transform: translateY(0);
}
}
#header-browser-image {
animation: headerSlideIn 0.5s ease-in-out;
}
</style>
<script></script>

View file

@ -61,7 +61,7 @@ const {
ogImage={mod.image}
>
<main class="container mt-6 2xl:mt-0">
<div class="mx-auto mb-24 mt-12 flex flex-col gap-6 lg:mt-32">
<div class="mx-auto mt-12 mb-24 flex flex-col gap-6 lg:mt-32">
<div
id="install-theme-error"
class="flex flex-col items-center justify-center gap-2 rounded-xl bg-red-200 p-2 pl-4 md:flex-row md:justify-between dark:bg-red-700"
@ -74,7 +74,7 @@ const {
</div>
<Button
href="/download"
class="inline-flex flex-shrink-0 whitespace-nowrap !rounded-lg bg-red-300 dark:bg-red-800"
class="inline-flex shrink-0 !rounded-lg bg-red-300 whitespace-nowrap dark:bg-red-800"
isAlert
>
{slug.alert.button}
@ -89,10 +89,10 @@ const {
<img
src={mod.image}
alt={mod.name}
class="h-full w-full rounded-xl border-2 border-dark object-cover shadow"
class="border-dark object-cover-sm h-full w-full rounded-xl border-2"
/>
<div class="flex flex-col justify-between gap-2 sm:flex-row">
<div class="flex flex-shrink-0 flex-col gap-2 font-normal">
<div class="flex shrink-0 flex-col gap-2 font-normal">
<p
set:html={slug.createdBy
.replace(
@ -134,8 +134,8 @@ const {
-->
</div>
<div></div>
</main></Layout
>
</main>
</Layout>
<script>
const backButton = document.getElementById('back-button') as HTMLAnchorElement

View file

@ -19,7 +19,7 @@ const allMods = (await getAllMods()) || []
<Layout title={layout.mods.title}>
<main class="container mt-32 flex flex-col gap-10 2xl:mt-32">
<header class="flex w-full flex-col gap-8 border-dark">
<header class="border-dark flex w-full flex-col gap-8">
<Description class="text-6xl font-bold">{mods.title}</Description>
<Description class="max-w-3xl">
{mods.description}

View file

@ -13,7 +13,9 @@ const {
---
<Layout title={layout.privacyPolicy.title} description={layout.privacyPolicy.description}>
<main class="mx-auto mt-52 w-1/2 pb-24">
<main
class="mx-auto mt-52 w-1/2 pb-24 [&_li]:ml-4 [&_li]:list-disc [&_p,li]:opacity-55 [&_ul]:mt-4"
>
<Title id="privacy-policy" class="xl:text-6xl">{privacyPolicy.title}</Title>
<div class="ml-4 font-bold">{privacyPolicy.lastUpdated}</div>
<Title class="mt-16 text-4xl font-bold" id="introduction">
@ -153,17 +155,3 @@ const {
</ul>
</main>
</Layout>
<style>
p,
li {
@apply opacity-55;
}
ul {
@apply mt-4;
}
li {
@apply ml-4 list-disc;
}
</style>

View file

@ -30,7 +30,7 @@ const release = Astro.props
---
<Layout title={slug.title} redirect={`/release-notes#${release.version}`}>
<main class="flex flex-col items-center pb-52 pt-36">
<main class="flex flex-col items-center pt-36 pb-52">
{slug.redirect.replaceAll('{version}', release.version)}
</main>
</Layout>

View file

@ -21,7 +21,7 @@ const {
<main
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 w-full flex-col justify-center gap-8">
<div id="release-notes" class="flex min-h-screen w-full flex-col justify-center gap-8 py-42">
<Description class="mt-48 text-6xl font-bold">{releaseNotes.topSection.title}</Description>
<p
class="text-base opacity-55"
@ -46,7 +46,7 @@ const {
{releaseNotesData.map(notes => <ReleaseNoteItem {...notes} />)}
</div>
</main>
<Button id="scroll-top" isPrimary class="fixed bottom-8 right-8" onclick="window.scrollTo(0, 0)">
<Button id="scroll-top" isPrimary class="fixed right-8 bottom-8" onclick="window.scrollTo(0, 0)">
<p class="hidden items-center gap-2 sm:flex">
{releaseNotes.backToTop}
<ArrowUpIcon aria-hidden="true" class="size-4" />
@ -54,17 +54,17 @@ const {
<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">
<Modal id="version-modal" class="!bg-paper m-auto border border-[--zen-dark]">
<ModalHeader class="border-b border-[--zen-dark]">
<p class="text-4xl font-bold text-dark">{releaseNotes.chooseVersion}</p>
<p class="text-dark text-4xl font-bold">{releaseNotes.chooseVersion}</p>
</ModalHeader>
<ModalBody>
<div id="version-list" class="flex flex-col gap-2 text-xl text-dark">
<div id="version-list" class="text-dark flex flex-col gap-2 text-xl">
{
releaseNotesData.map(note => (
<button
aria-label={`Navigate to version ${note.version}`}
class="w-full text-left transition-colors duration-150 hover:text-coral"
class="hover:text-coral w-full text-left transition-colors duration-150"
data-version={note.version}
>
{note.version}
@ -131,9 +131,3 @@ const {
}
})
</script>
<style is:global>
#version-modal > * {
font-family: 'Bricolage Grotesque', sans-serif !important;
}
</style>

View file

@ -28,7 +28,7 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
<Layout title={layout.whatsNew.title.replace('{latestVersion.version}', latestVersion.version)}>
<main
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]"
class="container flex flex-col gap-12 py-12 xl:mt-22 xl:grid xl:min-h-[calc(100vh-12rem)] xl:grid-cols-[2fr_3fr]"
>
<div class="flex flex-col gap-8">
<div>

255
src/styles/global.css Normal file
View file

@ -0,0 +1,255 @@
@import 'tailwindcss';
@font-face {
font-family: 'Junicode';
src: url('/fonts/JunicodeVF-Roman-subset.woff2') format('woff2');
font-display: swap;
}
@font-face {
font-family: 'Junicode-Italic';
src: url('/fonts/JunicodeVF-Italic-subset.woff2') format('woff2');
font-display: swap;
}
@theme {
--breakpoint-sm: 640px;
--breakpoint-md: 768px;
--breakpoint-lg: 1024px;
--breakpoint-xl: 1280px;
--color-paper: #f2f0e3;
--color-coral: #f76f53;
--color-dark: #2e2e2e;
--color-subtle: rgba(0, 0, 0, 0.05);
--color-muted: rgba(0, 0, 0, 0.05);
--color-zen-blue: #6287f5;
--color-zen-green: #63f78b;
--font-junicode: 'Junicode, serif';
--font-junicode-italic: 'Junicode-Italic, serif';
--font-junicode--font-feature-settings: 'swsh' 1;
--font-bricolage: 'Bricolage Grotesque', sans-serif;
--font-bricolage--font-variation-settings: 'wdth' 100;
--default-font-family: var(--font-bricolage);
--animate-fade-in: fadeIn 2s ease-in-out;
--animate-breathe: breathe 5s ease-in-out infinite;
--animate-header-slide-in: headerSlideIn 0.5s ease-in-out;
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes breathe {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
}
@keyframes headerSlideIn {
0% {
transform: translateY(100%);
}
100% {
transform: translateY(0);
}
}
}
html {
scroll-behavior: smooth;
}
body,
body > * {
font-family: 'Bricolage Grotesque', sans-serif;
font-optical-sizing: auto;
font-style: normal;
font-weight: 500;
font-variation-settings: 'wdth' 100;
}
h1 .italic {
font-family: 'Junicode-Italic', serif;
font-weight: 400;
font-feature-settings: 'swsh' 0;
font-style: normal;
}
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
@layer base {
@variant dark {
--color-paper: #1f1f1f;
--color-dark: #d1cfc0;
--color-subtle: rgba(255, 255, 255, 0.1);
--color-muted: rgba(255, 255, 255, 0.05);
}
}
@utility container {
@apply mx-auto w-full px-4;
@media (min-width: 100%) {
@apply w-full max-w-full px-4;
}
@variant sm {
@apply w-full max-w-full;
}
@variant md {
@apply w-full max-w-256;
}
@variant lg {
@apply w-full max-w-256 px-6;
}
@variant xl {
@apply w-full max-w-320 px-8;
}
}
@layer components {
#theme-switcher * {
@apply text-dark;
}
#version-modal > * {
@apply font-bricolage!;
}
.zen-link {
@apply text-coral underline underline-offset-4;
}
.ac-accordion-item-title {
@apply !text-dark [&>svg]:text-dark! flex-row-reverse! hover:opacity-80!;
}
.ac-accordion-item {
@apply transition-[height]! duration-200! ease-in-out! [&>li]:opacity-50!;
}
.ac-accordion {
&.ac-accordion--light {
> * + * {
@apply w-full;
border-color: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1)) !important;
}
}
}
.extra {
& a {
@apply !text-coral underline underline-offset-4;
}
}
.release-note-item {
border-color: light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
}
.svg-inline--fa {
@apply box-border inline-block h-4 overflow-visible align-[-0.125em];
}
/* Download card icon */
.download-card__icon {
@apply bg-subtle text-coral data-[twilight='true']:text-zen-blue flex h-10 w-10 items-center justify-center rounded-full p-2;
}
/* Make FontAwesome icons match size */
.download-card__icon svg {
@apply h-6 w-6;
}
.os-icon svg {
@apply h-12 w-12;
}
.navbar-dropdown {
@apply border-dark bg-paper absolute left-1/2 mt-2 grid !-translate-x-1/2 !transform grid-cols-2 gap-2 rounded-lg border-2 p-3 shadow-xs;
& .dropdown-item {
@apply flex cursor-pointer flex-col gap-2 rounded-lg p-4 transition-colors duration-200 select-none;
&:hover {
@apply bg-muted;
}
& .dropdown-title {
@apply font-bold;
}
& .dropdown-description {
@apply text-sm;
}
}
}
.feature {
@apply hover:bg-subtle w-full cursor-pointer rounded-lg p-4 opacity-0 select-none;
transition: background 0.2s ease-in-out;
&[data-active='true'] {
@apply bg-subtle;
}
}
.feature-tab {
@apply hover:bg-subtle rounded-lg px-4 py-2 text-lg font-medium opacity-0;
transition: background 0.2s ease-in-out;
&[data-active='true'] {
@apply bg-subtle;
}
}
.feature-description {
@apply px-4 text-sm;
}
.video-stack {
@apply aspect-video;
perspective: 2000px;
transform-style: preserve-3d;
}
.feature-video {
@apply left-1/2 hidden transform rounded-3xl shadow-md lg:absolute lg:mx-auto lg:block lg:w-full dark:opacity-80;
max-width: 800px;
transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
position: absolute;
top: 0;
transform-origin: top center;
backface-visibility: hidden;
will-change: transform, opacity;
transform: translate3d(-50%, 0, -100px) scale(0.95);
}
/* Don't animate translation on small screens */
@media (max-width: 1024px) {
.feature-video {
@apply absolute inset-0 hidden size-full transform-none! object-cover opacity-0;
&[data-active='true'] {
@apply block opacity-100;
}
}
.video-stack {
@apply relative aspect-video w-full overflow-hidden rounded-xl;
}
}
}

View file

@ -1,64 +0,0 @@
/** @type {import('tailwindcss').Config} */
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)',
'-md': '@media (max-width: 767px)',
'-lg': '@media (max-width: 1023px)',
},
colors: {
paper: 'var(--zen-paper)',
coral: '#F76F53',
dark: 'var(--zen-dark)',
subtle: 'var(--zen-subtle)',
muted: 'var(--zen-muted)',
'zen-blue': '#6287f5',
'zen-green': '#63f78b',
},
keyframes: {
fadeIn: {
'0%': { opacity: 0 },
'100%': { opacity: 1 },
},
breathe: {
'50%': { transform: 'scale(1.2)' },
'0%, 100%': { transform: 'scale(1)' },
},
},
animation: {
fadeIn: 'fadeIn 2s ease-in-out',
breathe: 'breathe 5s ease-in-out infinite',
},
},
},
plugins: [],
}