// 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;