gsap.registerPlugin(Flip); const q=selector=>document.querySelector(selector),qa=selector=>Array.from(document.querySelectorAll(selector)); const studyAbort=new AbortController(),studyCleanup=[]; const listen=(target,type,handler)=>target.addEventListener(type,handler,{signal:studyAbort.signal}); const preference=matchMedia('(prefers-reduced-motion: reduce)'),staticControl=q('#static-mode'); staticControl.checked=preference.matches;staticControl.disabled=preference.matches; const isStatic=()=>staticControl.checked||preference.matches; let applyMode=()=>{}; listen(staticControl,'change',()=>applyMode()); listen(preference,'change',()=>{staticControl.checked=preference.matches;staticControl.disabled=preference.matches;applyMode();}); listen(window,'pagehide',()=>{studyCleanup.forEach(cleanup=>cleanup());studyAbort.abort();}); const reading=text=>q('#reading').textContent=text; const tiles=qa('.filter-tile'),filters=['all','A','B','C','none'];let selected='all',filterTween=null,filterGeneration=0; function filterTo(category){if(filterTween){filterTween.progress(1).kill();filterTween=null;}const state=Flip.getState(tiles);selected=category;const token=++filterGeneration; const visible=tiles.filter(tile=>category==='all'||tile.dataset.group===category);tiles.forEach(tile=>tile.style.display=visible.includes(tile)?'flex':'none'); filters.forEach((value,i)=>q('#filter-'+i).setAttribute('aria-pressed',String(value===category)));q('#empty').hidden=visible.length!==0;reading(visible.length+'개 항목 · 선택 '+(category==='all'?'전체':category==='none'?'없음':category)); if(isStatic()){gsap.set(tiles,{clearProps:'transform,opacity'});return;} filterTween=Flip.from(state,{duration:.55,ease:'power1.inOut',absolute:true,onEnter:entering=>gsap.fromTo(entering,{opacity:0,scale:.7},{opacity:1,scale:1,duration:.3}),onLeave:leaving=>gsap.to(leaving,{opacity:0,scale:.7,duration:.3}),onComplete:()=>{if(token===filterGeneration)gsap.set(visible,{clearProps:'transform,opacity'});}});} filters.forEach((value,i)=>listen(q('#filter-'+i),'click',()=>filterTo(value)));listen(q('#reset'),'click',()=>filterTo('all'));applyMode=()=>filterTo(selected);studyCleanup.push(()=>filterTween?.kill());filterTo('all');