feat: FAQ two-column layout, team swipe & counter, showcase improvements

- FAQ: split into 2 columns on desktop to reduce section height
- Team: remove description line-clamp, show full bio
- ShowcaseLayout: add swipe navigation on mobile, optional counter
- Counter shows current/total with gold accent styling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 13:22:47 +03:00
parent 0b2d3310af
commit 3ff69d6945
3 changed files with 100 additions and 39 deletions

View File

@@ -22,43 +22,55 @@ export function FAQ() {
<SectionHeading centered>{faq.title}</SectionHeading>
</Reveal>
<div className="mx-auto mt-14 max-w-3xl">
{faq.items.map((item, i) => (
<Reveal key={i}>
<div
className={`border-b border-neutral-200 dark:border-white/[0.06] ${
i === 0 ? "border-t" : ""
}`}
>
<button
onClick={() => toggle(i)}
className="flex w-full items-center justify-between gap-6 py-6 text-left transition-colors"
>
<span className="text-base font-medium text-neutral-900 dark:text-white sm:text-lg">
{item.question}
</span>
<span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-neutral-100 transition-all duration-300 dark:bg-white/[0.06]">
{openIndex === i ? (
<Minus size={16} className="text-[#c9a96e]" />
) : (
<Plus size={16} className="text-neutral-400 dark:text-neutral-500" />
)}
</span>
</button>
<div
className={`grid transition-all duration-300 ease-out ${
openIndex === i ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"
}`}
>
<div className="overflow-hidden">
<div className="pb-6 pr-14 text-sm leading-relaxed text-neutral-600 dark:text-neutral-400 sm:text-base whitespace-pre-line">
{item.answer}
</div>
</div>
</div>
<div className="mx-auto mt-14 grid max-w-5xl gap-x-10 lg:grid-cols-2">
{[0, 1].map((col) => {
const half = Math.ceil(faq.items.length / 2);
const items = col === 0 ? faq.items.slice(0, half) : faq.items.slice(half);
const offset = col === 0 ? 0 : half;
return (
<div key={col}>
{items.map((item, i) => {
const idx = offset + i;
return (
<Reveal key={idx}>
<div
className={`border-b border-neutral-200 dark:border-white/[0.06] ${
i === 0 ? "border-t" : ""
}`}
>
<button
onClick={() => toggle(idx)}
className="flex w-full items-center justify-between gap-4 py-5 text-left transition-colors"
>
<span className="text-sm font-medium text-neutral-900 dark:text-white sm:text-base">
{item.question}
</span>
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-neutral-100 transition-all duration-300 dark:bg-white/[0.06]">
{openIndex === idx ? (
<Minus size={14} className="text-[#c9a96e]" />
) : (
<Plus size={14} className="text-neutral-400 dark:text-neutral-500" />
)}
</span>
</button>
<div
className={`grid transition-all duration-300 ease-out ${
openIndex === idx ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"
}`}
>
<div className="overflow-hidden">
<div className="pb-5 pr-10 text-sm leading-relaxed text-neutral-600 dark:text-neutral-400 whitespace-pre-line">
{item.answer}
</div>
</div>
</div>
</div>
</Reveal>
);
})}
</div>
</Reveal>
))}
);
})}
</div>
</div>
</section>