Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 37 additions & 18 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
"use client";

import { useTranslation } from "react-i18next";
import { useRef } from "react";

export default function Footer() {
const { t } = useTranslation();
const footerRef = useRef<HTMLDivElement>(null);

const skipToMain = () => {
const mainContent = document.querySelector("main");
if (mainContent) {
mainContent.focus();
mainContent.scrollIntoView();
}
};

return (
<footer className="bg-primary-container py-16 px-8">
<footer className="bg-primary-container py-16 px-8" ref={footerRef}>
<a
href="#main-content"
onClick={skipToMain}
className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-2 focus:bg-primary focus:text-white focus:rounded"
>
Skip to main content
</a>
<div className="max-w-7xl mx-auto">
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-16">
<div className="col-span-1 md:col-span-2">
Expand All @@ -16,80 +33,82 @@ export default function Footer() {
</p>
<div className="flex gap-4">
<a
className="w-10 h-10 rounded-full bg-on-primary-container/10 flex items-center justify-center text-on-primary-container hover:bg-on-primary-container/20 transition-colors"
className="w-10 h-10 rounded-full bg-on-primary-container/10 flex items-center justify-center text-on-primary-container hover:bg-on-primary-container/20 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container"
href="#"
aria-label={t("footer.website") || "Visit our website"}
>
<span className="material-symbols-outlined text-lg">public</span>
<span className="material-symbols-outlined text-lg" aria-hidden="true">public</span>
</a>
<a
className="w-10 h-10 rounded-full bg-on-primary-container/10 flex items-center justify-center text-on-primary-container hover:bg-on-primary-container/20 transition-colors"
className="w-10 h-10 rounded-full bg-on-primary-container/10 flex items-center justify-center text-on-primary-container hover:bg-on-primary-container/20 transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container"
href="#"
aria-label={t("footer.github") || "View our GitHub repository"}
>
<span className="material-symbols-outlined text-lg">
<span className="material-symbols-outlined text-lg" aria-hidden="true">
terminal
</span>
</a>
</div>
</div>
<div>
<nav>
<h5 className="text-xs font-bold uppercase tracking-widest text-on-primary-container mb-6">
{t("footer.network")}
</h5>
<ul className="space-y-4 text-sm text-on-primary-container/80">
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.howItWorks")}
</a>
</li>
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.forFreelancers")}
</a>
</li>
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.forLPs")}
</a>
</li>
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.dashboard")}
</a>
</li>
</ul>
</div>
<div>
</nav>
<nav>
<h5 className="text-xs font-bold uppercase tracking-widest text-on-primary-container mb-6">
{t("footer.developers")}
</h5>
<ul className="space-y-4 text-sm text-on-primary-container/80">
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.documentation")}
</a>
</li>
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.githubRepository")}
</a>
</li>
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.technicalSpecs")}
</a>
</li>
<li>
<a className="hover:text-on-primary-container transition-colors" href="#">
<a className="hover:text-on-primary-container transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-offset-primary-container focus:rounded px-1" href="#">
{t("footer.openSourcePolicy")}
</a>
</li>
</ul>
</div>
</nav>
</div>
<div className="pt-8 border-t border-on-primary-container/10 flex flex-col md:flex-row justify-between items-center gap-4 text-[10px] font-bold uppercase tracking-[0.2em] text-on-primary-container/60">
<div className="flex items-center gap-4">
<span>{t("footer.builtOnStellar")}</span>
<span>•</span>
<span aria-hidden="true">•</span>
<span>{t("footer.mitLicense")}</span>
</div>
<div>{t("footer.copyright")}</div>
Expand Down
88 changes: 84 additions & 4 deletions src/components/HowItWorks.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
"use client";

import { useTranslation } from "react-i18next";
import { useState, useEffect } from "react";

export default function HowItWorks() {
const { t } = useTranslation();
const [currentStep, setCurrentStep] = useState(0);
const [isPaused, setIsPaused] = useState(false);
const [expandedDetails, setExpandedDetails] = useState<number | null>(null);

const steps = [
{
Expand All @@ -20,6 +24,22 @@ export default function HowItWorks() {
},
];

useEffect(() => {
if (isPaused) return;

const timer = setInterval(() => {
setCurrentStep((prev) => (prev + 1) % steps.length);
}, 5000);

return () => clearInterval(timer);
}, [isPaused, steps.length]);

const handleStepClick = (index: number) => {
setCurrentStep(index);
setIsPaused(true);
setExpandedDetails(expandedDetails === index ? null : index);
};

return (
<section className="bg-surface-container-low py-24 px-8 overflow-hidden">
<div className="max-w-7xl mx-auto">
Expand All @@ -28,18 +48,78 @@ export default function HowItWorks() {
</h2>
<div className="grid md:grid-cols-3 gap-12 relative mb-24">
{steps.map((step, index) => (
<div key={index} className="relative z-10">
<div className="w-12 h-12 bg-primary-container rounded-full flex items-center justify-center text-on-primary-container font-bold mb-6">
<div
key={index}
className="relative z-10 cursor-pointer transition-all duration-300"
onClick={() => handleStepClick(index)}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
handleStepClick(index);
}
}}
aria-label={`Step ${index + 1}: ${step.title}`}
aria-expanded={expandedDetails === index}
>
<div
className={`w-12 h-12 bg-primary-container rounded-full flex items-center justify-center text-on-primary-container font-bold mb-6 transition-all duration-300 transform ${
currentStep === index ? "scale-125 ring-2 ring-primary" : ""
} ${expandedDetails === index ? "ring-2 ring-primary scale-110" : ""}`}
>
{index + 1}
</div>
<h3 className="text-xl font-headline mb-3">{step.title}</h3>
<p className="text-on-surface-variant text-sm leading-relaxed">
<h3 className="text-xl font-headline mb-3 transition-colors duration-300">
{step.title}
</h3>
<p
className={`text-on-surface-variant text-sm leading-relaxed transition-all duration-300 ${
expandedDetails === index ? "opacity-100" : "opacity-75"
}`}
>
{step.description}
</p>
{expandedDetails === index && (
<div className="mt-4 p-3 bg-primary-container rounded-lg animate-in fade-in slide-in-from-top-2">
<p className="text-sm text-on-primary-container font-medium">
Click step to explore details
</p>
</div>
)}
</div>
))}
</div>

{!isPaused && (
<div className="flex justify-center gap-2 mb-8">
{steps.map((_, index) => (
<button
key={index}
className={`h-2 rounded-full transition-all duration-300 ${
currentStep === index ? "w-8 bg-primary" : "w-2 bg-on-surface-variant/30"
}`}
onClick={() => {
setCurrentStep(index);
setIsPaused(true);
}}
aria-label={`Go to step ${index + 1}`}
/>
))}
</div>
)}

{isPaused && (
<div className="flex justify-center mb-8">
<button
onClick={() => setIsPaused(false)}
className="px-4 py-2 bg-primary text-surface-container-lowest rounded-lg text-sm font-bold hover:bg-primary/90 transition-colors"
>
Resume Auto-Advance
</button>
</div>
)}

<div className="bg-surface-container-highest p-8 md:p-12 rounded-xl flex flex-col md:flex-row items-center justify-between gap-8 border border-outline-variant/40">
<div className="text-center">
<div className="text-xs font-bold mb-2 uppercase text-on-surface-variant">
Expand Down
Loading
Loading