diff --git a/public/floorp.png b/public/floorp.png new file mode 100644 index 0000000..8d0f295 Binary files /dev/null and b/public/floorp.png differ diff --git a/public/librewolf.png b/public/librewolf.png new file mode 100644 index 0000000..186866b Binary files /dev/null and b/public/librewolf.png differ diff --git a/src/components/features.tsx b/src/components/features.tsx index 3b0f377..473d670 100644 --- a/src/components/features.tsx +++ b/src/components/features.tsx @@ -4,104 +4,98 @@ import Feature, { FeatureCard } from "./feature"; import { Button } from "./ui/button"; import TextReveal from "./ui/text-reveal"; import styled, { css, keyframes } from "styled-components"; -import BlurFade from "./ui/blur-fade"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from './ui/table'; +import { CheckIcon, XIcon } from "lucide-react"; +import { QuestionMarkIcon } from "@radix-ui/react-icons"; -const profileColors = [ - "#e8cd7d", - "#C2E3B7", - "#EEDBF9", -]; +function Checkmark() { + return +} -const enterAnimation = keyframes` - from { - opacity: 0; - transform: translate(-50%, -50%) scale(0.5); - left: 100%; - } +function Cross() { + return +} - to { - opacity: 1; - transform: translate(-50%, -50%) scale(1); - left: 50%; - } -`; - -const exitAnimation = keyframes` - from { - opacity: 1; - transform: translate(-50%, -50%) scale(1); - left: 50%; - } - - to { - opacity: 0; - transform: translate(-50%, -50%) scale(0.5); - left: 0; - } -`; - -const ProfileImage = styled.img<{ enter: boolean }>` - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - width: 75%; - animation: ${({ enter }: any) => enter ? css`${enterAnimation} 0.5s` : css`${exitAnimation} 0.5s`} forwards; -`; +function Question() { + return +} export default function Features() { - const [currentProfileColor, setCurrentProfileColor] = useState(profileColors[0]); - const [profile1Enter, setProfile1Enter] = useState(false); - const [profile2Enter, setProfile2Enter] = useState(false); - const [profile3Enter, setProfile3Enter] = useState(false); - - useEffect(() => { - let currentProfile = 0; - setProfile1Enter(true); - setCurrentProfileColor(profileColors[currentProfile]); - - const profiles = document.querySelectorAll("#profile-1, #profile-2, #profile-3"); - setInterval(() => { - currentProfile = (currentProfile + 1) % profiles.length; - setProfile1Enter(currentProfile === 0); - setProfile2Enter(currentProfile === 1); - setProfile3Enter(currentProfile === 2); - setCurrentProfileColor(profileColors[currentProfile]); - }, 2500); - }, []); return (
{/**/} - - - Split Views - - - - - Split Views - - - - - - - - - +
+
+
+
+
+
+
+
+
+
+
+

Packed with features

+
+ + + + How Zen differs from other browsers + Zen + Floorp + LibreWolf + + + + + Contain fine-grained security measures like sandboxing + + + + + + Optimized for peak performance + + + + + + Customizable with cutting-edge features + + + + + + Based on the latest version of Firefox + + + + + + Updated regularly with new features and latest security patches + + + + + + Open-source + + + + + +
+
+

Want more?

Zen Browser is packed with features that will change the way you browse the web. Download it today and experience a new way to browse the web.

diff --git a/src/components/ui/neon-gradient-card.tsx b/src/components/ui/neon-gradient-card.tsx new file mode 100644 index 0000000..1d6a15c --- /dev/null +++ b/src/components/ui/neon-gradient-card.tsx @@ -0,0 +1,144 @@ +'use client' + +import type { CSSProperties, ReactElement, ReactNode } from 'react' +import { useEffect, useRef, useState } from 'react' +import { ny } from '@/lib/utils' + +interface NeonColorsProps { + firstColor: string + secondColor: string +} + +interface NeonGradientCardProps { + /** + * @default
+ * @type ReactElement + * @description + * The component to be rendered as the card + */ + as?: ReactElement + /** + * @default "" + * @type string + * @description + * The className of the card + */ + className?: string + + /** + * @default "" + * @type ReactNode + * @description + * The children of the card + */ + children?: ReactNode + + /** + * @default 5 + * @type number + * @description + * The size of the border in pixels + */ + borderSize?: number + + /** + * @default 20 + * @type number + * @description + * The size of the radius in pixels + */ + borderRadius?: number + + /** + * @default "{ firstColor: '#ff00aa', secondColor: '#00FFF1' }" + * @type string + * @description + * The colors of the neon gradient + */ + neonColors?: NeonColorsProps + + [key: string]: any +} + +const NeonGradientCard: React.FC = ({ + className, + children, + borderSize = 2, + borderRadius = 20, + neonColors = { + firstColor: '#ff00aa', + secondColor: '#00FFF1', + }, + ...props +}) => { + const containerRef = useRef(null) + const [dimensions, setDimensions] = useState({ width: 0, height: 0 }) + + useEffect(() => { + const updateDimensions = () => { + if (containerRef.current) { + const { offsetWidth, offsetHeight } = containerRef.current + setDimensions({ width: offsetWidth, height: offsetHeight }) + } + } + + updateDimensions() + window.addEventListener('resize', updateDimensions) + + return () => { + window.removeEventListener('resize', updateDimensions) + } + }, []) + + useEffect(() => { + if (containerRef.current) { + const { offsetWidth, offsetHeight } = containerRef.current + setDimensions({ width: offsetWidth, height: offsetHeight }) + } + }, [children]) + + return ( +
+
+ {children} +
+
+ ) +} + +export { NeonGradientCard } diff --git a/src/components/ui/table.tsx b/src/components/ui/table.tsx new file mode 100644 index 0000000..cd2454f --- /dev/null +++ b/src/components/ui/table.tsx @@ -0,0 +1,120 @@ +import * as React from 'react' + +import { ny } from '@/lib/utils' + +const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+ + +)) +Table.displayName = 'Table' + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableHeader.displayName = 'TableHeader' + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableBody.displayName = 'TableBody' + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + tr]:last:border-b-0', + className, + )} + {...props} + /> +)) +TableFooter.displayName = 'TableFooter' + +const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableRow.displayName = 'TableRow' + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ className, ...props }, ref) => ( +
[role=checkbox]]:translate-y-[2px]', + className, + )} + {...props} + /> +)) +TableHead.displayName = 'TableHead' + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => ( + [role=checkbox]]:translate-y-[2px]', + className, + )} + {...props} + /> +)) +TableCell.displayName = 'TableCell' + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableCaption.displayName = 'TableCaption' + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +}