[{"data":1,"prerenderedAt":532},["ShallowReactive",2],{"writing-building-this-portfolio":3,"writing":308},{"id":4,"title":5,"body":6,"cover":294,"date":295,"description":296,"draft":297,"extension":238,"lang":298,"meta":299,"navigation":255,"path":300,"seo":301,"stem":302,"tags":303,"__hash__":307},"writing\u002Fwriting\u002Fbuilding-this-portfolio.md","Rebuilding my portfolio with Nuxt 4 and Nuxt Content",{"type":7,"value":8,"toc":288},"minimark",[9,18,26,31,34,216,227,231,234,266,270,277,281,284],[10,11,12,13,17],"p",{},"My old site was a Hugo theme with Bootstrap, a few inline scripts and a lot of ",[14,15,16],"code",{},"!important"," for dark mode. It worked, but adding a project meant copying Markdown tables of images and hoping the layout held.",[10,19,20,21,25],{},"The goal of the rebuild: ",[22,23,24],"strong",{},"content separated from presentation",", and a site that is itself a portfolio piece.",[27,28,30],"h2",{"id":29},"content-is-the-source-of-truth","Content is the source of truth",[10,32,33],{},"Every project is one Markdown file. Front-matter is validated with a schema, so a missing field fails the build instead of breaking a page.",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F content.config.ts\nprojects: defineCollection({\n  type: 'page',\n  source: 'projects\u002F*.md',\n  schema: z.object({\n    category: z.string(),\n    year: z.number(),\n    role: z.string(),\n    featured: z.boolean().default(false),\n    metrics: z.array(z.object({ value: z.string(), label: z.string() })).default([]),\n    cover: z.string(),\n  }),\n}),\n","ts","",[14,42,43,52,69,82,93,104,116,127,137,162,194,204,210],{"__ignoreMap":40},[44,45,48],"span",{"class":46,"line":47},"line",1,[44,49,51],{"class":50},"sJ8bj","\u002F\u002F content.config.ts\n",[44,53,55,59,63,66],{"class":46,"line":54},2,[44,56,58],{"class":57},"sScJk","projects",[44,60,62],{"class":61},"sVt8B",": ",[44,64,65],{"class":57},"defineCollection",[44,67,68],{"class":61},"({\n",[44,70,72,75,79],{"class":46,"line":71},3,[44,73,74],{"class":61},"  type: ",[44,76,78],{"class":77},"sZZnC","'page'",[44,80,81],{"class":61},",\n",[44,83,85,88,91],{"class":46,"line":84},4,[44,86,87],{"class":61},"  source: ",[44,89,90],{"class":77},"'projects\u002F*.md'",[44,92,81],{"class":61},[44,94,96,99,102],{"class":46,"line":95},5,[44,97,98],{"class":61},"  schema: z.",[44,100,101],{"class":57},"object",[44,103,68],{"class":61},[44,105,107,110,113],{"class":46,"line":106},6,[44,108,109],{"class":61},"    category: z.",[44,111,112],{"class":57},"string",[44,114,115],{"class":61},"(),\n",[44,117,119,122,125],{"class":46,"line":118},7,[44,120,121],{"class":61},"    year: z.",[44,123,124],{"class":57},"number",[44,126,115],{"class":61},[44,128,130,133,135],{"class":46,"line":129},8,[44,131,132],{"class":61},"    role: z.",[44,134,112],{"class":57},[44,136,115],{"class":61},[44,138,140,143,146,149,152,155,159],{"class":46,"line":139},9,[44,141,142],{"class":61},"    featured: z.",[44,144,145],{"class":57},"boolean",[44,147,148],{"class":61},"().",[44,150,151],{"class":57},"default",[44,153,154],{"class":61},"(",[44,156,158],{"class":157},"sj4cs","false",[44,160,161],{"class":61},"),\n",[44,163,165,168,171,174,176,179,181,184,186,189,191],{"class":46,"line":164},10,[44,166,167],{"class":61},"    metrics: z.",[44,169,170],{"class":57},"array",[44,172,173],{"class":61},"(z.",[44,175,101],{"class":57},[44,177,178],{"class":61},"({ value: z.",[44,180,112],{"class":57},[44,182,183],{"class":61},"(), label: z.",[44,185,112],{"class":57},[44,187,188],{"class":61},"() })).",[44,190,151],{"class":57},[44,192,193],{"class":61},"([]),\n",[44,195,197,200,202],{"class":46,"line":196},11,[44,198,199],{"class":61},"    cover: z.",[44,201,112],{"class":57},[44,203,115],{"class":61},[44,205,207],{"class":46,"line":206},12,[44,208,209],{"class":61},"  }),\n",[44,211,213],{"class":46,"line":212},13,[44,214,215],{"class":61},"}),\n",[10,217,218,219,222,223,226],{},"Adding ",[14,220,221],{},"content\u002Fprojects\u002Fmy-project.md"," creates ",[14,224,225],{},"\u002Fwork\u002Fmy-project"," — no component changes.",[27,228,230],{"id":229},"components-inside-markdown","Components inside Markdown",[10,232,233],{},"Case studies use a few components directly from Markdown, for example an architecture explorer and animated metrics:",[35,235,239],{"className":236,"code":237,"language":238,"meta":40,"style":40},"language-md shiki shiki-themes github-light github-dark","::architecture-explorer{:nodes=\"architecture\"}\n::\n\n::metric-grid{:metrics=\"metrics\"}\n::\n","md",[14,240,241,246,251,257,262],{"__ignoreMap":40},[44,242,243],{"class":46,"line":47},[44,244,245],{},"::architecture-explorer{:nodes=\"architecture\"}\n",[44,247,248],{"class":46,"line":54},[44,249,250],{},"::\n",[44,252,253],{"class":46,"line":71},[44,254,256],{"emptyLinePlaceholder":255},true,"\n",[44,258,259],{"class":46,"line":84},[44,260,261],{},"::metric-grid{:metrics=\"metrics\"}\n",[44,263,264],{"class":46,"line":95},[44,265,250],{},[27,267,269],{"id":268},"motion-but-only-when-it-helps","Motion, but only when it helps",[10,271,272,273,276],{},"One animation library (GSAP), loaded on the client only. Scroll reveals and counters respect ",[14,274,275],{},"prefers-reduced-motion","; when it is set, everything is simply visible.",[27,278,280],{"id":279},"static-by-default","Static by default",[10,282,283],{},"Every page is prerendered, images are optimised at build time, and the whole site deploys to GitHub Pages as static files.",[285,286,287],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":40,"searchDepth":54,"depth":54,"links":289},[290,291,292,293],{"id":29,"depth":54,"text":30},{"id":229,"depth":54,"text":230},{"id":268,"depth":54,"text":269},{"id":279,"depth":54,"text":280},null,"2026-09-29","Why I moved from a Hugo theme to Nuxt, and how content, images and motion are organised so adding a project is one Markdown file.",false,"en",{},"\u002Fwriting\u002Fbuilding-this-portfolio",{"title":5,"description":296},"writing\u002Fbuilding-this-portfolio",[304,305,306],"Engineering","Nuxt","Design","iF-MqYU0u9Y4CZ01rpLE7AyBLEnEw2QGgPwmO1s8dRs",[309,501],{"id":4,"title":5,"body":310,"cover":294,"date":295,"description":296,"draft":297,"extension":238,"lang":298,"meta":498,"navigation":255,"path":300,"seo":499,"stem":302,"tags":500,"__hash__":307},{"type":7,"value":311,"toc":492},[312,316,320,322,324,446,452,454,456,480,482,486,488,490],[10,313,12,314,17],{},[14,315,16],{},[10,317,20,318,25],{},[22,319,24],{},[27,321,30],{"id":29},[10,323,33],{},[35,325,326],{"className":37,"code":38,"language":39,"meta":40,"style":40},[14,327,328,332,342,350,358,366,374,382,390,406,430,438,442],{"__ignoreMap":40},[44,329,330],{"class":46,"line":47},[44,331,51],{"class":50},[44,333,334,336,338,340],{"class":46,"line":54},[44,335,58],{"class":57},[44,337,62],{"class":61},[44,339,65],{"class":57},[44,341,68],{"class":61},[44,343,344,346,348],{"class":46,"line":71},[44,345,74],{"class":61},[44,347,78],{"class":77},[44,349,81],{"class":61},[44,351,352,354,356],{"class":46,"line":84},[44,353,87],{"class":61},[44,355,90],{"class":77},[44,357,81],{"class":61},[44,359,360,362,364],{"class":46,"line":95},[44,361,98],{"class":61},[44,363,101],{"class":57},[44,365,68],{"class":61},[44,367,368,370,372],{"class":46,"line":106},[44,369,109],{"class":61},[44,371,112],{"class":57},[44,373,115],{"class":61},[44,375,376,378,380],{"class":46,"line":118},[44,377,121],{"class":61},[44,379,124],{"class":57},[44,381,115],{"class":61},[44,383,384,386,388],{"class":46,"line":129},[44,385,132],{"class":61},[44,387,112],{"class":57},[44,389,115],{"class":61},[44,391,392,394,396,398,400,402,404],{"class":46,"line":139},[44,393,142],{"class":61},[44,395,145],{"class":57},[44,397,148],{"class":61},[44,399,151],{"class":57},[44,401,154],{"class":61},[44,403,158],{"class":157},[44,405,161],{"class":61},[44,407,408,410,412,414,416,418,420,422,424,426,428],{"class":46,"line":164},[44,409,167],{"class":61},[44,411,170],{"class":57},[44,413,173],{"class":61},[44,415,101],{"class":57},[44,417,178],{"class":61},[44,419,112],{"class":57},[44,421,183],{"class":61},[44,423,112],{"class":57},[44,425,188],{"class":61},[44,427,151],{"class":57},[44,429,193],{"class":61},[44,431,432,434,436],{"class":46,"line":196},[44,433,199],{"class":61},[44,435,112],{"class":57},[44,437,115],{"class":61},[44,439,440],{"class":46,"line":206},[44,441,209],{"class":61},[44,443,444],{"class":46,"line":212},[44,445,215],{"class":61},[10,447,218,448,222,450,226],{},[14,449,221],{},[14,451,225],{},[27,453,230],{"id":229},[10,455,233],{},[35,457,458],{"className":236,"code":237,"language":238,"meta":40,"style":40},[14,459,460,464,468,472,476],{"__ignoreMap":40},[44,461,462],{"class":46,"line":47},[44,463,245],{},[44,465,466],{"class":46,"line":54},[44,467,250],{},[44,469,470],{"class":46,"line":71},[44,471,256],{"emptyLinePlaceholder":255},[44,473,474],{"class":46,"line":84},[44,475,261],{},[44,477,478],{"class":46,"line":95},[44,479,250],{},[27,481,269],{"id":268},[10,483,272,484,276],{},[14,485,275],{},[27,487,280],{"id":279},[10,489,283],{},[285,491,287],{},{"title":40,"searchDepth":54,"depth":54,"links":493},[494,495,496,497],{"id":29,"depth":54,"text":30},{"id":229,"depth":54,"text":230},{"id":268,"depth":54,"text":269},{"id":279,"depth":54,"text":280},{},{"title":5,"description":296},[304,305,306],{"id":502,"title":503,"body":504,"cover":512,"date":521,"description":522,"draft":297,"extension":238,"lang":523,"meta":524,"navigation":255,"path":525,"seo":526,"stem":527,"tags":528,"__hash__":531},"writing\u002Fwriting\u002Fanak-anak-masjid.md","Anak-anak di Masjid Umar Bin Khattab Bypass",{"type":7,"value":505,"toc":519},[506,513,516],[10,507,508],{},[509,510],"img",{"alt":511,"src":512},"Anak-anak di masjid","\u002Fimages\u002Fwriting\u002Fanak-anak-masjid\u002Fcover.png",[10,514,515],{},"Kami baru saja selesai melaksanakan sholat jum'at di masjid umar bin khattab bypass. Kami duduk sejenak untuk bersantai, menunggu awan melintas dilangit untuk melindungi kami dari terik matahari gorontalo yang saking panasnya, konon katanya disini mataharinya dua wkwk.",[10,517,518],{},"Kami lalu dikagetkan dengan aktivitas anak kecil disekeliling kami. Awalnya saya pikir mereka sedang bermain, namun ternyata mereka sedang membantu merapikan karpet masjid selesai dipakai jamaah sholat. Saya melihat senyum berseri dari wajah kecil mereka, ketika diberikan uang 2000 rupiah oleh bapak takmirul. Kebahagiaan telah ditebar dari senyum polos mereka. Sebuah pemandangan yang jarang terlihat, jadi saya memutuskan untuk mengambil moment tersebut.",{"title":40,"searchDepth":54,"depth":54,"links":520},[],"2022-05-24","Catatan kecil selepas sholat Jum'at — tentang senyum anak-anak yang merapikan karpet masjid.","id",{},"\u002Fwriting\u002Fanak-anak-masjid",{"title":503,"description":522},"writing\u002Fanak-anak-masjid",[529,530],"Personal","Cerita","qJfUpO0XCmqTLjOy7NkcHbCyrx7GxXQa6A13pfZnPRE",1790853657293]