mirror of
https://github.com/zen-browser/www.git
synced 2025-07-07 17:05:32 +02:00
feat: integrate React support and add AnimatedText component for enhanced animations
This commit is contained in:
parent
4059cfb764
commit
aa5c4f6ad0
10 changed files with 319 additions and 42 deletions
|
@ -2,7 +2,9 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
|
||||
import react from '@astrojs/react';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [tailwind()],
|
||||
});
|
||||
integrations: [tailwind(), react()],
|
||||
});
|
143
package-lock.json
generated
143
package-lock.json
generated
|
@ -10,21 +10,26 @@
|
|||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/cloudflare": "^12.0.1",
|
||||
"@astrojs/react": "^4.1.0",
|
||||
"@astrojs/tailwind": "^5.1.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",
|
||||
"@types/react": "^19.0.1",
|
||||
"@types/react-dom": "^19.0.2",
|
||||
"astro": "^5.0.4",
|
||||
"astro-navbar": "^2.3.7",
|
||||
"autoprefixer": "10.4.14",
|
||||
"free-astro-components": "^1.1.1",
|
||||
"lucide-astro": "^0.460.0",
|
||||
"motion": "^11.13.1",
|
||||
"motion": "^11.13.5",
|
||||
"postcss": "8.4.21",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"prettier-plugin-tailwindcss": "^0.6.6",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"sharp": "^0.33.5",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"typescript": "^5.6.3"
|
||||
|
@ -569,6 +574,25 @@
|
|||
"node": "^18.17.1 || ^20.3.0 || >=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@astrojs/react": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@astrojs/react/-/react-4.1.0.tgz",
|
||||
"integrity": "sha512-8F0ncvcCexVeQZMwPouLSFuzCK1KXUIYQ57lW3ZG2p7B5DGAajXGanb/CGF7MMSpX8Z0t9sELQqLHOCV/+78Ig==",
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"ultrahtml": "^1.5.3",
|
||||
"vite": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1 || ^20.3.0 || >=22.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0",
|
||||
"@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0",
|
||||
"react": "^17.0.2 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@astrojs/tailwind": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@astrojs/tailwind/-/tailwind-5.1.2.tgz",
|
||||
|
@ -901,6 +925,34 @@
|
|||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-react-jsx-self": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
|
||||
"integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-react-jsx-source": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
|
||||
"integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
|
||||
|
@ -2466,6 +2518,22 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.1.tgz",
|
||||
"integrity": "sha512-YW6614BDhqbpR5KtUYzTA+zlA7nayzJRA9ljz9CQoxthR0sDisYZLuvSMsil36t4EH/uAt8T52Xb4sVw17G+SQ==",
|
||||
"dependencies": {
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dom": {
|
||||
"version": "19.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.2.tgz",
|
||||
"integrity": "sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==",
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/unist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
||||
|
@ -2476,6 +2544,24 @@
|
|||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
|
||||
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
|
||||
},
|
||||
"node_modules/@vitejs/plugin-react": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
|
||||
"integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.26.0",
|
||||
"@babel/plugin-transform-react-jsx-self": "^7.25.9",
|
||||
"@babel/plugin-transform-react-jsx-source": "^7.25.9",
|
||||
"@types/babel__core": "^7.20.5",
|
||||
"react-refresh": "^0.14.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/kit": {
|
||||
"version": "2.4.10",
|
||||
"resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.4.10.tgz",
|
||||
|
@ -3305,6 +3391,11 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/data-uri-to-buffer": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz",
|
||||
|
@ -3687,9 +3778,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/framer-motion": {
|
||||
"version": "11.13.1",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.13.1.tgz",
|
||||
"integrity": "sha512-F40tpGTHByhn9h3zdBQPcEro+pSLtzARcocbNqAyfBI+u9S+KZuHH/7O9+z+GEkoF3eqFxfvVw0eBDytohwqmQ==",
|
||||
"version": "11.13.5",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.13.5.tgz",
|
||||
"integrity": "sha512-rArI0zPU9VkpS3Wt0J7dmRxAFUWtzPWoSofNQAP0UO276CmJ+Xlf5xN19GMw3w2QsdrS2sU+0+Q2vtuz4IEZaw==",
|
||||
"dependencies": {
|
||||
"motion-dom": "^11.13.0",
|
||||
"motion-utils": "^11.13.0",
|
||||
|
@ -3697,8 +3788,8 @@
|
|||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/is-prop-valid": "*",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
"react": "^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/is-prop-valid": {
|
||||
|
@ -5608,11 +5699,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/motion": {
|
||||
"version": "11.13.1",
|
||||
"resolved": "https://registry.npmjs.org/motion/-/motion-11.13.1.tgz",
|
||||
"integrity": "sha512-64+QpZQv8WJJFn+tEEzX04il9s6ReA6lhKRZaxzD6SunGqoaq5g+AFVfcKWme8N83eytUOpGp7mpfJ9cyZlhAA==",
|
||||
"version": "11.13.5",
|
||||
"resolved": "https://registry.npmjs.org/motion/-/motion-11.13.5.tgz",
|
||||
"integrity": "sha512-zmX/dz60w1ZtQB5NP9xYkLcCKwX9gc+pnHp4/mFhD9YW8wUe2ZmT8OPOtrTtq26/huxElSDu3hB7BMTSJa5iIQ==",
|
||||
"dependencies": {
|
||||
"framer-motion": "^11.13.1",
|
||||
"framer-motion": "^11.13.5",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -6326,6 +6417,33 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
|
||||
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",
|
||||
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
|
||||
"dependencies": {
|
||||
"scheduler": "^0.25.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.14.2",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
||||
"integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
|
@ -6757,6 +6875,11 @@
|
|||
"suf-log": "^2.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz",
|
||||
"integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="
|
||||
},
|
||||
"node_modules/section-matter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
|
||||
|
|
|
@ -13,21 +13,26 @@
|
|||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/cloudflare": "^12.0.1",
|
||||
"@astrojs/react": "^4.1.0",
|
||||
"@astrojs/tailwind": "^5.1.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",
|
||||
"@types/react": "^19.0.1",
|
||||
"@types/react-dom": "^19.0.2",
|
||||
"astro": "^5.0.4",
|
||||
"astro-navbar": "^2.3.7",
|
||||
"autoprefixer": "10.4.14",
|
||||
"free-astro-components": "^1.1.1",
|
||||
"lucide-astro": "^0.460.0",
|
||||
"motion": "^11.13.1",
|
||||
"motion": "^11.13.5",
|
||||
"postcss": "8.4.21",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"prettier-plugin-tailwindcss": "^0.6.6",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"sharp": "^0.33.5",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"typescript": "^5.6.3"
|
||||
|
|
98
src/components/AnimatedText.tsx
Normal file
98
src/components/AnimatedText.tsx
Normal file
|
@ -0,0 +1,98 @@
|
|||
import { motion, useInView, useAnimation } from "motion/react";
|
||||
import { useEffect, useRef, type JSX } from "react";
|
||||
|
||||
type AnimatedTextProps = {
|
||||
text: string | string[];
|
||||
el?: keyof JSX.IntrinsicElements;
|
||||
className?: string;
|
||||
once?: boolean;
|
||||
repeatDelay?: number;
|
||||
animation?: {
|
||||
hidden: any;
|
||||
visible: any;
|
||||
};
|
||||
};
|
||||
|
||||
const defaultAnimations = {
|
||||
hidden: {
|
||||
opacity: 0,
|
||||
y: 20,
|
||||
},
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
duration: 0.1,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const AnimatedText = ({
|
||||
text,
|
||||
el: Wrapper = "p",
|
||||
className,
|
||||
once,
|
||||
repeatDelay,
|
||||
animation = defaultAnimations,
|
||||
}: AnimatedTextProps) => {
|
||||
const controls = useAnimation();
|
||||
const textArray = Array.isArray(text) ? text : [text];
|
||||
const ref = useRef(null);
|
||||
const isInView = useInView(ref, { amount: 0.5, once });
|
||||
|
||||
useEffect(() => {
|
||||
let timeout: NodeJS.Timeout;
|
||||
const show = () => {
|
||||
controls.start("visible");
|
||||
if (repeatDelay) {
|
||||
timeout = setTimeout(async () => {
|
||||
await controls.start("hidden");
|
||||
controls.start("visible");
|
||||
}, repeatDelay);
|
||||
}
|
||||
};
|
||||
|
||||
if (isInView) {
|
||||
show();
|
||||
} else {
|
||||
controls.start("hidden");
|
||||
}
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}, [isInView]);
|
||||
|
||||
return (
|
||||
<Wrapper className={className}>
|
||||
<span className="sr-only">{textArray.join(" ")}</span>
|
||||
<motion.span
|
||||
ref={ref}
|
||||
initial="hidden"
|
||||
animate={controls}
|
||||
variants={{
|
||||
visible: { transition: { staggerChildren: 0.1 } },
|
||||
hidden: {},
|
||||
}}
|
||||
aria-hidden
|
||||
>
|
||||
{textArray.map((line, lineIndex) => (
|
||||
<span className="block" key={`${line}-${lineIndex}`}>
|
||||
{line.split(" ").map((word, wordIndex) => (
|
||||
<span className="inline-block" key={`${word}-${wordIndex}`}>
|
||||
{word.split("").map((char, charIndex) => (
|
||||
<motion.span
|
||||
key={`${char}-${charIndex}`}
|
||||
className="inline-block"
|
||||
variants={animation}
|
||||
>
|
||||
{char}
|
||||
</motion.span>
|
||||
))}
|
||||
<span className="inline-block"> </span>
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
))}
|
||||
</motion.span>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
|
@ -13,7 +13,7 @@ import {
|
|||
|
||||
<section
|
||||
id="Community"
|
||||
class="flex min-h-screen w-full flex-col items-center text-center relative"
|
||||
class="flex w-full flex-col items-center text-center relative"
|
||||
>
|
||||
<Title>Community Driven</Title>
|
||||
<Description class="px-4 lg:px-0 lg:w-1/2">
|
||||
|
|
|
@ -4,7 +4,23 @@ import Description from '../components/Description.astro'
|
|||
import Button from '../components/Button.astro'
|
||||
import { Image } from 'astro:assets'
|
||||
import myImage from '../assets/browser.png'
|
||||
import { ArrowRight } from 'lucide-astro'
|
||||
import { ArrowRight } from 'lucide-astro';
|
||||
import { motion } from 'framer-motion';
|
||||
import { AnimatedText } from './AnimatedText';
|
||||
|
||||
let titleAnimationCounter = 0;
|
||||
function getNewAnimationDelay() {
|
||||
titleAnimationCounter++;
|
||||
return titleAnimationCounter * 0.15;
|
||||
}
|
||||
|
||||
function getTitleAnimation() {
|
||||
return {
|
||||
initial: { opacity: 0, translateY: 20, filter: 'blur(4px)' },
|
||||
animate: { opacity: 1, translateY: 0, filter: 'blur(0px)', transition: { duration: 0.3, delay: getNewAnimationDelay() } },
|
||||
};
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
<header
|
||||
|
@ -12,18 +28,43 @@ import { ArrowRight } from 'lucide-astro'
|
|||
class="flex py-56 min-h-screen w-full flex-col items-center gap-24 text-center gap-[20%] lg:gap-[15%]"
|
||||
>
|
||||
<div class="flex flex-col items-center h-full justify-center">
|
||||
<Title class='text-left px-12 lg:px-0 lg:text-center leading-[108px] md:!text-9xl !font-normal'>Welcome to<br class="hidden md:block" /> a <span class="italic">calmer</span> internet</Title>
|
||||
<Description class='text-left px-12 lg:px-0 lg:text-center'
|
||||
>Beautifully designed, privacy-focused, and packed with features.<br
|
||||
/>We care about your experience, not your data.</Description
|
||||
>
|
||||
<Title class='text-left px-12 lg:px-0 lg:text-center leading-[108px] md:!text-9xl !font-normal'>
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
Welcome
|
||||
</motion.span>
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
to
|
||||
</motion.span>
|
||||
<br class="hidden md:block" />
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
a
|
||||
</motion.span>
|
||||
<motion.span client:load {...getTitleAnimation()} className='italic'>
|
||||
calmer
|
||||
</motion.span>
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
internet
|
||||
</motion.span>
|
||||
</Title>
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
<Description class='text-left px-12 lg:px-0 lg:text-center'
|
||||
>Beautifully designed, privacy-focused, and packed with features.<br
|
||||
/>We care about your experience, not your data.</Description
|
||||
>
|
||||
</motion.span>
|
||||
<div class="mt-6 gap-3 sm:gap-6 flex flex-row">
|
||||
<Button href="/download" isPrimary>
|
||||
Download
|
||||
<ArrowRight class="size-4" />
|
||||
</Button>
|
||||
<Button href="#features">Start Exploring</Button>
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
<Button href="/download" isPrimary>
|
||||
Download
|
||||
<ArrowRight class="size-4" />
|
||||
</Button>
|
||||
</motion.span>
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
<Button href="#features">Start Exploring</Button>
|
||||
</motion.span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<Image src={myImage} alt="Zen browser" class="top-full -translate-y-[20%] mx-auto" />
|
||||
<motion.span client:load {...getTitleAnimation()}>
|
||||
<Image src={myImage} alt="Zen browser" class="top-full -translate-y-[20%] mx-auto" />
|
||||
</motion.span>
|
|
@ -4,16 +4,16 @@ import Title from '../components/Title.astro'
|
|||
import Description from '../components/Description.astro'
|
||||
import Button from '../components/Button.astro'
|
||||
import { Astronav, MenuItems, MenuIcon, Dropdown, DropdownItems, DropdownSubmenu } from "astro-navbar";
|
||||
import { ArrowRight, ChevronDown } from 'lucide-astro'
|
||||
import { ArrowRight, ChevronDown, Download, DownloadCloud } from 'lucide-astro'
|
||||
import Logo from './Logo.astro';
|
||||
---
|
||||
|
||||
<nav
|
||||
id="nav-bar"
|
||||
class="fixed flex justify-between w-full items-center pt-6 px-6 z-10 top-0 left-0"
|
||||
class="fixed flex justify-between w-full items-center lg:pt-6 lg:px-6 z-10 top-0 left-0"
|
||||
>
|
||||
<Astronav>
|
||||
<MenuItems class="w-fit rounded-full border-dark border-2 p-2 backdrop-blur-2xl bg-paper dark:bg-paper dark:shadow-md mx-auto flex gap-2 lg:gap-20">
|
||||
<MenuItems class="w-fit lg:rounded-full border-dark border-b-2 lg:border-2 p-2 backdrop-blur-2xl bg-paper dark:bg-paper dark:shadow-md mx-auto flex gap-2 lg:gap-20">
|
||||
<a class="font-bold text-lg items-center flex gap-2" href="/">
|
||||
<Logo class="text-dark" /> <span class="hidden lg:block">zen browser</span>
|
||||
</a>
|
||||
|
@ -24,7 +24,7 @@ import Logo from './Logo.astro';
|
|||
<ChevronDown class="group-open:rotate-180 transform transition-transform duration-200" />
|
||||
</button>
|
||||
<DropdownItems>
|
||||
<div class="navbar-dropdown top-16 left-0 right-1/4">
|
||||
<div class="navbar-dropdown w-full lg:w-fit top-16 left-0 right-1/4">
|
||||
<a class="dropdown-item row-span-2 bg-dark/5" href="/mods">
|
||||
<div class="dropdown-title">
|
||||
Zen Mods
|
||||
|
@ -62,7 +62,7 @@ import Logo from './Logo.astro';
|
|||
<ChevronDown class="group-open:rotate-180 transform transition-transform duration-200" />
|
||||
</button>
|
||||
<DropdownItems>
|
||||
<div class="navbar-dropdown !grid-cols-1 gap-1 top-16 left-1/3 right-1/4">
|
||||
<div class="navbar-dropdown w-full lg:w-fit left-0 !grid-cols-1 gap-1 top-16 lg:left-1/3 lg:right-1/4">
|
||||
<a class="dropdown-item" href="/donate">
|
||||
<div class="dropdown-title">
|
||||
Donate ❤️
|
||||
|
@ -98,13 +98,18 @@ import Logo from './Logo.astro';
|
|||
</div>
|
||||
</DropdownItems>
|
||||
</Dropdown>
|
||||
<a class="flex items-center" href="/mods">
|
||||
<a class="flex items-center hidden lg:block" href="/mods">
|
||||
<span>Mods</span>
|
||||
</a>
|
||||
</div>
|
||||
<Button href="/download" isPrimary>
|
||||
Download
|
||||
<ArrowRight class="size-4" />
|
||||
<span class="hidden lg:block">
|
||||
Download
|
||||
<ArrowRight class="size-4" />
|
||||
</span>
|
||||
<span class="lg:hidden">
|
||||
<Download class="size-4" />
|
||||
</span>
|
||||
</Button>
|
||||
</MenuItems>
|
||||
</Astronav>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
---
|
||||
const { class: className } = Astro.props
|
||||
const { class: className } = Astro.props;
|
||||
---
|
||||
|
||||
<h1 class:list={["text-dark", className]}>
|
||||
<h1 class:list={["title text-dark", className]}>
|
||||
<slot />
|
||||
</h1>
|
||||
<style>
|
||||
h1 {
|
||||
.title {
|
||||
line-height: 0.9;
|
||||
margin-bottom: 0.4rem;
|
||||
font-family: 'Junicode', serif;
|
||||
|
@ -14,6 +14,6 @@ const { class: className } = Astro.props
|
|||
font-style: normal;
|
||||
font-feature-settings: 'swsh' 1;
|
||||
|
||||
@apply text-4xl lg:text-5xl xl:text-6xl;
|
||||
@apply text-5xl xl:text-6xl;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -74,8 +74,7 @@ import Footer from "../components/Footer.astro";
|
|||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
*:not(h1) > * {
|
||||
font-size: 18px;
|
||||
body, body > * {
|
||||
font-family: "Bricolage Grotesque", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-style: normal;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/strict"
|
||||
}
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "react"
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue