Memorable design.
Worth seeing.

☘︎

A multidisciplinary designer & artist passionate about storytelling, visual communication, and purposeful design.

Just an
inkling.

Websites, digital experiences, illustration, and motion graphics that bring concepts to life.

About Me →
Sketchbook and botanical drawing

Good to meet you.

Every story starts with an idea. With fresh eyes, creative thinking, and thoughtful design, those ideas can become something worth sharing. It all starts with a good conversation.

Get in Touch →

Reach Out!

☘

I’m all ears. Send a note or use the form below.

← Back to Projects

Mars Travel Badges

☘

Digital Illustration

Mars Travel Badge

Project Details

Two retro-style Mars travel badge illustrations featuring classic space exploration themes, including a rocket launch, planetary imagery, and an astronaut helmet design inspired by vintage travel souvenirs.

Detail Image

Software

Procreate
Adobe Photoshop
Adobe Illustrator

← Back to Projects

3D Duck

☘

3D Character Design

Blue Duck character turnaround showcase

Project Details

A stylized 3D duck character commissioned by Wagbit LLC. Sculpted in Nomad Sculpt and rendered in Blender, the character combines playful proportions with expressive personality.

Preview of the blue duck 3D character

Select “View in 3D” to rotate the character.

Software

Nomad SculptNomad Sculpt logo
BlenderBlender logo
(function () { 'use strict'; function initDuckModel() { const root = document.getElementById('tws-duck-project'); if (!root) return; const button = root.querySelector('#tws-duck-open'); const model = root.querySelector('#tws-duck-model'); const preview = root.querySelector('#tws-duck-preview'); const status = root.querySelector('#tws-duck-model-status'); const error = root.querySelector('#tws-duck-error'); const instructions = root.querySelector('#tws-duck-instructions'); if (!button || !model || button.dataset.duckModelReady === 'true') return; button.dataset.duckModelReady = 'true'; const loaderUrl = 'https://ajax.googleapis.com/ajax/libs/model-viewer/4.1.0/model-viewer.min.js'; function loadViewerLibrary() { if (customElements.get('model-viewer')) return Promise.resolve(); if (!window.twsDuckViewerLoader) { window.twsDuckViewerLoader = new Promise((resolve, reject) => { const existing = document.querySelector('script[data-tws-duck-viewer-lib]'); if (existing) { existing.addEventListener('load', resolve, {once:true}); existing.addEventListener('error', () => reject(new Error('Viewer script failed')), {once:true}); return; } const script = document.createElement('script'); script.type = 'module'; script.src = loaderUrl; script.dataset.twsDuckViewerLib = 'true'; script.onload = resolve; script.onerror = () => reject(new Error('Viewer script failed')); document.head.appendChild(script); }).then(() => customElements.whenDefined('model-viewer')); } return window.twsDuckViewerLoader; } button.addEventListener('click', async function () { if (button.disabled) return; button.disabled = true; status.hidden = false; error.hidden = true; try { await loadViewerLibrary(); model.addEventListener('load', function () { status.hidden = true; preview.hidden = true; instructions.textContent = '↔ Drag to Rotate · Interactive 3D Model'; }, {once:true}); model.addEventListener('error', function () { status.hidden = true; error.hidden = false; button.disabled = false; }, {once:true}); model.src = model.dataset.modelSrc; } catch (err) { status.hidden = true; error.hidden = false; button.disabled = false; } }); } function initDuckGallery() { const root = document.getElementById('tws-duck-project'); if (!root) return; const gallery = root.querySelector('.tws-lightbox-gallery'); const viewer = root.querySelector('.tws-lightbox'); if (!gallery || !viewer) return; if (gallery.dataset.duckGalleryReady === 'true') return; const items = Array.from(gallery.querySelectorAll('.tws-gallery-item')); if (!items.length) return; const image = viewer.querySelector('.tws-lightbox-image'); const caption = viewer.querySelector('.tws-lightbox-caption'); const counter = viewer.querySelector('.tws-lightbox-counter'); const closeButton = viewer.querySelector('.tws-lightbox-close'); const previous = viewer.querySelector('.tws-lightbox-prev'); const next = viewer.querySelector('.tws-lightbox-next'); if (!image || !caption || !counter || !closeButton || !previous || !next) return; gallery.dataset.duckGalleryReady = 'true'; let current = 0; let lastFocused = null; let touchStartX = 0; function show(index) { current = (index + items.length) % items.length; const item = items[current]; const thumbnail = item.querySelector('img'); image.src = item.dataset.full || (thumbnail ? thumbnail.src : ''); image.alt = thumbnail ? thumbnail.alt : ''; caption.textContent = item.dataset.caption || ''; counter.textContent = String(current + 1).padStart(2, '0') + ' / ' + String(items.length).padStart(2, '0'); } function open(index) { lastFocused = document.activeElement; show(index); viewer.classList.add('is-open'); viewer.setAttribute('aria-hidden', 'false'); closeButton.focus(); } function close() { viewer.classList.remove('is-open'); viewer.setAttribute('aria-hidden', 'true'); image.removeAttribute('src'); if (lastFocused && lastFocused.isConnected) lastFocused.focus(); } items.forEach((item, index) => item.addEventListener('click', function(event){event.preventDefault();open(index)})); closeButton.addEventListener('click', close); previous.addEventListener('click', () => show(current - 1)); next.addEventListener('click', () => show(current + 1)); viewer.addEventListener('click', function(event){if(event.target === viewer || event.target.classList.contains('tws-lightbox-stage')) close()}); document.addEventListener('keydown', function(event){ if (!viewer.classList.contains('is-open')) return; if (event.key === 'Escape') close(); if (event.key === 'ArrowLeft') show(current - 1); if (event.key === 'ArrowRight') show(current + 1); if (event.key === 'Tab') { const controls = [closeButton, previous, next]; const focused = controls.indexOf(document.activeElement); if (event.shiftKey && focused <= 0) {event.preventDefault();next.focus()} else if (!event.shiftKey && focused === controls.length - 1) {event.preventDefault();closeButton.focus()} } }); viewer.addEventListener('touchstart', function(event){touchStartX = event.changedTouches[0].screenX}, {passive:true}); viewer.addEventListener('touchend', function(event){const difference=event.changedTouches[0].screenX-touchStartX;if(Math.abs(difference)>60)show(current+(difference<0?1:-1))}, {passive:true}); window.addEventListener('hashchange', close); } function initDuckProject(){initDuckModel();initDuckGallery()} window.initDuckGallery = initDuckGallery; window.initDuckProject = initDuckProject; if(document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initDuckProject); else initDuckProject(); const observer = new MutationObserver(function(){ const root = document.getElementById('tws-duck-project'); if(root && (root.querySelector('#tws-duck-open')?.dataset.duckModelReady !== 'true' || root.querySelector('.tws-lightbox-gallery')?.dataset.duckGalleryReady !== 'true')) initDuckProject(); }); observer.observe(document.body, {childList:true,subtree:true}); })();
← Back to Projects

OTC Newspaper Comic

☘

Digital Illustration

OTC Newspaper Comic

Project Details

Fantasy illustration exploring nature, mythology, and atmosphere.

Detail Image

Software

Procreate
Adobe Photoshop
Adobe Illustrator

← Back to Branding/Advertising

Branding & Advertising Projects

☘

Selected UI/UX design work spanning user research, wireframing, prototyping, and visual design.

← Back to UI/UX Design

UI/UX Design Projects

☘

Selected UI/UX design work spanning user research, wireframing, prototyping, and visual design.

← Back to Projects

UI/UX · Mobile App

MendPen

Health &Wellness Mobile App

Project Details

MendPen is a health and wellness mobile app concept designed around creativity, reflection, and emotional self-expression. The experience guides users from identifying how they feel into creative activities, where they can draw, color, explore tools, respond to prompts, and record reflections.

Sketches: Procreate. UI and screen flow: Adobe XD. Logo: Adobe Illustrator.

Role &DesignerUI/UX Designer · Graphic Designer
Melissa Williams
Software
  • Procreate
  • Adobe Illustrator
  • Adobe XD
Project TypeMobile App · Interactive Prototype · Screen Flow
Design FocusNavigation · Accessibility · Visual Hierarchy · Branding · Illustration

Explore the App Experience

Explore the original MendPen interface screen by screen. Use the arrows, progress dots, or swipe on mobile.

Original MendPen welcome screen
SCREEN 01 / 10

Welcome to MendPen

Begin the experience with the app’s welcome interface and visual identity.

01 / 10

Interactive screen-flow concept · Original Adobe XD artwork

LIVE PROTOTYPEExplore the Adobe XD Prototype

Experience the original clickable MendPen prototype in Adobe XD. Opens in a new tab.

A screen-based UI/UX proof of concept using ten original MendPen interface designs.
(function(){'use strict';function init(){var root=document.getElementById('tws-mendpen-project');if(!root||root.dataset.mpPlayerReady)return;root.dataset.mpPlayerReady='1';var urls=["https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Mendpen.png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Mood+Selection.png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Moodconfirmation.png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Mood+Word+Prompt.png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Art+Aboard+Type.png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Canvas+Page+(Blank).png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Canvas+Page+(Color+Page).png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Reflection+Page.png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Journal.png", "https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/mendpen/Account+Settings.png"],titles=["Welcome to MendPen", "Choose a Mood", "Confirm Your Mood", "Explore a Mood Prompt", "Choose an Art Activity", "Start with a Blank Canvas", "Create with Color", "Reflect on the Experience", "Capture a Journal Entry", "Manage Account Settings"],descs=["Begin the experience with the app\u2019s welcome interface and visual identity.", "Select how you are feeling to begin a personalized creative journey.", "Review the selected feeling before moving into the experience.", "A word-based prompt helps connect reflection with a creative activity.", "Explore the art activity options before entering the creative workspace.", "Open a clean canvas ready for drawing and experimentation.", "See the coloring interface and creative tools in context.", "Move from making art to considering the experience and emotions.", "Record personal reflections in the journal interface.", "Review the account preferences and settings available in the app."];var img=root.querySelector('.mp-art img'),title=root.querySelector('.mp-copy h3'),desc=root.querySelector('.mp-copy p'),num=root.querySelector('.mp-number'),count=root.querySelector('.mp-count'),prev=root.querySelector('[data-mp-prev]'),next=root.querySelector('[data-mp-next]'),dots=root.querySelectorAll('[data-mp-go]');var index=0,seq=0;function show(n){n=Math.max(0,Math.min(urls.length-1,n));index=n;var ticket=++seq;img.classList.add('mp-fade');num.textContent='SCREEN '+String(n+1).padStart(2,'0')+' / 10';title.textContent=titles[n];desc.textContent=descs[n];count.textContent=String(n+1).padStart(2,'0')+' / 10';prev.disabled=n===0;next.disabled=n===urls.length-1;dots.forEach(function(d,i){if(i===n)d.setAttribute('aria-current','step');else d.removeAttribute('aria-current')});var pre=new Image();pre.onload=function(){if(ticket!==seq)return;img.src=urls[n];img.alt=titles[n]+' — original MendPen interface';img.classList.remove('mp-fade')};pre.onerror=function(){if(ticket===seq){img.classList.remove('mp-fade');desc.textContent+=' (This image could not be loaded.)'}};pre.src=urls[n];}root.addEventListener('click',function(e){var b=e.target.closest('[data-mp-prev],[data-mp-next],[data-mp-go]');if(!b||!root.contains(b))return;if(b.hasAttribute('data-mp-go'))show(+b.getAttribute('data-mp-go'));else show(index+(b.hasAttribute('data-mp-next')?1:-1))});var player=root.querySelector('.mp-player');player.addEventListener('keydown',function(e){if(e.key==='ArrowRight'){e.preventDefault();show(index+1)}else if(e.key==='ArrowLeft'){e.preventDefault();show(index-1)}});var touchX=null;player.addEventListener('touchstart',function(e){touchX=e.changedTouches[0].screenX},{passive:true});player.addEventListener('touchend',function(e){if(touchX===null)return;var delta=e.changedTouches[0].screenX-touchX;touchX=null;if(Math.abs(delta)>60)show(index+(delta<0?1:-1))},{passive:true});show(0);}if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init);else init();})();(function(){var root=document.getElementById('tws-mendpen-project');if(!root)return;function align(){var head=document.querySelector('header.tws-header, .tws-header');if(!head)return;var h=head.getBoundingClientRect();if(h.width<100||!h.height)return;root.style.width=h.width+'px';root.style.left='0px';root.style.transform='none';var r=root.getBoundingClientRect();root.style.left=(h.left-r.left)+'px';}align();window.addEventListener('resize',align,{passive:true});if('ResizeObserver'in window){var head=document.querySelector('header.tws-header, .tws-header');if(head)new ResizeObserver(align).observe(head);}document.addEventListener('click',function(e){if(e.target.closest('[data-route]'))requestAnimationFrame(align)});requestAnimationFrame(align);})();
← Back to Projects

UI/UX · Digital Storefront

Tree Water Studio Website

☘

E-Commerce Website · UI/UX

Visit Live Website treewater.studio

Tree Water Studio website homepage

Project Details

Tree Water Studio is an e-commerce website concept designed as a welcoming digital storefront for artists and creatives.

Brushes, kits, textures, and illustration elements are organized for easy discovery, alongside original artwork and publications such as Harry’s Sunday Drive.

The design brings together clear navigation, visual branding, and thoughtful product presentation.

Tree Water Studio website page layout

Software Used

Adobe XD
Procreate
Adobe Illustrator
Adobe Photoshop

Project Overview

Role &DesignerUI/UX Designer · Illustrator · Graphic Designer
Melissa Williams
Project TypeE-Commerce Website · Creative Brand · UI/UX
ApplicationsDigital Product Store · Artist Portfolio · Children’s Book Promotion
AudienceDigital artists, illustrators, designers, and customers interested in original illustrated products
Creative ProcessAdobe XD for layouts and UI/UX;Procreate, Illustrator, and Photoshop for illustrations and visual assets
Design FocusProduct discovery · Navigation · Responsive design · Branding · Visual hierarchy
(function(){'use strict'; /* Original viewer identifiers, extended with photo gallery features. */ if(window.__twsStudioDuckGalleryV8)return; window.__twsStudioDuckGalleryV8=true; window.__twsStudioDuckStandaloneV6=true; var ROOT='https://cdn-treewaterstudio.s3.us-east-2.amazonaws.com/wp-content/uploads/2026/3D+Duck/3D+Duck/'; var GLB=ROOT+'Wagbit_Duck_Lightweight.glb'; var PHOTOS=[ {src:ROOT+'Blue+Duck+Character+Turnaround+Showcase.webp',title:'Wagbit Promotional Duck — Character Turnaround'}, {src:ROOT+'Blue+Duck+Figurine+Desk+Showcase.webp',title:'Wagbit Promotional Duck — Figurine Desk Showcase'} ]; var popup=null,panel=null,stage=null,status=null,bar=null,label=null,closeBtn=null; var photos=null,photoImg=null,caption=null,thumbs=null,tab3d=null,tabPhotos=null,model=null; var loadPromise=null,serial=0,returnFocus=null,previousOverflow='',current=0,mode='3d'; function node(tag,cls,parent){var e=document.createElement(tag);if(cls)e.className=cls;if(parent)parent.appendChild(e);return e;} function button(cls,text,parent,aria){var e=node('button',cls,parent);e.type='button';e.textContent=text;if(aria)e.setAttribute('aria-label',aria);return e;} function showPhoto(index){ current=(index+PHOTOS.length)%PHOTOS.length; if(!photoImg)return; var p=PHOTOS[current];photoImg.src=p.src;photoImg.alt=p.title; if(mode==='photos')caption.textContent=p.title+' · '+(current+1)+' of '+PHOTOS.length; Array.prototype.forEach.call(thumbs.children,function(t,i){t.setAttribute('aria-current',String(i===current));}); } function switchMode(next){ mode=next;if(!stage)return; var is3d=next==='3d';stage.hidden=!is3d;photos.hidden=is3d; tab3d.setAttribute('aria-selected',String(is3d));tabPhotos.setAttribute('aria-selected',String(!is3d)); tab3d.classList.toggle('is-active',is3d);tabPhotos.classList.toggle('is-active',!is3d); thumbs.hidden=is3d; caption.textContent=is3d?'Drag to rotate · Scroll or pinch to zoom':PHOTOS[current].title+' · '+(current+1)+' of '+PHOTOS.length; } function make(){ if(popup&&popup.isConnected)return; var old=document.getElementById('tws-studio-duck-popup');if(old)old.remove(); popup=node('div','',document.body);popup.id='tws-studio-duck-popup';popup.hidden=true; panel=node('div','duck-panel',popup);panel.setAttribute('role','dialog');panel.setAttribute('aria-modal','true');panel.setAttribute('aria-label','Wagbit LLC commissioned promotional duck 3D model and photo gallery'); var head=node('div','duck-head',panel);node('h2','',head).textContent='Wagbit Promotional Duck'; var credit=node('p','duck-credit',panel);credit.innerHTML='3D promotional character commissioned by Wagbit LLC ↗';head.after(credit); var future=node('p','duck-future',panel);future.innerHTML='Future Downloadable 3D Assets — This commissioned duck character by Wagbit LLC is a featured example of the 3D products planned for Tree Water Studio’s store expansion. Purchasable, reusable 3D assets in formats such as OBJ are planned for future release; this model is not currently offered for sale.';credit.after(future); closeBtn=button('duck-close','×',head,'Close duck viewer'); var tabs=node('div','duck-tabs',panel);tabs.setAttribute('role','tablist');tabs.setAttribute('aria-label','Duck viewer mode'); tab3d=button('duck-tab','Interactive 3D',tabs);tab3d.setAttribute('role','tab'); tabPhotos=button('duck-tab','Photo Gallery',tabs);tabPhotos.setAttribute('role','tab'); var views=node('div','duck-viewports',panel); stage=node('div','duck-stage',views);stage.setAttribute('aria-label','Interactive 3D duck'); status=node('div','duck-status',stage);label=node('span','',status);bar=node('progress','',status);bar.max=100;bar.value=0; photos=node('div','duck-photos',views);photos.hidden=true; photoImg=node('img','',photos);photoImg.alt=''; var nav=node('div','duck-photo-nav',photos); var prev=button('','‹',nav,'Previous duck image');var next=button('','›',nav,'Next duck image'); var footer=node('div','duck-footer',panel);caption=node('p','duck-caption',footer); thumbs=node('div','duck-thumbs',footer);thumbs.setAttribute('aria-label','Duck image thumbnails'); PHOTOS.forEach(function(item,i){ var t=button('duck-thumb','',thumbs,'Show '+item.title); var img=node('img','',t);img.src=item.src;img.alt='';img.loading='lazy'; t.addEventListener('click',function(){showPhoto(i);switchMode('photos');}); }); prev.addEventListener('click',function(){showPhoto(current-1);}); next.addEventListener('click',function(){showPhoto(current+1);}); tab3d.addEventListener('click',function(){switchMode('3d');}); tabPhotos.addEventListener('click',function(){switchMode('photos');}); closeBtn.addEventListener('click',close); popup.addEventListener('click',function(e){if(e.target===popup)close();}); showPhoto(0);switchMode('3d'); } function library(){ if(window.customElements&&customElements.get('model-viewer'))return Promise.resolve(); if(loadPromise)return loadPromise; loadPromise=new Promise(function(resolve,reject){ var s=document.createElement('script');s.type='module'; s.src='https://ajax.googleapis.com/ajax/libs/model-viewer/4.0.0/model-viewer.min.js'; s.onload=function(){customElements.whenDefined('model-viewer').then(resolve,reject);}; s.onerror=function(){reject(Error('3D viewer library could not load'));}; document.head.appendChild(s); }).catch(function(err){loadPromise=null;throw err;}); return loadPromise; } async function open(){ make();if(!popup.hidden)return; var token=++serial;returnFocus=document.activeElement;previousOverflow=document.body.style.overflow; popup.hidden=false;document.body.style.overflow='hidden';switchMode('3d');closeBtn.focus(); status.hidden=false;label.textContent='Preparing 3D viewer…';bar.value=0; var oldModel=stage.querySelector('model-viewer');if(oldModel)oldModel.remove(); var oldPoster=stage.querySelector('img');if(oldPoster)oldPoster.remove();model=null; var poster=node('img','',stage);poster.src=PHOTOS[0].src;poster.alt='Duck model preview'; stage.insertBefore(poster,status); try{ await library();if(token!==serial||popup.hidden)return; model=document.createElement('model-viewer'); model.setAttribute('camera-controls','');model.setAttribute('disable-pan',''); model.setAttribute('environment-image','neutral');model.setAttribute('alt','Interactive 3D Wagbit LLC promotional duck'); model.setAttribute('poster',PHOTOS[0].src); model.addEventListener('progress',function(e){if(token!==serial)return;var n=Math.round((e.detail.totalProgress||0)*100);bar.value=n;label.textContent='Loading 3D duck… '+n+'%';}); model.addEventListener('load',function(){if(token===serial)status.hidden=true;}); model.addEventListener('error',function(){if(token===serial){status.hidden=false;label.textContent='3D unavailable. You can still view the duck photos.';}}); poster.replaceWith(model);model.src=GLB; }catch(err){console.error('TWS Duck viewer:',err);if(token===serial){status.hidden=false;label.textContent='3D unavailable. Select Photo Gallery to view the artwork.';}} } function close(){ if(!popup||popup.hidden)return; ++serial;popup.hidden=true;document.body.style.overflow=previousOverflow; if(model){model.remove();model=null;} if(stage){var preview=stage.querySelector('img');if(preview)preview.remove();} if(returnFocus&&returnFocus.isConnected)returnFocus.focus(); } /* Keep the original button ID and public function names. */ document.addEventListener('click',function(e){ var target=e.target.nodeType===1?e.target:e.target.parentElement; var trigger=target&&target.closest&&target.closest('#tws-website-duck-open'); if(!trigger)return;e.preventDefault();open(); },true); document.addEventListener('keydown',function(e){ if(!popup||popup.hidden)return; if(e.key==='Escape'){e.preventDefault();close();return;} if(mode==='photos'&&e.key==='ArrowRight'){e.preventDefault();showPhoto(current+1);} if(mode==='photos'&&e.key==='ArrowLeft'){e.preventDefault();showPhoto(current-1);} if(e.key==='Tab'){ var visible=Array.prototype.filter.call(panel.querySelectorAll('button'),function(b){return b.getClientRects().length>0;}); if(!visible.length)return; if(e.shiftKey&&document.activeElement===visible[0]){e.preventDefault();visible[visible.length-1].focus();} else if(!e.shiftKey&&document.activeElement===visible[visible.length-1]){e.preventDefault();visible[0].focus();} } }); window.addEventListener('hashchange',close); window.twsOpenStudioDuck=open; window.twsCloseStudioDuck=close; })();
/* Preserve existing hover/focus video previews. */ (function(){ function setupMotionPreviews(){ var page=document.querySelector('[data-page="motiongraphics"]'); if(!page)return; page.querySelectorAll('.tws-motion-card').forEach(function(card){ if(card.dataset.motionPreviewBound==='1')return; var video=card.querySelector('video'); if(!video)return; card.dataset.motionPreviewBound='1'; video.muted=true; video.defaultMuted=true; video.playsInline=true; video.loop=true; function start(){ if(page.hidden)return; video.muted=true; var result=video.play(); if(result&&typeof result.then==='function'){ result.then(function(){ if(card.matches(':hover')||card.matches(':focus-within')){ card.classList.add('is-playing'); }else{ stop(); } }).catch(function(){ card.classList.remove('is-playing'); }); }else{ card.classList.add('is-playing'); } } function stop(){ video.pause(); try{video.currentTime=0;}catch(e){} card.classList.remove('is-playing'); } card.addEventListener('mouseenter',start); card.addEventListener('mouseleave',stop); card.addEventListener('focusin',start); card.addEventListener('focusout',function(e){ if(!card.contains(e.relatedTarget))stop(); }); video.addEventListener('ended',function(){ card.classList.remove('is-playing'); }); video.addEventListener('error',function(){ card.classList.remove('is-playing'); }); }); } if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded',setupMotionPreviews); }else{ setupMotionPreviews(); } })();
(function(){ 'use strict'; function init(){ const page=document.querySelector('[data-page="motiongraphics"]'); if(!page||page.dataset.motionReady==='true')return; page.dataset.motionReady='true'; const cards=Array.from(page.querySelectorAll('.tws-motion-card')); const reduced=window.matchMedia('(prefers-reduced-motion: reduce)'); const fine=window.matchMedia('(hover: hover) and (pointer: fine)'); const visible=()=>page.getClientRects().length>0&&getComputedStyle(page).visibility!=='hidden'; function stop(card){ const video=card.querySelector('video');if(!video)return; video.pause();card.classList.remove('is-playing'); try{video.currentTime=0}catch(e){} } function play(card){ const video=card.querySelector('video'); if(!video||!visible()||reduced.matches)return; cards.forEach(other=>{if(other!==card)stop(other)}); video.muted=true; const result=video.play(); if(result&&typeof result.then==='function')result.then(()=>{ if(!video.paused&&visible())card.classList.add('is-playing'); }).catch(()=>card.classList.remove('is-playing')); else card.classList.add('is-playing'); } cards.forEach(card=>{ card.addEventListener('pointerenter',e=>{if(e.pointerType==='mouse'||e.pointerType==='pen')play(card)}); card.addEventListener('pointerleave',()=>stop(card)); card.addEventListener('focusin',()=>play(card)); card.addEventListener('focusout',()=>stop(card)); }); if('IntersectionObserver' in window){ const observer=new IntersectionObserver(entries=>{ if(fine.matches)return; entries.forEach(entry=>{ if(entry.isIntersecting&&entry.intersectionRatio>=.5&&visible())play(entry.target); else stop(entry.target); }); },{threshold:[0,.5,1]}); cards.forEach(card=>observer.observe(card)); } function stopAll(){cards.forEach(stop)} window.addEventListener('hashchange',stopAll); document.addEventListener('visibilitychange',()=>{if(document.hidden)stopAll()}); if(reduced.addEventListener)reduced.addEventListener('change',()=>{if(reduced.matches)stopAll()}); } if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init); else init(); })();
← Back to Publication Design

Publication Design Projects

☘

Selected illustration work spanning character design, fantasy art, storytelling, and visual exploration.

← Back to Comic Art & Coloring

Comic Art & Coloring Projects

☘

Selected illustration work spanning character design, fantasy art, storytelling, and visual exploration.

← Back to Projects

Kid's Book

☘

Digital Illustration

Type Poster

Project Details

Fantasy illustration exploring nature, mythology, and atmosphere.

Detail Image

Software

Procreate
Adobe Photoshop
Adobe Illustrator

Showcase

← Back to Projects

Type Poster

☘

Digital Illustration

Type Poster

Project Details

Fantasy illustration exploring nature, mythology, and atmosphere.

Detail Image

Software

Procreate
Adobe Photoshop
Adobe Illustrator

Showcase

← Back to Projects

Zoo Brochure

☘

Digital Illustration

Zoo Brochure

Project Details

Fantasy illustration exploring nature, mythology, and atmosphere.

Detail Image

Software

ProcreateAdobe PhotoshopAdobe Illustrator

Showcase

← Back to Projects

Solar Eclipse Event Poster

☘

Digital Illustration

Solar Eclipse Event Poster

Project Details

Fantasy illustration exploring nature, mythology, and atmosphere.

Detail Image

Software

Procreate
Adobe Photoshop
Adobe Illustrator

Showcase