1<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><style id="nuxt-ui-colors">@layer base { 2 :root { 3 --ui-color-primary-50: var(--color-blue-50, oklch(97% 0.014 254.604)); 4 --ui-color-primary-100: var(--color-blue-100, oklch(93.2% 0.032 255.585)); 5 --ui-color-primary-200: var(--color-blue-200, oklch(88.2% 0.059 254.128)); 6 --ui-color-primary-300: var(--color-blue-300, oklch(80.9% 0.105 251.813)); 7 --ui-color-primary-400: var(--color-blue-400, oklch(70.7% 0.165 254.624)); 8 --ui-color-primary-500: var(--color-blue-500, oklch(62.3% 0.214 259.815)); 9 --ui-color-primary-600: var(--color-blue-600, oklch(54.6% 0.245 262.881)); 10 --ui-color-primary-700: var(--color-blue-700, oklch(48.8% 0.243 264.376)); 11 --ui-color-primary-800: var(--color-blue-800, oklch(42.4% 0.199 265.638)); 12 --ui-color-primary-900: var(--color-blue-900, oklch(37.9% 0.146 265.522)); 13 --ui-color-primary-950: var(--color-blue-950, oklch(28.2% 0.091 267.935)); 14 --ui-color-secondary-50: var(--color-blue-50, oklch(97% 0.014 254.604)); 15 --ui-color-secondary-100: var(--color-blue-100, oklch(93.2% 0.032 255.585)); 16 --ui-color-secondary-200: var(--color-blue-200, oklch(88.2% 0.059 254.128)); 17 --ui-color-secondary-300: var(--color-blue-300, oklch(80.9% 0.105 251.813)); 18 --ui-color-secondary-400: var(--color-blue-400, oklch(70.7% 0.165 254.624)); 19 --ui-color-secondary-500: var(--color-blue-500, oklch(62.3% 0.214 259.815)); 20 --ui-color-secondary-600: var(--color-blue-600, oklch(54.6% 0.245 262.881)); 21 --ui-color-secondary-700: var(--color-blue-700, oklch(48.8% 0.243 264.376)); 22 --ui-color-secondary-800: var(--color-blue-800, oklch(42.4% 0.199 265.638)); 23 --ui-color-secondary-900: var(--color-blue-900, oklch(37.9% 0.146 265.522)); 24 --ui-color-secondary-950: var(--color-blue-950, oklch(28.2% 0.091 267.935)); 25 --ui-color-success-50: var(--color-green-50, oklch(98.2% 0.018 155.826)); 26 --ui-color-success-100: var(--color-green-100, oklch(96.2% 0.044 156.743)); 27 --ui-color-success-200: var(--color-green-200, oklch(92.5% 0.084 155.995)); 28 --ui-color-success-300: var(--color-green-300, oklch(87.1% 0.15 154.449)); 29 --ui-color-success-400: var(--color-green-400, oklch(79.2% 0.209 151.711)); 30 --ui-color-success-500: var(--color-green-500, oklch(72.3% 0.219 149.579)); 31 --ui-color-success-600: var(--color-green-600, oklch(62.7% 0.194 149.214)); 32 --ui-color-success-700: var(--color-green-700, oklch(52.7% 0.154 150.069)); 33 --ui-color-success-800: var(--color-green-800, oklch(44.8% 0.119 151.328)); 34 --ui-color-success-900: var(--color-green-900, oklch(39.3% 0.095 152.535)); 35 --ui-color-success-950: var(--color-green-950, oklch(26.6% 0.065 152.934)); 36 --ui-color-info-50: var(--color-blue-50, oklch(97% 0.014 254.604)); 37 --ui-color-info-100: var(--color-blue-100, oklch(93.2% 0.032 255.585)); 38 --ui-color-info-200: var(--color-blue-200, oklch(88.2% 0.059 254.128)); 39 --ui-color-info-300: var(--color-blue-300, oklch(80.9% 0.105 251.813)); 40 --ui-color-info-400: var(--color-blue-400, oklch(70.7% 0.165 254.624)); 41 --ui-color-info-500: var(--color-blue-500, oklch(62.3% 0.214 259.815)); 42 --ui-color-info-600: var(--color-blue-600, oklch(54.6% 0.245 262.881)); 43 --ui-color-info-700: var(--color-blue-700, oklch(48.8% 0.243 264.376)); 44 --ui-color-info-800: var(--color-blue-800, oklch(42.4% 0.199 265.638)); 45 --ui-color-info-900: var(--color-blue-900, oklch(37.9% 0.146 265.522)); 46 --ui-color-info-950: var(--color-blue-950, oklch(28.2% 0.091 267.935)); 47 --ui-color-warning-50: var(--color-yellow-50, oklch(98.7% 0.026 102.212)); 48 --ui-color-warning-100: var(--color-yellow-100, oklch(97.3% 0.071 103.193)); 49 --ui-color-warning-200: var(--color-yellow-200, oklch(94.5% 0.129 101.54)); 50 --ui-color-warning-300: var(--color-yellow-300, oklch(90.5% 0.182 98.111)); 51 --ui-color-warning-400: var(--color-yellow-400, oklch(85.2% 0.199 91.936)); 52 --ui-color-warning-500: var(--color-yellow-500, oklch(79.5% 0.184 86.047)); 53 --ui-color-warning-600: var(--color-yellow-600, oklch(68.1% 0.162 75.834)); 54 --ui-color-warning-700: var(--color-yellow-700, oklch(55.4% 0.135 66.442)); 55 --ui-color-warning-800: var(--color-yellow-800, oklch(47.6% 0.114 61.907)); 56 --ui-color-warning-900: var(--color-yellow-900, oklch(42.1% 0.095 57.708)); 57 --ui-color-warning-950: var(--color-yellow-950, oklch(28.6% 0.066 53.813)); 58 --ui-color-error-50: var(--color-red-50, oklch(97.1% 0.013 17.38)); 59 --ui-color-error-100: var(--color-red-100, oklch(93.6% 0.032 17.717)); 60 --ui-color-error-200: var(--color-red-200, oklch(88.5% 0.062 18.334)); 61 --ui-color-error-300: var(--color-red-300, oklch(80.8% 0.114 19.571)); 62 --ui-color-error-400: var(--color-red-400, oklch(70.4% 0.191 22.216)); 63 --ui-color-error-500: var(--color-red-500, oklch(63.7% 0.237 25.331)); 64 --ui-color-error-600: var(--color-red-600, oklch(57.7% 0.245 27.325)); 65 --ui-color-error-700: var(--color-red-700, oklch(50.5% 0.213 27.518)); 66 --ui-color-error-800: var(--color-red-800, oklch(44.4% 0.177 26.899)); 67 --ui-color-error-900: var(--color-red-900, oklch(39.6% 0.141 25.723)); 68 --ui-color-error-950: var(--color-red-950, oklch(25.8% 0.092 26.042)); 69 --ui-color-neutral-50: var(--color-old-neutral-50, oklch(98.5% 0 0)); 70 --ui-color-neutral-100: var(--color-old-neutral-100, oklch(97% 0 0)); 71 --ui-color-neutral-200: var(--color-old-neutral-200, oklch(92.2% 0 0)); 72 --ui-color-neutral-300: var(--color-old-neutral-300, oklch(87% 0 0)); 73 --ui-color-neutral-400: var(--color-old-neutral-400, oklch(70.8% 0 0)); 74 --ui-color-neutral-500: var(--color-old-neutral-500, oklch(55.6% 0 0)); 75 --ui-color-neutral-600: var(--color-old-neutral-600, oklch(43.9% 0 0)); 76 --ui-color-neutral-700: var(--color-old-neutral-700, oklch(37.1% 0 0)); 77 --ui-color-neutral-800: var(--color-old-neutral-800, oklch(26.9% 0 0)); 78 --ui-color-neutral-900: var(--color-old-neutral-900, oklch(20.5% 0 0)); 79 --ui-color-neutral-950: var(--color-old-neutral-950, oklch(14.5% 0 0)); 80 } 81 :root, .light { 82 --ui-primary: var(--ui-color-primary-500); 83 --ui-secondary: var(--ui-color-secondary-500); 84 --ui-success: var(--ui-color-success-500); 85 --ui-info: var(--ui-color-info-500); 86 --ui-warning: var(--ui-color-warning-500); 87 --ui-error: var(--ui-color-error-500); 88 } 89 .dark { 90 --ui-primary: var(--ui-color-primary-400); 91 --ui-secondary: var(--ui-color-secondary-400); 92 --ui-success: var(--ui-color-success-400); 93 --ui-info: var(--ui-color-info-400); 94 --ui-warning: var(--ui-color-warning-400); 95 --ui-error: var(--ui-color-error-400); 96 } 97}</style>
97<script type="importmap">{"imports":{"#entry":"/_nuxt/CsVLaggN.js"}}</script>
97<title>Designing Interfaces, Building Experiences. - Nuxt Portfolio Template</title><style>::view-transition-new(root),::view-transition-old(root){animation:none;mix-blend-mode:normal}::view-transition-new(root){z-index:9999}::view-transition-old(root){z-index:1}</style><link rel="stylesheet" href="/_nuxt/entry.C680F3sh.css" crossorigin><style>@layer components {:where(.i-lucide\:arrow-right){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 12h14m-7-7l7 7l-7 7'/%3E%3C/svg%3E")}:where(.i-lucide\:arrow-up-right){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 7h10v10M7 17L17 7'/%3E%3C/svg%3E")}:where(.i-lucide\:file-text){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z'/%3E%3Cpath d='M14 2v4a2 2 0 0 0 2 2h4M10 9H8m8 4H8m8 4H8'/%3E%3C/g%3E%3C/svg%3E")}:where(.i-lucide\:folder){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z'/%3E%3C/svg%3E")}:where(.i-lucide\:home){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8'/%3E%3Cpath d='M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3C/g%3E%3C/svg%3E")}:where(.i-lucide\:mic){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M12 19v3m7-12v2a7 7 0 0 1-14 0v-2'/%3E%3Crect width='6' height='13' x='9' y='2' rx='3'/%3E%3C/g%3E%3C/svg%3E")}:where(.i-lucide\:user){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cg fill='none' stroke='black' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/g%3E%3C/svg%3E")}:where(.i-simple-icons\:github){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}:where(.i-simple-icons\:linkedin){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z'/%3E%3C/svg%3E")}:where(.i-simple-icons\:x){display:inline-block;width:1em;height:1em;background-color:currentColor;-webkit-mask-image:var(--svg);mask-image:var(--svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;--svg:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z'/%3E%3C/svg%3E")}}</style><link rel="preload" as="fetch" crossorigin="anonymous" href="/projects/_payload.json?ac2f601d-158a-41cb-b4ab-6c077265ac56"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CsVLaggN.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CRobRmWH.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/DlAUqK2U.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/DXVl7IqR.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Xbqyi5tN.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/BoeCZeT
97V.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/uyKfVzNe.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CUSINPPD.js"><link rel="preload" as="fetch" fetchpriority="low" crossorigin="anonymous" href="/_nuxt/builds/meta/ac2f601d-158a-41cb-b4ab-6c077265ac56.json"><link rel="prefetch" as="script" crossorigin href="/_nuxt/BIFBNDoM.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/BR18rP2x.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/BwRIYNWs.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/CFuAkPGq.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/D2VEnTYJ.js"><meta name="theme-color" content="white"><link rel="icon" href="/favicon.ico"><meta property="og:image" content="https://ui.nuxt.com/assets/templates/nuxt/portfolio-light.png"><meta name="twitter:image" content="https://ui.nuxt.com/assets/templates/nuxt/portfolio-light.png"><meta name="twitter:card" content="summary_large_image"><meta property="og:title" content="Designing Interfaces, Building Experiences."><meta name="description" content="I've worked on a variety of projects, focusing on creating intuitive digital experiences where thoughtful design meets clean code. Here are some highlights I'm proud of, showcasing my process from concept to execution."><meta property="og:description" content="I've worked on a variety of projects, focusing on creating intuitive digital experiences where thoughtful design meets clean code. Here are some highlights I'm proud of, showcasing my process from concept to execution.">
97<script type="module" src="/_nuxt/CsVLaggN.js" crossorigin></script>
97<script>"use strict";(()=>{const t=window,e=document.documentElement,c=["dark","light"],n=getStorageValue("localStorage","nuxt-color-mode")||"system";let i=n==="system"?u():n;const r=e.getAttribute("data-color-mode-forced");r&&(i=r),l(i),t["__NUXT_COLOR_MODE__"]={preference:n,value:i,getColorScheme:u,addColorScheme:l,removeColorScheme:d};function l(o){const s=""+o+"",a="";e.classList?e.classList.add(s):e.className+=" "+s,a&&e.setAttribute("data-"+a,o)}function d(o){const s=""+o+"",a="";e.classList?e.classList.remove(s):e.className=e.className.replace(new RegExp(s,"g"),""),a&&e.removeAttribute("data-"+a)}function f(o){return t.matchMedia("(prefers-color-scheme"+o+")")}function u(){if(t.matchMedia&&f("").media!=="not all"){for(const o of c)if(f(":"+o).matches)return o}return"light"}})();function getStorageValue(t,e){switch(t){case"localStorage":return window.localStorage.getItem(e);case"sessionStorage":return window.sessionStorage.getItem(e);case"cookie":return getCookie(e);default:return null}}function getCookie(t){const c=("; "+window.document.cookie).split("; "+t+"=");if(c.length===2)return c.pop()?.split(";").shift()}</script>
97<!-- Global site tag (gtag.js) - Google Analytics -->
vendor: 64 bytes, lines 97-98
97 98<script async src="https://www.googletagmanager.com/gtag/js?id=
98G-R0DNR50DWG
vendor: 12 bytes, line 98
98"></script>
99<script> 100
vendor: 134 bytes, lines 100-104
100window.dataLayer = window.dataLayer || []; 101 function gtag(){dataLayer.push(arguments);} 102 gtag('js', new Date()); 103 104 gtag('config', '
104G-R0DNR50DWG
vendor: 4 bytes, line 104
104');
105</script>
105</head><body><div id="__nuxt" class="isolate"><!--[--><!--[--><!--[--><!--[--><!--[--><div><div class="w-full max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8 sm:border-x border-default pt-10"><!--[--><div class="fixed top-2 sm:top-4 mx-auto left-1/2 transform -translate-x-1/2 z-10"><!--[--><!----><!----><nav data-collapsed="false" class="relative flex gap-1.5 [&>div]:min-w-0 items-center justify-between bg-muted/80 backdrop-blur-sm rounded-full px-2 sm:px-4 border border-muted/50 shadow-lg shadow-neutral-950/5" aria-label="Main" data-orientation="horizontal" dir="ltr" data-reka-navigation-menu><!--[--><!--[--><!--]--><!--[--><!--[--><div style="position:relative;"><ul class="isolate min-w-0 flex items-center" data-orientation="horizontal"><!--[--><!--[--><li data-menu-item class="min-w-0 py-2"><!--[--><!--[--><a href="/" data-reka-collection-item class="group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2 focus-visible:before:ring-inverted before:inset-x-px before:inset-y-0 text-muted hover:text-highlighted transition-colors data-[state=open]:text-highlighted px-2 py-1"><!--[--><!--[--><!--[--><span class="iconify i-lucide:home shrink-0 size-5 text-dimmed group-hover:text-default transition-colors group-data-[state=open]:text-default block" aria-hidden="true" style=""></span><!--]--><span class="truncate"><!--[-->Home<!--]--><!----></span><!----><!--]--><!--]--></a><!----><!--]--><!----><!--]--></li><li data-menu-item class="min-w-0 py-2"><!--[--><!--[--><a href="/projects" data-reka-collection-item data-active aria-current="page" class="group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2 focus-visible:before:ring-inverted before:inset-x-px before:inset-y-0 text-highlighted px-2 py-1"><!--[--><!--[--><!--[--><span class="iconify i-lucide:folder shrink-0 size-5 text-highlighted group-data-[state=open]:text-highlighted block" aria-hidden="true" style=""></span><!--]--><span class="truncate"><!--[-->Projects<!--]--><!----></span><!----><!--]--><!--]--></a><!----><!--]--><!----><!--]--></li><li data-menu-item class="min-w-0 py-2"><!--[--><!--[--><a href="/blog" data-reka-collection-item class="group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2 focus-visible:before:ring-inverted before:inset-x-px before:inset-y-0 text-muted hover:text-highlighted transition-colors data-[state=open]:text-highlighted px-2 py-1"><!--[--><!--[--><!--[--><span class="iconify i-lucide:file-text shrink-0 size-5 text-dimmed group-hover:text-default transition-colors group-data-[state=open]:text-default block" aria-hidden="true" style=""></span><!--]--><span class="truncate"><!--[-->Blog<!--]--><!----></span><!----><!--]--><!--]--></a><!----><!--]--><!----><!--]--></li><li data-menu-item class="min-w-0 py-2"><!--[--><!--[--><!--[--><a href="https://podcast.michaelshobowale.com" rel="noopener noreferrer" target="_blank" data-reka-collection-item class="group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2 focus-visible:before:ring-inverted before:inset-x-px before:inset-y-0 text-muted hover:text-highlighted transition-colors data-[state=open]:text-highlighted px-2 py-1"><!--[--><!--[--><!--[--><span class="iconify i-lucide:mic shrink-0 size-5 text-dimmed group-hover:text-default transition-colors group-data-[state=open]:text-default block" aria-hidden="true" style=""></span><!--]--><span class="truncate"><!--[-->Podcasts<!--]--><span class="iconify i-lucide:arrow-up-right inline-block size-3 align-top text-dimmed" aria-hidden="true" style=""></span></span><!----><!--]--><!--]--></a><!----><!--]--><!--]--><!----><!--]--></li><li data-menu-item class="min-w-0 py-2"><!--[--><!--[--><a href="/about" data-reka-collection-item class="group relative w-full flex items-center gap-1.5 font-medium text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2 focus-visible:before:ring-inverted before:inset-x-px before:inset-y-0 text-muted hover:text-highlighted transition-colors data-[state=open]:text-highlighted px-2 py-1"><!--[--><!--[--><!--[--><span class="iconify i-lucide:user shrink-0 size-5 text-dimmed group-hover:text-default transition-colors group-data-[state=open]:text-default block" aria-hidden="true" style=""></span><!--]--><span class="truncate"><!--[-->About<!--]--><!----></span><!----><!--]--><!--]--></a><!----><!--]--><!----><!--]--></li>
105<!--]--><!--]--></ul></div><!----><!--]--><!--]--><!--[--><!--[--><div class="size-4"></div><!--]--><!--]--><div class="absolute top-full left-0 flex w-full justify-center"><!----><!----></div><!--]--></nav><!--]--></div><!--[--><main class="min-h-[calc(100vh-var(--ui-header-height))] relative"><!--[--><div class="flex flex-col lg:grid lg:grid-cols-10 lg:gap-10"><!----><div class="lg:col-span-10"><!--[--><div data-orientation="vertical" class="relative isolate"><!--[--><!--]--><div class="w-full max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8 flex flex-col lg:grid gap-16 sm:gap-y-24 py-18 sm:py-24 lg:py-32"><!--[--><div class="text-center"><div class=""><!--[--><!----><h1 class="tracking-tight font-bold text-highlighted mx-auto max-w-xl text-pretty text-3xl sm:text-4xl lg:text-5xl !mx-0 text-left"><!--[-->Designing Interfaces, Building Experiences.<!--]--></h1><div class="text-md mx-auto max-w-2xl sm:text-md text-muted text-balance mt-6 !mx-0 text-left"><!--[-->I've worked on a variety of projects, focusing on creating intuitive digital experiences where thoughtful design meets clean code. Here are some highlights I'm proud of, showcasing my process from concept to execution.<!--]--></div><!--]--></div><!----><div class="mt-10"><!--[--><div class="flex flex-wrap gap-x-6 gap-y-3 justify-start"><!--[--><div class="flex items-center gap-2"><!--[--><!--[--><a href="https://calendly.com/shoboske/30min" rel="noopener noreferrer" target="_blank" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors px-2.5 py-1.5 text-sm gap-1.5 text-inverted bg-inverted hover:bg-inverted/90 active:bg-inverted/90 disabled:bg-inverted aria-disabled:bg-inverted focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-inverted"><!--[--><!--[--><!----><!--]--><!--[--><span class="truncate">Let's talk</span><!--]--><!--[--><!----><!--]--><!--]--></a><!--]--><!--]--></div><!--]--></div><!--]--></div></div><!----><!--]--></div><!--[--><!--]--></div><section data-orientation="vertical" class="relative isolate"><!--[--><!--]--><div class="w-full max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8 flex flex-col lg:grid py-16 sm:py-24 lg:py-32 gap-8 sm:gap-16 !pt-0"><!--[--><!----><!--[--><!--[--><div style="opacity:0;transform:translateY(10px);"><div data-orientation="horizontal" class="relative flex rounded-lg transition has-focus-visible:ring-2 has-focus-visible:ring-primary group" style=""><!----><div class="relative flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 lg:grid-cols-2 lg:items-center p-0 sm:p-0"><div class="flex flex-col flex-1 items-start max-sm:order-last"><!----><div class="inline-flex items-center mb-2.5"><!--[--><span class="text-sm text-muted">2021</span><!--]--></div><div class="flex-1"><!--[--><div class="text-base text-pretty font-semibold text-highlighted"><!--[-->Convos with Friends Podcast<!--]--></div><div class="text-[15px] text-pretty text-muted mt-1"><!--[-->A podcast site built with Next.js and Netlify CMS, featuring audio streaming from Anchor FM and a Disqus commenting system for audience engagement.<!--]--></div><!--]--></div><div class="pt-4 mt-auto"><!--[--><a href="/projects/convos-with-friends" class="focus-visible:outline-primary hover:text-default transition-colors text-sm text-primary flex items-center"><!--[--><!--[--> View Project <span class="iconify i-lucide:arrow-right size-4 text-primary transition-all opacity-0 group-hover:translate-x-1 group-hover:opacity-100" aria-hidden="true" style=""></span><!--]--><!--]--></a><!--]--></div></div><!--[--><img src="/images/convos-with-friends/header.png" data-project-title="Convos with Friends Podcast" alt="Convos with Friends Podcast" class="object-cover w-full h-48 rounded-lg"><!--]--></div><a href="/projects/convos-with-friends" aria-label="Convos with Friends Podcast" class="focus:outline-none peer"><!--[--><!--[--><span class="absolute inset-0" aria-hidden="true"></span><!--]--><!--]--></a></div></div><div style="opacity:0;transform:translateY(10px);"><div data-orientation="horizontal" class="relative flex rounded-lg transition has-focus-visible:ring-2 has-focus-visible:ring-primary group" style=""><!---->
105<div class="relative flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 lg:grid-cols-2 lg:items-center p-0 sm:p-0"><div class="flex flex-col flex-1 items-start lg:order-last max-sm:order-last"><!----><div class="inline-flex items-center mb-2.5"><!--[--><span class="text-sm text-muted">2025</span><!--]--></div><div class="flex-1"><!--[--><div class="text-base text-pretty font-semibold text-highlighted"><!--[-->Footie Manager<!--]--></div><div class="text-[15px] text-pretty text-muted mt-1"><!--[-->A football management web app where you can create teams, manage players, set formations, and simulate matches with friends. Currently a work in progress.<!--]--></div><!--]--></div><div class="pt-4 mt-auto"><!--[--><a href="/projects/footie-manager" class="focus-visible:outline-primary hover:text-default transition-colors text-sm text-primary flex items-center"><!--[--><!--[--> View Project <span class="iconify i-lucide:arrow-right size-4 text-primary transition-all opacity-0 group-hover:translate-x-1 group-hover:opacity-100" aria-hidden="true" style=""></span><!--]--><!--]--></a><!--]--></div></div><!--[--><img src="/images/footie-manager/formation-view.png" data-project-title="Footie Manager" alt="Footie Manager" class="object-cover w-full h-48 rounded-lg"><!--]--></div><a href="/projects/footie-manager" aria-label="Footie Manager" class="focus:outline-none peer"><!--[--><!--[--><span class="absolute inset-0" aria-hidden="true"></span><!--]--><!--]--></a></div></div><div style="opacity:0;transform:translateY(10px);"><div data-orientation="horizontal" class="relative flex rounded-lg transition has-focus-visible:ring-2 has-focus-visible:ring-primary group" style=""><!----><div class="relative flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 lg:grid-cols-2 lg:items-center p-0 sm:p-0"><div class="flex flex-col flex-1 items-start max-sm:order-last"><!----><div class="inline-flex items-center mb-2.5"><!--[--><span class="text-sm text-muted">2022</span><!--]--></div><div class="flex-1"><!--[--><div class="text-base text-pretty font-semibold text-highlighted"><!--[-->Invoice Generator App<!--]--></div><div class="text-[15px] text-pretty text-muted mt-1"><!--[-->A cross-platform mobile application for freelancers and small businesses to create, customize and share professional invoices as PDFs, all without requiring an internet connection.<!--]--></div><!--]--></div><div class="pt-4 mt-auto"><!--[--><a href="/projects/invoice-generator-app" class="focus-visible:outline-primary hover:text-default transition-colors text-sm text-primary flex items-center"><!--[--><!--[--> View Project <span class="iconify i-lucide:arrow-right size-4 text-primary transition-all opacity-0 group-hover:translate-x-1 group-hover:opacity-100" aria-hidden="true" style=""></span><!--]--><!--]--></a><!--]--></div></div><!--[--><img src="/images/invoice-gen/share-invoice-screen.png" data-project-title="Invoice Generator App" alt="Invoice Generator App" class="object-cover w-full h-48 rounded-lg"><!--]--></div><a href="/projects/invoice-generator-app" aria-label="Invoice Generator App" class="focus:outline-none peer"><!--[--><!--[--><span class="absolute inset-0" aria-hidden="true"></span><!--]--><!--]--></a></div></div><div style="opacity:0;transform:translateY(10px);"><div data-orientation="horizontal" class="relative flex rounded-lg transition has-focus-visible:ring-2 has-focus-visible:ring-primary group" style=""><!----><div class="relative flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 lg:grid-cols-2 lg:items-center p-0 sm:p-0"><div class="flex flex-col flex-1 items-start lg:order-last max-sm:order-last"><!----><div class="inline-flex items-center mb-2.5"><!--[--><span class="text-sm text-muted">2021</span><!--]--></div><div class="flex-1"><!--[--><div class="text-base text-pretty font-semibold text-highlighted"><!--[-->Portfolio Website<!--]--></div><div class="text-[15px] text-pretty text-muted mt-1"><!--[-->My personal portfolio website built with Next.js and later evolved to Nuxt 3, showcasing projects, blog posts, and professional experience with a focus on performance and design.<!--]--></div><!--]--></div><div class="pt-4 mt-auto"><!--[--><a href="/projects/portfolio-website" class="focus-visible:outline-primary hover:text-default transition-colors text-sm text-primary flex items-center"><!--[--><!--[--> View Project <span class="iconify i-lucide:arrow-right size-4 text-primary transition-all opacity-0 group-hover:translate-x-1 group-hover:opacity-100" aria-hidden="true" style=""></span><!--]--><!--]--></a>
105<!--]--></div></div><!--[--><img src="/images/portfolio-website/homepage.png" data-project-title="Portfolio Website" alt="Portfolio Website" class="object-cover w-full h-48 rounded-lg"><!--]--></div><a href="/projects/portfolio-website" aria-label="Portfolio Website" class="focus:outline-none peer"><!--[--><!--[--><span class="absolute inset-0" aria-hidden="true"></span><!--]--><!--]--></a></div></div><div style="opacity:0;transform:translateY(10px);"><div data-orientation="horizontal" class="relative flex rounded-lg transition has-focus-visible:ring-2 has-focus-visible:ring-primary group" style=""><!----><div class="relative flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 lg:grid-cols-2 lg:items-center p-0 sm:p-0"><div class="flex flex-col flex-1 items-start max-sm:order-last"><!----><div class="inline-flex items-center mb-2.5"><!--[--><span class="text-sm text-muted">2021</span><!--]--></div><div class="flex-1"><!--[--><div class="text-base text-pretty font-semibold text-highlighted"><!--[-->Xchangr App<!--]--></div><div class="text-[15px] text-pretty text-muted mt-1"><!--[-->A mobile application connecting Nigerian students in North Cyprus with trusted currency exchangers, featuring city-based filtering and easy registration for new exchangers.<!--]--></div><!--]--></div><div class="pt-4 mt-auto"><!--[--><a href="/projects/xchangr-app" class="focus-visible:outline-primary hover:text-default transition-colors text-sm text-primary flex items-center"><!--[--><!--[--> View Project <span class="iconify i-lucide:arrow-right size-4 text-primary transition-all opacity-0 group-hover:translate-x-1 group-hover:opacity-100" aria-hidden="true" style=""></span><!--]--><!--]--></a><!--]--></div></div><!--[--><img src="/images/xchangr/promo.jpeg" data-project-title="Xchangr App" alt="Xchangr App" class="object-cover w-full h-48 rounded-lg"><!--]--></div><a href="/projects/xchangr-app" aria-label="Xchangr App" class="focus:outline-none peer"><!--[--><!--[--><span class="absolute inset-0" aria-hidden="true"></span><!--]--><!--]--></a></div></div><!--]--><!--]--><!--]--></div><!--[--><!--]--></section><!--]--></div><!----></div><!--]--></main><!--]--><footer class="z-10 bg-default"><!----><div class="w-full max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8 py-8 lg:py-4 lg:flex lg:items-center lg:justify-between lg:gap-x-3"><!--[--><div class="lg:flex-1 flex items-center justify-center lg:justify-end gap-x-1.5 lg:order-3"><!--[--><!--[--><!--[--><!--[--><a href="https://x.com/shoboske" rel="noopener noreferrer" target="_blank" aria-label="Find me on X" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-xs gap-1 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1"><!--[--><!--[--><span class="iconify i-simple-icons:x shrink-0 size-4" aria-hidden="true" style=""></span><!--]--><!--[--><!----><!--]--><!--[--><!----><!--]--><!--]--></a><!--]--><!--]--><!--[--><!--[--><a href="https://github.com/shoboske" rel="noopener noreferrer" target="_blank" aria-label="Find me on GitHub" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-xs gap-1 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1"><!--[--><!--[--><span class="iconify i-simple-icons:github shrink-0 size-4" aria-hidden="true" style=""></span><!--]--><!--[--><!----><!--]--><!--[--><!----><!--]--><!--]--></a><!--]--><!--]--><!--[--><!--[--><a href="https://www.linkedin.com/in/michaelshobowale/" rel="noopener noreferrer" target="_blank" aria-label="Find me on LinkedIn" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-xs gap-1 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1"><!--[--><!--[--><span class="iconify i-simple-icons:linkedin shrink-0 size-4" aria-hidden="true" style=""></span><!--]--><!--[--><!----><!--]--><!--[--><!----><!--]--><!--]--></a>
105<!--]--><!--]--><!--]--><!--]--></div><div class="mt-3 lg:mt-0 lg:order-2 flex items-center justify-center"><!--[--><!--]--></div><div class="flex items-center justify-center lg:justify-start lg:flex-1 gap-x-1.5 mt-3 lg:mt-0 lg:order-1 text-muted text-xs"><!--[-->Built with love by Michael Shobowale ⢠© 2026<!--]--></div><!--]--></div><!----></footer><!--]--></div></div><span></span><!--]--><!--]--><!--[--><!--]--><!--v-if--><!--]--><!--[--><!--]--><!--]--><!--]--></div><div id="teleports"></div>
105<script type="application/json" data-nuxt-data="nuxt-app" data-ssr="true" id="__NUXT_DATA__" data-src="/projects/_payload.json?ac2f601d-158a-41cb-b4ab-6c077265ac56">[{"state":1,"once":15,"_errors":16,"serverRendered":5,"path":18,"prerenderedAt":19},["Reactive",2],{"$scolor-mode":3,"$stoasts":7,"$ssite-config":8},{"preference":4,"value":4,"unknown":5,"forced":6},"system",true,false,[],{"_priority":9,"env":12,"name":13,"url":14},{"name":10,"env":11,"url":10},-5,-15,"production","michael-shobo","https://michaelshobowale.com",["Set"],["ShallowReactive",17],{"navigation":-1,"search":-1,"projects-page":-1,"projects":-1},"/projects",1787065839217]</script>
105<script>window.__NUXT__={};window.__NUXT__.config={public:{content:{wsUrl:""},mdc:{components:{prose:true,map:{accordion:"ProseAccordion","accordion-item":"ProseAccordionItem",badge:"ProseBadge",callout:"ProseCallout",card:"ProseCard","card-group":"ProseCardGroup",caution:"ProseCaution","code-collapse":"ProseCodeCollapse","code-group":"ProseCodeGroup","code-icon":"ProseCodeIcon","code-preview":"ProseCodePreview","code-tree":"ProseCodeTree",collapsible:"ProseCollapsible",field:"ProseField","field-group":"ProseFieldGroup",icon:"ProseIcon",kbd:"ProseKbd",note:"ProseNote",steps:"ProseSteps",tabs:"ProseTabs","tabs-item":"ProseTabsItem",tip:"ProseTip",warning:"ProseWarning"}},headings:{anchorLinks:{h1:false,h2:true,h3:true,h4:true,h5:false,h6:false}}}},app:{baseURL:"/",buildId:"ac2f601d-158a-41cb-b4ab-6c077265ac56",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script>
105</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.