black theme complete

This commit is contained in:
Emre
2025-10-11 06:18:46 +03:00
parent 16c1a09bc4
commit 31fe89eabb
16 changed files with 276 additions and 293 deletions

View File

@@ -1,104 +1,49 @@
import { motion } from 'framer-motion';
import { Link } from 'react-router-dom';
type FooterLink = {
label: string;
href: string;
target?: '_blank' | '_self';
};
const footerLinksColumn1 = [
{ label: 'About', to: '/about' },
{ label: 'Solutions', to: '/solutions' },
{ label: 'Use Cases', to: '/usecases' },
];
type FooterColumn = {
title: string;
links: FooterLink[];
};
const footerColumns: FooterColumn[] = [
{
title: 'GeoMind',
links: [
{ label: 'Technology', href: '/technology' },
{ label: 'Use Cases', href: '/usecases' },
],
},
{
title: 'Company',
links: [
{ label: 'Manual', href: 'https://manual.grid.tf/', target: '_blank' },
{ label: 'Support', href: 'mailto:support@threefold.tech', target: '_blank' },
],
},
const footerLinksColumn2 = [
{ label: 'Manual', to: '/manual' },
{ label: 'Support', to: '/support' },
{ label: 'Privacy', to: '/privacy' },
];
export const Footer = () => {
const year = new Date().getFullYear();
return (
<footer className="border-t border-slate-200 bg-white">
<motion.div
initial={{ opacity: 0, y: 16 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.2 }}
transition={{ duration: 0.6, ease: 'easeOut' }}
className="mx-auto flex max-w-6xl flex-col gap-8 px-6 py-12 lg:flex-row lg:items-start lg:justify-between lg:px-8"
>
<div className="flex items-center gap-3">
<img
src="/images/geomind_logo.png"
alt="Geomind logo"
className="h-12 w-12 rounded-full object-contain shadow-subtle"
/>
<div>
<p className="text-sm font-semibold tracking-[0.35em] text-slate-500">
GEOMIND
</p>
<p className="mt-2 max-w-xs text-sm text-slate-500">
The datacenter standard for the next era of cloud and AI.
</p>
<footer className="bg-black px-6 pb-16 pt-12 sm:px-10 lg:px-20">
<div className="mx-auto flex w-full max-w-7xl flex-col gap-12 border-t border-white/10 pt-12 md:flex-row md:justify-between">
<div className="space-y-3">
<span className="text-xs font-bold uppercase tracking-[0.35em] text-white">
Geomind
</span>
<p className="max-w-sm text-sm font-semibold text-white">
The datacenter standard for the next era of cloud and AI. </p>
</div>
<nav className="grid grid-cols-2 gap-x-24 gap-y-4 text-xs font-medium uppercase tracking-[0.3em] text-white md:ml-auto self-start">
<div className="flex flex-col items-start gap-4">
{footerLinksColumn1.map(({ label, to }) => (
<Link key={to} to={to} className="text-white transition-colors duration-300">
{label}
</Link>
))}
</div>
</div>
<div className="grid flex-1 grid-cols-1 gap-8 text-sm sm:grid-cols-2 lg:grid-cols-2 lg:ml-auto lg:max-w-md">
{footerColumns.map((column) => (
<div key={column.title}>
<p className="text-xs font-semibold uppercase tracking-[0.25em] text-slate-400">
{column.title}
</p>
<ul className="mt-3 space-y-3 text-sm font-medium text-slate-600">
{column.links.map((link) => (
<li key={link.label}>
<a
href={link.href}
target={link.target}
rel={link.target === '_blank' ? 'noopener noreferrer' : undefined}
className="transition-colors duration-300 hover:text-brand-600"
>
{link.label}
</a>
</li>
))}
</ul>
</div>
))}
</div>
</motion.div>
<div className="bg-mist py-4">
<div className="mx-auto flex max-w-6xl flex-col items-center justify-between gap-2 px-6 text-xs text-slate-500 sm:flex-row lg:px-8">
<span>Copyright {new Date().getFullYear()} GeoMind. All rights reserved.</span>
<div className="flex gap-4">
<a
href="https://www.linkedin.com/company/tf9/"
target="_blank"
rel="noopener noreferrer"
className="hover:text-brand-600"
>
LinkedIn
</a>
<a
href="https://github.com/threefoldtech"
target="_blank"
rel="noopener noreferrer"
className="hover:text-brand-600"
>
GitHub
</a>
<div className="flex flex-col items-start gap-4">
{footerLinksColumn2.map(({ label, to }) => (
<Link key={to} to={to} className="text-white transition-colors duration-300">
{label}
</Link>
))}
</div>
</div>
</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>
</div>
</footer>
);

View File

@@ -10,16 +10,9 @@ const navItems = [
];
export const Header = () => {
const [isScrolled, setIsScrolled] = useState(false);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const location = useLocation();
useEffect(() => {
const onScroll = () => setIsScrolled(window.scrollY > 12);
onScroll();
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}, []);
const isHome = location.pathname === '/';
useEffect(() => {
setIsMenuOpen(false);
@@ -32,7 +25,7 @@ export const Header = () => {
transition={{ duration: 0.6, ease: 'easeOut' }}
className={cn(
'fixed inset-x-0 top-0 z-50 transition-all duration-500',
isScrolled ? 'bg-mist/95 shadow-lg backdrop-blur-sm' : 'bg-transparent',
isHome ? 'bg-transparent' : 'bg-black',
)}
>
<div className="flex w-full items-center justify-between px-6 py-4 sm:px-10 lg:px-16">
@@ -63,7 +56,10 @@ export const Header = () => {
</div>
<a
href="mailto:support@threefold.tech"
className="rounded-full border border-brand-200 bg-white px-4 py-2 text-sm font-semibold text-brand-700 shadow-subtle transition-all duration-300 hover:-translate-y-0.5 hover:border-brand-700 hover:bg-brand-700 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-300 focus-visible:ring-offset-2"
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>
@@ -76,19 +72,22 @@ export const Header = () => {
<span className="relative block h-5 w-6">
<span
className={cn(
'absolute left-0 top-1 h-0.5 w-full bg-ink transition-all duration-300',
'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 bg-ink transition-all duration-300',
'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 bg-ink transition-all duration-300',
'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',
)}
/>
@@ -102,7 +101,10 @@ export const Header = () => {
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -16 }}
transition={{ duration: 0.25, ease: 'easeOut' }}
className="border-t border-slate-100 bg-mist/95 px-6 py-4 shadow-lg md:hidden"
className={cn(
'px-6 py-4 shadow-lg md:hidden',
isHome ? 'border-t border-slate-100 bg-mist/95' : 'border-t border-white/10 bg-black',
)}
>
<div className="flex flex-col gap-4">
{navItems.map(({ label, to }) => (
@@ -121,7 +123,10 @@ export const Header = () => {
))}
<a
href="mailto:support@threefold.tech"
className="rounded-full border border-brand-200 bg-brand-600 px-4 py-2 text-center text-sm font-semibold text-white shadow-subtle transition-colors duration-300 hover:bg-brand-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-300 focus-visible:ring-offset-2"
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',
)}
>
Contact
</a>

View File

@@ -12,9 +12,17 @@ type LayoutProps = {
export const Layout = ({ children }: LayoutProps) => {
const { pathname } = useLocation();
const isHome = pathname === '/';
const darkRoutes = ['/about', '/technology', '/usecases'];
const isDarkPage = darkRoutes.some((route) => pathname.startsWith(route));
return (
<div className={cn('relative min-h-screen bg-mist text-ink', !isHome && 'overflow-hidden')}>
<div
className={cn(
'relative min-h-screen',
isDarkPage ? 'bg-black text-slate-100' : 'bg-mist text-ink',
!isHome && 'overflow-hidden',
)}
>
<ScrollToTop />
<Header />
<main