portfolio/src/sections/TimelineSection.tsx
Cursor Agent 2e76528ac0
Port portfolio from Next.js/React to SolidJS with Vite
Replace Next.js App Router with Vite, solid-js, and @solidjs/router.
Convert all components, sections, hooks, and pages to SolidJS patterns
(signals, onMount, For, A). Swap lucide-react for lucide-solid and add
client-side routing with Vercel SPA rewrites.

Co-authored-by: Mike Karl <karl.mike2002@gmail.com>
2026-06-15 23:52:28 +00:00

66 lines
2.5 KiB
TypeScript

import { For } from "solid-js";
import { useScrollReveal } from "../hooks/useScrollReveal";
import { timeline, timelinePage } from "../data/timeline";
export default function TimelineSection() {
const revealRef = useScrollReveal<HTMLDivElement>({ stagger: 0.12 });
return (
<section id="timeline" class="py-20 md:py-32 px-[5vw] bg-charcoal">
<div class="max-w-[1200px] mx-auto">
<div class="space-y-4 mb-16">
<h2 class="section-label">{timelinePage.label}</h2>
<p class="text-text-secondary max-w-xl">
{timelinePage.subtitle}
</p>
</div>
<div ref={revealRef} class="relative">
<div class="absolute left-4 md:left-1/2 top-0 bottom-0 w-px bg-warm-grey md:-translate-x-px" />
<div class="space-y-12">
<For each={timeline}>
{(item) => {
const isLeft = () => item.side === "left";
return (
<div class="relative flex items-start md:items-center">
<div class="absolute left-4 md:left-1/2 w-3 h-3 bg-amber border-2 border-deep-space -translate-x-1/2 mt-2 md:mt-0 z-10" />
<div
class={`pl-12 md:pl-0 md:w-1/2 ${
isLeft()
? "md:pr-12 md:text-right"
: "md:pl-12 md:ml-auto"
}`}
>
<div class="space-y-3">
<span class="font-mono text-amber text-sm">
{item.year}
</span>
<h3 class="font-display font-semibold text-text-primary text-xl tracking-tight">
{item.title}
</h3>
<p class="text-text-secondary text-sm leading-relaxed">
{item.description}
</p>
<div
class={`flex flex-wrap gap-2 ${
isLeft() ? "md:justify-end" : ""
}`}
>
<For each={item.tags}>
{(tag) => <span class="chip">{tag}</span>}
</For>
</div>
</div>
</div>
</div>
);
}}
</For>
</div>
</div>
</div>
</section>
);
}