// page-cases.jsx โ€” forum-style case-study list const { SiteCtx: SiteCtx_C, useReveal: useReveal_C, I18N: I18N_C } = window.MM_HOOKS; function CasesPage({ onOpen }) { const { lang } = React.useContext(SiteCtx_C); const t = I18N_C[lang]; const projects = window.SITE_DATA.PROJECTS; const [hRef, hShown] = useReveal_C({ threshold: 0.1 }); return (
{t.cases_eyebrow}

{t.cases_title}

{t.cases_sub}

{projects.map((p, i) => )}
[ end of feed ยท {projects.length} threads ]
); } function CaseRow({ p, i, onOpen }) { const { lang } = React.useContext(SiteCtx_C); const [ref, shown] = useReveal_C({ threshold: 0.1 }); return (
onOpen(p.id)} className={`case-row reveal-pop ${shown ? "is-shown" : ""} ${p.pinned ? "case-row--pinned" : ""}`} style={{ transitionDelay: `${(i % 4) * 80}ms` }} >
{p.pinned && ๐Ÿ“Œ} {String(i + 1).padStart(2, "0")}
{p.category}
{lang === "zh" ? p.title_zh : p.title_en}
{lang === "zh" ? p.oneLiner_zh : p.oneLiner_en}
{p.tags.map(tag => {tag})}
{p.updated}
{p.readMinutes} min
โ†’
); } window.CasesPage = CasesPage;