style updates

This commit is contained in:
Emre
2025-10-11 11:17:38 +03:00
parent c0f08ad3fa
commit 9451d22494
28 changed files with 613 additions and 240 deletions

View File

@@ -2,7 +2,7 @@ import { Link } from 'react-router-dom';
const footerLinksColumn1 = [
{ label: 'About', to: '/about' },
{ label: 'Solutions', to: '/solutions' },
{ label: 'Tech', to: '/technology' },
{ label: 'Use Cases', to: '/usecases' },
];
@@ -43,7 +43,9 @@ export const Footer = () => {
</nav>
</div>
<div className="mx-auto mt-12 flex w-full max-w-7xl items-center justify-between text-xs uppercase tracking-[0.3em] text-white">
<span>© {year} Geomind. All rights reserved.</span>
<span>
© {year}. <span className="text-brand-400">Built on Geomind.</span> All rights reserved.
</span>
</div>
</footer>
);

View File

@@ -2,15 +2,17 @@ import { useEffect, useState } from 'react';
import { Link, NavLink, useLocation } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
import { cn } from '../../lib/cn';
import { buttonBaseClass } from '../../lib/buttonStyles';
const navItems = [
{ label: 'About', to: '/about' },
{ label: 'Solutions', to: '/technology' },
{ label: 'Tech', to: '/technology' },
{ label: 'Use Cases', to: '/usecases' },
];
export const Header = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [hoveredNav, setHoveredNav] = useState<string | null>(null);
const location = useLocation();
const isHome = location.pathname === '/';
@@ -29,70 +31,81 @@ export const Header = () => {
)}
>
<div className="flex w-full items-center justify-between px-6 py-4 sm:px-10 lg:px-16">
<div className="flex items-center gap-8">
<Link to="/" className="flex items-center">
<img
src="/images/geomind_logo.png"
alt="Geomind logo"
className="h-8 w-auto object-contain"
/>
</Link>
<Link
to="/"
className="flex items-center"
onClick={() => {
if (location.pathname === '/') {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
}}
>
<img
src="/images/geomind_logo.png"
alt="Geomind logo"
className="h-8 w-auto object-contain"
/>
</Link>
<div className="flex items-center gap-4 sm:gap-6">
<nav className="hidden items-center gap-8 md:flex">
{navItems.map(({ label, to }) => (
<NavLink
key={to}
to={to}
className={({ isActive }) =>
cn(
'text-sm font-medium uppercase tracking-wide text-white transition-colors duration-300 hover:text-white/80',
isActive && 'text-white',
)
}
onMouseEnter={() => setHoveredNav(to)}
onMouseLeave={() => setHoveredNav(null)}
onFocus={() => setHoveredNav(to)}
onBlur={() => setHoveredNav(null)}
className={({ isActive }) => {
const isHovered = hoveredNav === to;
return cn(
'text-sm font-semibold uppercase tracking-wide transition-colors duration-300 text-white hover:!text-brand-500 focus-visible:!text-brand-500',
(isActive || isHovered) && '!text-brand-500',
isActive && hoveredNav && hoveredNav !== to && 'animate-blink !text-brand-500',
);
}}
>
{label}
</NavLink>
))}
</nav>
<a
href="mailto:support@threefold.tech"
className={cn(buttonBaseClass, 'px-4 py-2')}
>
GET IN TOUCH
</a>
<button
type="button"
aria-label="Toggle navigation"
className="md:hidden"
onClick={() => setIsMenuOpen((prev) => !prev)}
>
<span className="relative block h-5 w-6">
<span
className={cn(
'absolute left-0 top-1 h-0.5 w-full transition-all duration-300',
isHome ? 'bg-ink' : 'bg-white',
isMenuOpen && 'translate-y-2 rotate-45',
)}
/>
<span
className={cn(
'absolute left-0 top-3 h-0.5 w-full transition-all duration-300',
isHome ? 'bg-ink' : 'bg-white',
isMenuOpen && 'opacity-0',
)}
/>
<span
className={cn(
'absolute left-0 top-5 h-0.5 w-4 transition-all duration-300',
isHome ? 'bg-ink' : 'bg-white',
isMenuOpen && 'left-0 top-3 w-full -rotate-45',
)}
/>
</span>
</button>
</div>
<a
href="mailto:support@threefold.tech"
className={cn(
'rounded-full px-4 py-2 text-sm font-semibold transition-all duration-300 hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-300 focus-visible:ring-offset-2',
'border border-brand-200 bg-white text-brand-700 shadow-subtle hover:border-brand-700 hover:bg-brand-700 hover:text-white focus-visible:ring-offset-white',
)}
>
Contact
</a>
<button
type="button"
aria-label="Toggle navigation"
className="md:hidden"
onClick={() => setIsMenuOpen((prev) => !prev)}
>
<span className="relative block h-5 w-6">
<span
className={cn(
'absolute left-0 top-1 h-0.5 w-full transition-all duration-300',
isHome ? 'bg-ink' : 'bg-white',
isMenuOpen && 'translate-y-2 rotate-45',
)}
/>
<span
className={cn(
'absolute left-0 top-3 h-0.5 w-full transition-all duration-300',
isHome ? 'bg-ink' : 'bg-white',
isMenuOpen && 'opacity-0',
)}
/>
<span
className={cn(
'absolute left-0 top-5 h-0.5 w-4 transition-all duration-300',
isHome ? 'bg-ink' : 'bg-white',
isMenuOpen && 'left-0 top-3 w-full -rotate-45',
)}
/>
</span>
</button>
</div>
<AnimatePresence>
{isMenuOpen && (
@@ -113,8 +126,8 @@ export const Header = () => {
to={to}
className={({ isActive }) =>
cn(
'text-base font-medium uppercase tracking-wide text-white transition-colors duration-300',
isActive && 'text-white',
'text-base font-semibold uppercase tracking-wide text-white transition-colors duration-300',
isActive && 'text-brand-500',
)
}
>
@@ -123,12 +136,9 @@ export const Header = () => {
))}
<a
href="mailto:support@threefold.tech"
className={cn(
'rounded-full px-4 py-2 text-center text-sm font-semibold text-white shadow-subtle transition-colors duration-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-300 focus-visible:ring-offset-2',
'border border-brand-200 bg-brand-600 hover:bg-brand-700 focus-visible:ring-offset-white',
)}
className={cn(buttonBaseClass, 'flex w-full justify-center px-4 py-2 text-center')}
>
Contact
GET IN TOUCH
</a>
</div>
</motion.nav>

View File

@@ -1,6 +1,7 @@
import { type ReactNode } from 'react';
import { Link } from 'react-router-dom';
import { cn } from '../../lib/cn';
import { buttonBaseClass } from '../../lib/buttonStyles';
type PrimaryButtonProps = {
to?: string;
@@ -11,16 +12,10 @@ type PrimaryButtonProps = {
target?: string;
};
const styles: Record<
NonNullable<PrimaryButtonProps['variant']>,
string
> = {
solid:
'bg-brand-600 text-white shadow-subtle hover:bg-brand-500 hover:text-white hover:shadow-lg',
outline:
'border border-brand-200 bg-white text-brand-700 hover:border-brand-400 hover:bg-white/95 hover:text-brand-700 hover:shadow-md',
ghost:
'bg-transparent text-brand-600 hover:bg-brand-50/80 hover:text-brand-700',
const styles: Record<NonNullable<PrimaryButtonProps['variant']>, string> = {
solid: buttonBaseClass,
outline: buttonBaseClass,
ghost: buttonBaseClass,
};
export const PrimaryButton = ({
@@ -31,8 +26,7 @@ export const PrimaryButton = ({
className,
target,
}: PrimaryButtonProps) => {
const baseClasses =
'inline-flex items-center justify-center rounded-full px-5 py-2 text-sm font-semibold transition-all duration-300 hover:-translate-y-0.5 active:translate-y-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand-300 focus-visible:ring-offset-2';
const baseClasses = buttonBaseClass;
if (to) {
return (