diff --git a/dist/assets/CutoutPreparation-9rCu4swh.js b/dist/assets/CutoutPreparation-DTym6CdH.js similarity index 98% rename from dist/assets/CutoutPreparation-9rCu4swh.js rename to dist/assets/CutoutPreparation-DTym6CdH.js index 648b27e..7f9e217 100644 --- a/dist/assets/CutoutPreparation-9rCu4swh.js +++ b/dist/assets/CutoutPreparation-DTym6CdH.js @@ -1 +1 @@ -import{t as e}from"./index-BYcEjj7E.js";function t(e,t,n){if(!Number.isInteger(t)||!Number.isInteger(n)||t<1||n<1||e.length!==t*n)throw Error(`누끼 크기를 읽지 못했어요. 다른 사진으로 다시 시도해 주세요.`);let r=t,i=n,a=0,o=0,s=0,c=0;for(let n=0;n=13){let e=n%t,c=Math.floor(n/t);r=Math.min(r,e),i=Math.min(i,c),a=Math.max(a,e+1),o=Math.max(o,c+1),s++}if(!s||c===e.length)throw Error(`강아지와 배경을 구분하지 못했어요. 다른 사진으로 다시 시도해 주세요.`);let l=new Uint8Array(e.length),u=new Int32Array(s),d=[];for(let r=0;r=t||d<0||d>=n)continue;let f=d*t+c;!l[f]&&e[f]>=13&&(l[f]=1,u[a++]=f)}}d.push(a)}let f=d.filter(e=>e>=s*.05).length,p=[];f>1&&p.push(`multiple-foreground`),s<16&&p.push(`tiny-foreground`);let m=Math.ceil(Math.max(t,n)*.01);return{bounds:{x0:Math.max(0,r-m),y0:Math.max(0,i-m),x1:Math.min(t,a+m),y1:Math.min(n,o+m)},largeComponentCount:f,warnings:p}}var n=class{worker=null;disposed=!1;pending=null;onStatus;constructor(e=()=>{}){this.onStatus=e}run(e,t){return this.disposed?Promise.reject(Error(`누끼 준비가 종료됐어요.`)):(this.cancel(),t.throwIfAborted(),new Promise((n,r)=>{let i=()=>this.cancel(),a={snapshot:e,signal:t,abort:i,fallback:!1,resolve:n,reject:r};this.pending=a,t.addEventListener(`abort`,i,{once:!0}),this.send(a).catch(e=>{this.pending===a&&this.fail(e)})}))}cancel(){let e=this.pending;this.pending=null,this.worker?.terminate(),this.worker=null,e&&(e.signal.removeEventListener(`abort`,e.abort),e.reject(new DOMException(`사진 준비를 취소했어요.`,`AbortError`)))}dispose(){this.disposed=!0,this.cancel()}fail(e){let t=this.pending;t&&(this.pending=null,this.worker?.terminate(),this.worker=null,t.signal.removeEventListener(`abort`,t.abort),t.reject(e instanceof Error?e:Error(`누끼를 준비하지 못했어요.`)))}async send(e){let n=await createImageBitmap(e.snapshot.bitmap);if(this.pending!==e||e.signal.aborted){n.close();return}let r;try{r=new Worker(new URL(`/assets/cutout.worker-D417j0Nw.js`,``+import.meta.url),{type:`module`})}catch(e){throw n.close(),e}this.worker=r,r.onmessage=n=>{if(this.worker!==r||this.pending!==e||n.data.id!==e.snapshot.requestId)return;let i=n.data;if(i.type===`status`){this.onStatus(i.id,i.message);return}if(r.terminate(),this.worker=null,i.type===`fallback`){if(e.fallback){this.fail(Error(`이 기기에서 누끼를 계산하지 못했어요.`));return}e.fallback=!0,this.send(e).catch(t=>{this.pending===e&&this.fail(t)});return}if(i.type===`error`){this.fail(Error(i.message));return}try{if(i.width!==e.snapshot.width||i.height!==e.snapshot.height)throw Error(`누끼 좌표가 사진과 맞지 않아요.`);let n=new Uint8Array(i.alpha),r=t(n,i.width,i.height);this.pending=null,e.signal.removeEventListener(`abort`,e.abort),e.resolve({requestId:i.id,width:i.width,height:i.height,alpha:n,...r,run:i.run})}catch(e){this.fail(e)}},r.onerror=t=>{this.worker===r&&this.pending===e&&this.fail(Error(t.message||`누끼 작업이 중단됐어요.`))},r.onmessageerror=()=>{this.worker===r&&this.pending===e&&this.fail(Error(`누끼 결과를 읽지 못했어요.`))};try{r.postMessage({type:`infer`,id:e.snapshot.requestId,image:n,forceWasm:e.fallback},[n])}catch(e){throw n.close(),e}}},r=class{nextId=0;pending=null;disposed=!1;results=new Set;provider=new n((e,t)=>{this.pending?.id===e&&!this.pending.controller.signal.aborted&&this.pending.onProgress(t)});async prepare(n,r=()=>{},o){if(this.disposed)throw Error(`누끼 준비가 종료됐어요.`);this.cancel(),o?.throwIfAborted();let s=new AbortController,c={id:++this.nextId,controller:s,onProgress:r};this.pending=c;let l=()=>s.abort(o?.reason);o?.addEventListener(`abort`,l,{once:!0});let u=null,d=``,f=``,p=new Image,m=new Image,h=!1,g=null,_=()=>{if(!h){h=!0;for(let e of[p,m])e.onload=e.onerror=null,e.removeAttribute(`src`);d&&URL.revokeObjectURL(d),f&&URL.revokeObjectURL(f),g&&this.results.delete(g)}},v=document.createElement(`canvas`);try{r(`사진 크기와 방향을 준비하는 중…`),u=await e(n,c.id,s.signal),s.signal.throwIfAborted();let o=await this.provider.run(u,s.signal);s.signal.throwIfAborted(),v.width=u.width,v.height=u.height;let l=v.getContext(`2d`);if(!l)throw Error(`사진 미리보기를 준비할 수 없어요.`);l.drawImage(u.bitmap,0,0);let h=await i(v);s.signal.throwIfAborted();let y=l.getImageData(0,0,v.width,v.height),b=new Uint8Array(o.alpha.length);for(let e=0;ee.toBlob(e=>{!e||e.type!==`image/png`?n(Error(`PNG 사진 미리보기를 만들지 못했어요.`)):t(e)},`image/png`))}function a(e,t,n){return new Promise((r,i)=>{let a=()=>{e.onload=e.onerror=null,n.removeEventListener(`abort`,o)},o=()=>{a(),i(new DOMException(`사진 준비를 취소했어요.`,`AbortError`))};e.onload=()=>{a(),r()},e.onerror=()=>{a(),i(Error(`PNG 사진 미리보기를 읽지 못했어요.`))},n.addEventListener(`abort`,o,{once:!0}),n.aborted?o():e.src=t})}export{r as CutoutPreparation}; \ No newline at end of file +import{t as e}from"./index-DoRt0pZc.js";function t(e,t,n){if(!Number.isInteger(t)||!Number.isInteger(n)||t<1||n<1||e.length!==t*n)throw Error(`누끼 크기를 읽지 못했어요. 다른 사진으로 다시 시도해 주세요.`);let r=t,i=n,a=0,o=0,s=0,c=0;for(let n=0;n=13){let e=n%t,c=Math.floor(n/t);r=Math.min(r,e),i=Math.min(i,c),a=Math.max(a,e+1),o=Math.max(o,c+1),s++}if(!s||c===e.length)throw Error(`강아지와 배경을 구분하지 못했어요. 다른 사진으로 다시 시도해 주세요.`);let l=new Uint8Array(e.length),u=new Int32Array(s),d=[];for(let r=0;r=t||d<0||d>=n)continue;let f=d*t+c;!l[f]&&e[f]>=13&&(l[f]=1,u[a++]=f)}}d.push(a)}let f=d.filter(e=>e>=s*.05).length,p=[];f>1&&p.push(`multiple-foreground`),s<16&&p.push(`tiny-foreground`);let m=Math.ceil(Math.max(t,n)*.01);return{bounds:{x0:Math.max(0,r-m),y0:Math.max(0,i-m),x1:Math.min(t,a+m),y1:Math.min(n,o+m)},largeComponentCount:f,warnings:p}}var n=class{worker=null;disposed=!1;pending=null;onStatus;constructor(e=()=>{}){this.onStatus=e}run(e,t){return this.disposed?Promise.reject(Error(`누끼 준비가 종료됐어요.`)):(this.cancel(),t.throwIfAborted(),new Promise((n,r)=>{let i=()=>this.cancel(),a={snapshot:e,signal:t,abort:i,fallback:!1,resolve:n,reject:r};this.pending=a,t.addEventListener(`abort`,i,{once:!0}),this.send(a).catch(e=>{this.pending===a&&this.fail(e)})}))}cancel(){let e=this.pending;this.pending=null,this.worker?.terminate(),this.worker=null,e&&(e.signal.removeEventListener(`abort`,e.abort),e.reject(new DOMException(`사진 준비를 취소했어요.`,`AbortError`)))}dispose(){this.disposed=!0,this.cancel()}fail(e){let t=this.pending;t&&(this.pending=null,this.worker?.terminate(),this.worker=null,t.signal.removeEventListener(`abort`,t.abort),t.reject(e instanceof Error?e:Error(`누끼를 준비하지 못했어요.`)))}async send(e){let n=await createImageBitmap(e.snapshot.bitmap);if(this.pending!==e||e.signal.aborted){n.close();return}let r;try{r=new Worker(new URL(`/assets/cutout.worker-D417j0Nw.js`,``+import.meta.url),{type:`module`})}catch(e){throw n.close(),e}this.worker=r,r.onmessage=n=>{if(this.worker!==r||this.pending!==e||n.data.id!==e.snapshot.requestId)return;let i=n.data;if(i.type===`status`){this.onStatus(i.id,i.message);return}if(r.terminate(),this.worker=null,i.type===`fallback`){if(e.fallback){this.fail(Error(`이 기기에서 누끼를 계산하지 못했어요.`));return}e.fallback=!0,this.send(e).catch(t=>{this.pending===e&&this.fail(t)});return}if(i.type===`error`){this.fail(Error(i.message));return}try{if(i.width!==e.snapshot.width||i.height!==e.snapshot.height)throw Error(`누끼 좌표가 사진과 맞지 않아요.`);let n=new Uint8Array(i.alpha),r=t(n,i.width,i.height);this.pending=null,e.signal.removeEventListener(`abort`,e.abort),e.resolve({requestId:i.id,width:i.width,height:i.height,alpha:n,...r,run:i.run})}catch(e){this.fail(e)}},r.onerror=t=>{this.worker===r&&this.pending===e&&this.fail(Error(t.message||`누끼 작업이 중단됐어요.`))},r.onmessageerror=()=>{this.worker===r&&this.pending===e&&this.fail(Error(`누끼 결과를 읽지 못했어요.`))};try{r.postMessage({type:`infer`,id:e.snapshot.requestId,image:n,forceWasm:e.fallback},[n])}catch(e){throw n.close(),e}}},r=class{nextId=0;pending=null;disposed=!1;results=new Set;provider=new n((e,t)=>{this.pending?.id===e&&!this.pending.controller.signal.aborted&&this.pending.onProgress(t)});async prepare(n,r=()=>{},o){if(this.disposed)throw Error(`누끼 준비가 종료됐어요.`);this.cancel(),o?.throwIfAborted();let s=new AbortController,c={id:++this.nextId,controller:s,onProgress:r};this.pending=c;let l=()=>s.abort(o?.reason);o?.addEventListener(`abort`,l,{once:!0});let u=null,d=``,f=``,p=new Image,m=new Image,h=!1,g=null,_=()=>{if(!h){h=!0;for(let e of[p,m])e.onload=e.onerror=null,e.removeAttribute(`src`);d&&URL.revokeObjectURL(d),f&&URL.revokeObjectURL(f),g&&this.results.delete(g)}},v=document.createElement(`canvas`);try{r(`사진 크기와 방향을 준비하는 중…`),u=await e(n,c.id,s.signal),s.signal.throwIfAborted();let o=await this.provider.run(u,s.signal);s.signal.throwIfAborted(),v.width=u.width,v.height=u.height;let l=v.getContext(`2d`);if(!l)throw Error(`사진 미리보기를 준비할 수 없어요.`);l.drawImage(u.bitmap,0,0);let h=await i(v);s.signal.throwIfAborted();let y=l.getImageData(0,0,v.width,v.height),b=new Uint8Array(o.alpha.length);for(let e=0;ee.toBlob(e=>{!e||e.type!==`image/png`?n(Error(`PNG 사진 미리보기를 만들지 못했어요.`)):t(e)},`image/png`))}function a(e,t,n){return new Promise((r,i)=>{let a=()=>{e.onload=e.onerror=null,n.removeEventListener(`abort`,o)},o=()=>{a(),i(new DOMException(`사진 준비를 취소했어요.`,`AbortError`))};e.onload=()=>{a(),r()},e.onerror=()=>{a(),i(Error(`PNG 사진 미리보기를 읽지 못했어요.`))},n.addEventListener(`abort`,o,{once:!0}),n.aborted?o():e.src=t})}export{r as CutoutPreparation}; \ No newline at end of file diff --git a/dist/assets/OriginalGlassRenderer-DLs_logl.js b/dist/assets/OriginalGlassRenderer-BAqBMSXc.js similarity index 99% rename from dist/assets/OriginalGlassRenderer-DLs_logl.js rename to dist/assets/OriginalGlassRenderer-BAqBMSXc.js index 33dc3f4..44d75b4 100644 --- a/dist/assets/OriginalGlassRenderer-DLs_logl.js +++ b/dist/assets/OriginalGlassRenderer-BAqBMSXc.js @@ -1,4 +1,4 @@ -import{a as e,c as t,d as n,f as r,h as i,i as a,l as o,m as s,n as c,o as l,p as u,r as ee,u as d}from"./index-BYcEjj7E.js";var f=`uniform sampler2D uSceneTexture,uSceneDepth; +import{a as e,c as t,d as n,f as r,h as i,i as a,l as o,m as s,n as c,o as l,p as u,r as ee,u as d}from"./index-DoRt0pZc.js";var f=`uniform sampler2D uSceneTexture,uSceneDepth; uniform sampler2D uProtectionDepthMap; uniform mat4 uContentViewProjection,uContentInverseViewProjection; uniform mat4 uPetWorldToLocal; diff --git a/dist/assets/PhysicalGlassComparison-B37yDBlH.js b/dist/assets/PhysicalGlassComparison-HEVBf_iN.js similarity index 95% rename from dist/assets/PhysicalGlassComparison-B37yDBlH.js rename to dist/assets/PhysicalGlassComparison-HEVBf_iN.js index da79c7d..12f5b98 100644 --- a/dist/assets/PhysicalGlassComparison-B37yDBlH.js +++ b/dist/assets/PhysicalGlassComparison-HEVBf_iN.js @@ -1 +1 @@ -import{a as e,d as t,h as n,l as r,n as i,o as a,s as o,u as s}from"./index-BYcEjj7E.js";var c=class{renderer;background;targetA=new n(1,1,{type:e});targetB=new n(1,1,{type:e});blitMaterial=new o({toneMapped:!1,depthTest:!1,depthWrite:!1});blit=new a(new s(2,2),this.blitMaterial);blitScene=new t;blitCamera=new r(-1,1,1,-1,0,1);disposed=!1;constructor(e,t){this.renderer=e,this.background=t,this.blitScene.add(this.blit)}resize(e,t){for(let n of[this.targetA,this.targetB])(n.width!==e||n.height!==t)&&n.setSize(e,t)}composite(e,t){this.renderer.setRenderTarget(null),this.renderer.setScissorTest(!1);let n=this.renderer.getClearColor(new i),r=this.renderer.getClearAlpha();this.renderer.setClearColor(this.background,1),this.renderer.clear(),this.renderer.setClearColor(n,r),this.renderer.setScissorTest(!0);try{for(let n=0;nspan{font-size:23px;font-weight:400;line-height:1}.upload{cursor:pointer;border-radius:16px;position:relative}.upload input[type=file],.sr-only{clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;position:absolute!important;overflow:hidden!important}.upload:focus-within{outline-offset:4px;outline:3px solid #6b439d}main{grid-template-columns:minmax(0,1fr) 366px;align-items:start;gap:28px;padding:0 44px;display:grid}.visual-column{min-width:0;position:sticky;top:20px}.photo-mat{background:var(--cream);border:1px solid #d0bddf;border-radius:28px;padding:20px 20px 0;box-shadow:0 6px #d3c4e3,0 16px 32px #70508b0d}.preview-heading{justify-content:space-between;align-items:center;gap:12px;margin-bottom:15px;display:flex}.eyebrow{letter-spacing:1.8px;color:#79628e;margin:0 0 5px;font-size:12px;font-weight:400}.preview-chip{color:#71558e;background:#f0e5ff;border:1px solid #dfcdec;border-radius:18px;padding:7px 11px;font-size:12px;line-height:1.25}.stage{background:#f7f0e5;border:1px solid #e4d9eb;border-radius:16px;height:clamp(410px,62vh,740px);position:relative;overflow:hidden}#canvas-wrap{touch-action:none;border-radius:inherit;position:absolute;inset:0}#canvas-wrap:focus-visible{outline-offset:-4px}#canvas-wrap canvas{cursor:grab;border-radius:inherit;width:100%;height:100%;display:block}#canvas-wrap canvas.is-dragging{cursor:grabbing}#empty{z-index:1;text-align:center;pointer-events:none;color:var(--muted);background:#f7f0e5ed;flex-direction:column;justify-content:center;align-items:center;gap:16px;padding:24px;display:flex;position:absolute;inset:0}#empty strong{letter-spacing:-.6px;color:var(--ink);font-size:clamp(19px,2vw,26px)}#empty>span:last-child{font-size:14px;line-height:1.8}.empty-star{color:#a082bf;font-size:62px;line-height:1.2}#hint{color:#665177;text-align:center;pointer-events:none;background:#fffbf2ed;border:1px solid #d4c2e6;border-radius:25px;width:max-content;max-width:calc(100% - 28px);margin:0;padding:10px 16px;font-size:13px;transition:opacity .25s;position:absolute;bottom:18px;left:50%;transform:translate(-50%)}.photo-caption{color:#7c6a88;justify-content:space-between;align-items:center;gap:12px;min-height:55px;padding:3px 4px;font-size:13px;display:flex}.caption-spark{color:#97b;letter-spacing:5px;white-space:nowrap;font-size:26px}.processing-card{align-items:center;gap:14px;padding:22px 4px 10px;display:flex}.processing-copy{flex:1;min-width:0}#status{overflow-wrap:anywhere;margin:0;font-size:14px}#depth-provenance{color:var(--muted);overflow-wrap:anywhere;margin:6px 0 0;font-size:12px;line-height:1.6}#ai-depth{flex:none;padding:9px 14px;font-size:13px}.editor-heading{justify-content:space-between;align-items:center;margin:0 0 18px;padding:3px 4px;display:flex}.editor-heading h1{letter-spacing:-.8px;margin:5px 0 0;font-size:25px;line-height:1.3}.editor-sticker{color:#8e573c;background:var(--apricot);border:1px solid #dfb49c;border-radius:15px;place-items:center;width:47px;height:47px;font-size:29px;display:grid;transform:rotate(9deg);box-shadow:0 3px #dbc9ca}aside{background:#faf6ff;border:1px solid #d4c1e6;border-radius:28px;min-width:0;padding:23px 22px;box-shadow:0 5px #d8cbea}#tool-tabs{background:#eadff4;border:1px solid #dfd0ec;border-radius:18px;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px;margin-bottom:20px;padding:5px;display:grid}#tool-tabs button{color:#715b87;min-width:0;min-height:44px;box-shadow:none;background:0 0;border:1px solid #0000;border-radius:12px;justify-content:center;align-items:center;gap:6px;padding:8px 3px;font-size:14px;font-weight:400;display:flex}#tool-tabs button[aria-selected=true]{background:var(--cream);color:#573672;border-color:#d5c4e5;box-shadow:0 2px #ccb8dd}#tool-tabs button>span{font-size:20px;font-weight:400;line-height:1}.tool-panel{gap:20px;min-width:0;display:grid}#pattern-cards{grid-template-columns:repeat(3,minmax(0,1fr));gap:9px;display:grid}.pattern-card{background:#fffcf7;border:2px solid #e5d9ed;border-radius:16px;flex-direction:column;align-items:stretch;min-width:0;padding:7px 6px 10px;display:flex;box-shadow:0 3px #e3d7eb}.pattern-card[aria-pressed=true]{background:#eee1ff;border-color:#8057aa;animation:.22s ease-out selection-pop;box-shadow:0 3px #9875b7}.pattern-swatch{border:1px solid #b7a6bd;border-radius:9px;height:75px;margin-bottom:9px;display:block;position:relative;overflow:hidden}.swatch-gobang{background-color:#cab7df;background-image:repeating-linear-gradient(0deg,#0000 0 17px,#7d69825c 18px,#fffbf2bf 20px,#ac94b369 23px),repeating-linear-gradient(90deg,#0000 0 17px,#7d69825c 18px,#fffbf2bf 20px,#ac94b369 23px),linear-gradient(135deg,#b3abd3,#e6cbb5 50%,#bcbad6)}.swatch-color{background-color:#d3b1cd;background-image:conic-gradient(#d8b898 25%,#796880 0 50%,#ebd9c1 0 75%,#b39db9 0);background-size:37px 37px}.swatch-fine{background-color:#c8bfd6;background-image:repeating-linear-gradient(0deg,#0000 0 8px,#f8f0e6bf 9px,#927caa80 11px),repeating-linear-gradient(90deg,#0000 0 8px,#f8f0e6bf 9px,#927caa80 11px),linear-gradient(125deg,#c3b0da,#edd5bf)}.pattern-name{letter-spacing:-.3px;font-size:14px;font-weight:400}.pattern-detail{color:#6d587b;margin-top:3px;font-size:12px;line-height:1.4}.control-help{color:var(--muted);word-break:keep-all;margin:-8px 0 0;font-size:12px;line-height:1.7}.range-control{gap:4px;font-size:14px;font-weight:400;display:grid}.range-control>span:first-child{justify-content:space-between;align-items:center;gap:12px;display:flex}output{color:#744fa0;text-align:center;font-variant-numeric:tabular-nums;background:#eae0f5;border-radius:8px;min-width:38px;padding:3px 8px;font-size:13px;font-weight:400}input[type=range]{appearance:none;cursor:pointer;accent-color:#8660ad;background:0 0;width:100%;min-width:0;min-height:44px;margin:0}input[type=range]::-webkit-slider-runnable-track{background:#dac9eb;border-radius:8px;height:7px}input[type=range]::-webkit-slider-thumb{appearance:none;background:#8861b3;border:3px solid #fffbf2;border-radius:50%;width:23px;height:23px;margin-top:-8px;box-shadow:0 0 0 1px #9d7fb5,0 2px #b59bc9}input[type=range]::-moz-range-track{background:#dac9eb;border-radius:8px;height:7px}input[type=range]::-moz-range-thumb{background:#8861b3;border:3px solid #fffbf2;border-radius:50%;width:18px;height:18px;box-shadow:0 0 0 1px #9d7fb5}.range-ends{color:#7a6a87;justify-content:space-between;margin-top:-8px;font-size:12px;font-weight:400;display:flex}.inline-control{justify-content:space-between;align-items:center;gap:15px;font-size:14px;font-weight:400;display:flex}.inline-control select{width:120px}.core-optics{display:grid}.quiet-button,.tactile-button{min-height:44px;padding:11px 16px;font-size:14px;font-weight:400}.quiet-button{background:#fffbf2;box-shadow:0 2px #ddcfe7}.tactile-button{color:#593979;background:#e1cdfa;border:1px solid #aa88c6;box-shadow:0 3px #b69acb}.section-intro{text-align:center;padding:12px 0 4px}.section-intro h2{margin:8px 0;font-size:18px}.section-intro p{color:var(--muted);margin:0;font-size:14px;line-height:1.8}.intro-symbol{color:#9b6347;background:#f5e2d1;border-radius:20px;place-items:center;width:64px;height:64px;margin:0 auto 13px;font-size:36px;display:grid}.section-intro.compact{text-align:left;padding:0}.section-intro.compact h2{margin-top:0}details{border-top:1px solid #dfd2e8;margin-top:24px}summary{cursor:pointer;justify-content:space-between;align-items:center;gap:12px;min-height:52px;padding:8px 2px;font-size:14px;font-weight:400;list-style:none;display:flex}summary::-webkit-details-marker{display:none}summary>span{color:#8f70a8;font-size:21px;font-weight:400}details[open]>summary>span{transform:rotate(45deg)}.details-content{gap:14px;padding:8px 0 14px;display:grid}.details-content>label{gap:6px;font-size:14px;display:grid}.details-content input[type=number],select{background:#fffcf8;border:1px solid #cdbadb;border-radius:12px;width:100%;min-width:0;padding:10px 12px;font-size:14px}#test-photo{max-width:100%}.sample-strip{grid-template-columns:repeat(5,minmax(0,1fr));gap:5px;display:grid}.sample-strip img{aspect-ratio:1;object-fit:cover;border:2px solid #fff;border-radius:10px;width:100%;box-shadow:0 2px #d9c9e5}.local-note{text-align:center;color:var(--muted);margin:16px 0 0;font-size:12px;line-height:1.7}#developer-tools{margin-top:0}#developer-tools>summary{color:#79678b;font-size:13px;font-weight:400}#developer-tools .upload{text-align:center;background:#efe6f9;border:1px solid #cdbadb;min-height:44px;padding:10px 12px;font-size:14px;display:grid}#developer-tools details{margin-top:0}#developer-tools .control-note{color:#73637e;margin:0;font-size:12px;line-height:1.65}.reference-strip{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;min-width:0;display:grid}.reference-strip figure{background:#fffcf8;border:1px solid #d7c6e4;border-radius:12px;flex-direction:column;gap:5px;min-width:0;margin:0;padding:6px;display:flex}.reference-strip img{object-fit:contain;border-radius:7px;width:100%;height:120px;display:block}.reference-strip figcaption{text-align:center;color:#746180;font-size:12px}#reference-status{color:#9b3c38;grid-column:1/-1;margin:0;font-size:12px}#depth-inspection-canvas{cursor:crosshair;width:100%;height:auto;margin:10px 0}#depth-inspection pre,#depth-debug{white-space:pre-wrap;overflow-wrap:anywhere;color:#6b577b;max-width:100%;font-size:12px}.depth-coordinates{grid-template-columns:1fr 1fr;gap:8px;display:grid}.depth-coordinates label{gap:5px;font-size:13px;display:grid}.depth-coordinates input{width:100%;min-width:0}.app-footer{letter-spacing:.4px;color:#73607f;justify-content:space-between;gap:20px;padding:28px 48px 22px;font-size:12px;display:flex}.app-footer>span:last-child{font-style:italic}@keyframes selection-pop{0%{transform:scale(.96)}65%{transform:scale(1.035)}to{transform:scale(1)}}@media (hover:hover){button:not(:disabled):hover{filter:brightness(.98)}.pattern-card:hover{border-color:#aa88c6}.primary-upload:hover{background:#ffcca6}}@media (width>=1600px){.stage{height:740px}}@media (width<=1100px){.app-header{padding:24px 28px}main{grid-template-columns:minmax(0,1fr) 340px;gap:22px;padding:0 28px}aside{padding:21px 18px}.photo-mat{padding:16px 16px 0}.stage{height:clamp(410px,61vh,660px)}.processing-card{flex-direction:column;align-items:flex-start;gap:10px}.preview-heading .eyebrow{letter-spacing:1px}.preview-chip{display:none}}@media (width<=850px){.app-header{padding:24px 24px 22px}main{flex-direction:column;gap:18px;padding:0 24px;display:flex}.visual-column{width:100%;position:static}.photo-mat{padding:18px 18px 0}.stage{height:clamp(360px,60vh,610px)}aside{width:100%;padding:23px 24px}.editor-heading{margin-bottom:17px}.processing-card{flex-direction:row;align-items:center;padding:20px 4px 0}.pattern-swatch{height:88px}.tool-panel{gap:22px}.app-footer{padding:24px 28px}.preview-chip{display:inline-block}.header-note{display:none}}@media (width<=480px){.app-header{gap:12px;padding:21px 17px 19px}.brand{letter-spacing:-1px;gap:7px;font-size:24px}.brand-mark{font-size:35px}.brand-dot{font-size:31px}.primary-upload{border-radius:14px;min-height:44px;padding:9px 12px;font-size:13px}.primary-upload>span{font-size:20px}main{gap:17px;padding:0 12px}.photo-mat{border-radius:23px;padding:11px 11px 0}.preview-heading{gap:6px;margin:2px 2px 11px}.eyebrow{letter-spacing:1.2px;font-size:12px}.preview-chip{padding:5px 8px;font-size:12px}.stage{border-radius:13px;height:clamp(320px,49svh,455px)}.photo-caption{min-height:45px;padding:0 4px;font-size:12px}.caption-spark{font-size:22px}#hint{padding:8px 10px;font-size:12px;bottom:13px}#empty{gap:13px;padding:20px}#empty strong{font-size:19px}.empty-star{font-size:49px}.processing-card{flex-direction:column;align-items:flex-start;gap:9px;padding:19px 5px 0}#status{font-size:13px}#ai-depth{min-height:44px;padding:8px 12px;font-size:12px}aside{border-radius:24px;padding:21px 17px}.editor-heading h1{font-size:23px}.editor-sticker{border-radius:12px;width:40px;height:40px;font-size:26px}.editor-heading .eyebrow{font-size:12px}.pattern-swatch{height:76px}.pattern-detail{font-size:12px}.pattern-name{font-size:14px}#pattern-cards{gap:8px}.tool-panel{gap:20px}.app-footer{padding:22px 19px;font-size:12px}.app-footer>span:last-child{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition:none!important;animation:none!important}button:not(:disabled):active,.upload:active{transform:none}}html,body,#app{width:100%;min-height:100%}body{overflow:hidden}#app{max-width:none}#experience{width:100%;height:100dvh;min-height:320px;margin:0;padding:0;display:block;position:relative;overflow:hidden}#experience .stage{background:var(--room);border:0;border-radius:0;width:100%;height:100%;position:absolute;inset:0}#canvas-wrap,#canvas-wrap canvas{border-radius:0}#canvas-wrap{transition:opacity .65s}#experience:not([data-flow=ready]) #canvas-wrap{opacity:0;pointer-events:none}#experience:not([data-flow=ready]) #hint{visibility:hidden}.scene-toolbar{z-index:2;padding:max(18px,env(safe-area-inset-top)) max(22px,env(safe-area-inset-right)) 12px max(22px,env(safe-area-inset-left));pointer-events:none;justify-content:space-between;align-items:center;gap:16px;display:flex;position:absolute;top:0;left:0;right:0}.scene-toolbar>*{pointer-events:auto}.scene-brand{color:var(--ink);letter-spacing:-.5px;font-size:15px;font-weight:400;text-decoration:none}.scene-actions{align-items:center;gap:7px;display:flex}.scene-actions button,.scene-actions .upload{border:1px solid var(--line);background:var(--cream);min-height:44px;color:var(--ink);border-radius:6px;place-items:center;padding:8px 13px;font-size:14px;display:grid;box-shadow:0 1px 3px #35261510}#experience[data-flow=entry] .scene-brand,#experience:not([data-flow=ready]) .scene-actions>.upload{visibility:hidden}.welcome,.flow-overlay{background:var(--room);text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:70px 24px 36px;display:flex;position:absolute;inset:0;overflow:auto}.welcome h1{letter-spacing:0;margin:8px 0 15px;font-family:inherit;font-size:clamp(30px,4.5vw,48px);font-weight:400;line-height:1.35}.entry-kicker{color:var(--muted);letter-spacing:.8px;margin:19px 0 0;font-size:13px}.welcome .primary-upload{color:#fffaf0;background:#6e4932;border:1px solid #63422d;border-radius:5px;min-width:208px;margin:0;padding:12px 23px;font-size:15px;box-shadow:0 2px 3px #4223111c}.entry-samples{min-height:44px;color:var(--muted);text-underline-offset:4px;background:0 0;border:0;border-radius:0;margin:10px 0 0;padding:8px 14px;font-size:13px;text-decoration:underline}.entry-privacy{color:var(--muted);margin:27px 0 0;font-size:12px}.entry-door{border:3px solid #79583e;border-bottom-width:7px;border-radius:2px;width:39px;height:59px;padding:3px;position:relative}.entry-door:before{content:"";background:#a38851;border:1px solid #735d35;width:4px;height:8px;position:absolute;bottom:15px;right:-3px}.entry-door>span{opacity:.6;background:#b8c0b3;border:1px solid #8b967f;width:100%;height:37px;display:block}.flow-overlay{z-index:1}.flow-photo{object-fit:contain;border:6px solid var(--cream);width:auto;max-width:min(43vw,190px);height:auto;max-height:27svh;margin-bottom:30px;display:block;box-shadow:0 2px 8px #49341d1f}.flow-overlay h2{letter-spacing:-.6px;word-break:keep-all;max-width:500px;margin:0;font-size:clamp(20px,3vw,27px);font-weight:400;line-height:1.6}#flow-detail{max-width:470px;color:var(--muted);overflow-wrap:anywhere;margin:13px 0 23px;font-size:14px;line-height:1.8}.flow-actions{flex-wrap:wrap;justify-content:center;align-items:center;gap:10px;max-width:450px;display:flex}.flow-actions button,.flow-actions .upload{border:1px solid var(--line);background:var(--cream);border-radius:5px;min-height:44px;padding:10px 15px;font-size:14px}#flow-flat{background:0 0}#hint{bottom:max(25px,env(safe-area-inset-bottom));border:1px solid var(--line);background:var(--cream);max-width:calc(100% - 40px);color:var(--ink);border-radius:4px;padding:11px 18px;font-size:14px;line-height:1.65;box-shadow:0 2px 10px #382a1410}#hint strong{font-size:15px;font-weight:400;display:block}#hint .hint-secondary{color:var(--muted);font-size:12px;display:block}#settings-dialog{border:0;border-left:1px solid var(--line);background:var(--cream);width:min(410px,100%);max-width:100%;height:100dvh;max-height:100dvh;color:var(--ink);overscroll-behavior:contain;border-radius:0;margin:0 0 0 auto;padding:0}#settings-dialog::backdrop{background:#201a1366}#settings-dialog aside{width:100%;min-height:100%;padding:25px 24px max(24px,env(safe-area-inset-bottom));box-shadow:none;border:0;border-radius:0}#settings-dialog .editor-heading{margin-bottom:17px;padding:0}.editor-heading h2{letter-spacing:-.5px;margin:0;font-size:20px}#settings-close{background:0 0;border-radius:5px;padding:7px 12px;font-size:13px}.theme-setting{grid-template-columns:auto minmax(0,1fr);align-items:center;gap:20px;padding-bottom:22px;font-size:14px;display:grid}.theme-setting select{width:100%}#settings-dialog .processing-card{border-top:1px solid var(--line);flex-direction:column;align-items:stretch;margin-top:20px;padding-top:20px}#settings-dialog .processing-card button{width:100%}:root{--room:#f1ebff}:root[data-theme=wood]{color:#3e3429;--room:#e6dfcf;--ink:#3e3429;--muted:#726554;--cream:#f8f4e9;--purple:#705039;--lavender:#e8dfcf;--apricot:#e0d1b5;--line:#cfc3ad;--shadow:#b1a084;background:#e6dfcf}[data-theme=wood] button,[data-theme=wood] select,[data-theme=wood] .upload{border-radius:5px}[data-theme=wood] button:not(:disabled):active,[data-theme=wood] .upload:active{box-shadow:none;transform:translateY(1px)}[data-theme=wood] button:focus-visible,[data-theme=wood] select:focus-visible,[data-theme=wood] input:focus-visible,[data-theme=wood] summary:focus-visible,[data-theme=wood] a:focus-visible,[data-theme=wood] #canvas-wrap:focus-visible,[data-theme=wood] .upload:focus-within{outline-color:#765534}[data-theme=wood] aside{background:#f8f4e9}[data-theme=wood] #tool-tabs{background:0 0;border:0;border-bottom:1px solid #cfc3ad;border-radius:0;gap:0;padding:0}[data-theme=wood] #tool-tabs button{color:#756651;border-radius:0}[data-theme=wood] #tool-tabs button[aria-selected=true]{box-shadow:none;color:#3e3429;background:0 0;border:0;border-bottom:2px solid #785735}[data-theme=wood] .pattern-card{box-shadow:none;background:#faf7ed;border:1px solid #cfc3ad;border-radius:4px;padding:5px 5px 9px}[data-theme=wood] .pattern-card[aria-pressed=true]{background:#e9dfca;border:1px solid #725334;animation:none;box-shadow:inset 0 0 0 1px #725334}[data-theme=wood] .pattern-swatch{filter:saturate(.35)sepia(.12);border-color:#a99b84;border-radius:1px}[data-theme=wood] .pattern-detail{color:#6c5d47}[data-theme=wood] output{color:#614831;background:#e9e0ce;border-radius:3px}[data-theme=wood] input[type=range]{accent-color:#84633f}[data-theme=wood] input[type=range]::-webkit-slider-runnable-track{background:#d1c5ae;height:4px}[data-theme=wood] input[type=range]::-webkit-slider-thumb{background:#856344;width:20px;height:20px;margin-top:-8px;box-shadow:0 0 0 1px #a28967}[data-theme=wood] input[type=range]::-moz-range-track{background:#d1c5ae;height:4px}[data-theme=wood] input[type=range]::-moz-range-thumb{background:#856344;width:16px;height:16px;box-shadow:0 0 0 1px #a28967}[data-theme=wood] .range-ends,[data-theme=wood] #developer-tools>summary,[data-theme=wood] #developer-tools .control-note,[data-theme=wood] #depth-inspection pre,[data-theme=wood] #depth-debug,[data-theme=wood] .reference-strip figcaption{color:#726554}[data-theme=wood] .quiet-button,[data-theme=wood] .tactile-button{box-shadow:none;color:#584630;background:#ede4d2;border-color:#baa98d}[data-theme=wood] .intro-symbol{color:#816440;background:#e9dfcc;border-radius:4px}[data-theme=wood] details{border-color:#d6cbb9}[data-theme=wood] summary>span{color:#8b7657}[data-theme=wood] .details-content input[type=number],[data-theme=wood] select{background:#fffdf6;border-color:#cfc3ad}[data-theme=wood] .sample-strip img{box-shadow:none;border-radius:3px}[data-theme=wood] #developer-tools .upload{background:#e9e0ce;border-color:#cfc3ad}[data-theme=wood] .reference-strip figure{background:#fffdf6;border-color:#cfc3ad;border-radius:3px}[data-theme=booth] .welcome .primary-upload{background:var(--apricot);color:#593c31;border-color:#a76948;border-radius:16px;box-shadow:0 4px #cc9b7b}[data-theme=booth] .welcome h1{font-family:inherit;font-weight:400}[data-theme=booth] .entry-door{border-color:#967ab1}[data-theme=booth] .scene-actions button,[data-theme=booth] .scene-actions .upload,[data-theme=booth] #hint{border-radius:18px}@media (width<=480px){.scene-toolbar{padding:14px 14px 8px}.scene-brand{font-size:13px}.scene-actions{gap:5px}.scene-actions button,.scene-actions .upload{padding:7px 10px;font-size:14px}#settings-dialog{border-top:1px solid var(--line);border-radius:12px 12px 0 0;width:100%;height:90dvh;max-height:90dvh;margin:auto 0 0}#settings-dialog aside{padding:21px 20px max(28px,env(safe-area-inset-bottom))}.welcome{padding-top:64px}#hint{bottom:max(18px,env(safe-area-inset-bottom));padding:9px 13px;font-size:12px}#hint strong{font-size:14px}}@media (height<=590px){.welcome{justify-content:flex-start}.entry-door{display:none}.welcome h1{font-size:27px;line-height:1.35}.entry-privacy{margin-top:14px}.flow-photo{max-height:20svh;margin-bottom:16px}}@media (prefers-reduced-motion:reduce){#canvas-wrap{transition:none}}@media (height<=590px){#hint{padding:8px 12px;font-size:12px;bottom:12px}#hint strong,#hint .hint-secondary{display:none}}#gyro-notice{bottom:max(20px,env(safe-area-inset-bottom));width:max-content;max-width:calc(100% - 40px);color:var(--ink);background:var(--cream);border:1px solid var(--line);text-align:center;pointer-events:none;z-index:5;border-radius:14px;margin:0;padding:10px 14px;font-size:14px;line-height:1.6;position:absolute;left:50%;transform:translate(-50%)}#experience:not([data-flow=ready]) #gyro-notice{display:none}#render-recovery{border:1px solid var(--line);background:var(--cream);width:min(420px,100% - 36px);color:var(--ink);text-align:center;border-radius:12px;padding:28px}#render-recovery::backdrop{background:var(--room)}#render-recovery h2{font-size:24px;font-weight:400;line-height:1.4}#render-recovery p{font-size:15px}#render-reload{border-color:var(--line);padding:10px 24px}.journey{--journey-height:clamp(144px,30dvh,236px);--journey-car-width:58%;width:min(460px,88vw);height:var(--journey-height);flex:none;margin:0 0 24px;position:relative;overflow:hidden}.journey-scenery{position:absolute;inset:0;overflow:hidden}.journey-sun{opacity:.65;background:#dfbb73;border-radius:50%;width:34px;height:34px;position:absolute;top:9%;right:15%}.journey-cloud{background:var(--cream);border-radius:50%;width:65px;height:13px;position:absolute;top:21%;left:16%}.journey-cloud:before{content:"";background:inherit;border-radius:50%;width:30px;height:24px;position:absolute;bottom:0;left:17px}.journey-hill{opacity:.45;background:#b6bc9c;border-radius:50% 50% 0 0;width:95%;height:45%;position:absolute;bottom:26px;left:-8%}.journey-tree{background:#9b8563;width:9px;height:55px;position:absolute;bottom:29px;right:18%}.journey-tree:before{content:"";background:#9ca883;border-radius:50% 50% 42% 42%;width:43px;height:54px;position:absolute;top:-22px;left:-17px}.journey-road{background:repeating-linear-gradient(90deg,#0000 0 22px,#bcb099 22px 44px,#0000 44px 66px) 0 12px/132px 2px repeat-x;border-top:2px solid #ada289;height:20px;position:absolute;bottom:11px;left:0;right:0}.journey-car,.journey-traveler{width:min(var(--journey-car-width),calc((var(--journey-height) - 38px) * 5 / 3));aspect-ratio:5/3;transform-origin:50% 85%;max-width:267px;position:absolute;bottom:24px;left:16%}.journey-traveler{z-index:3;pointer-events:none}.journey-car-body{z-index:2;width:100%;height:100%;position:absolute;inset:0;overflow:visible}.journey-passenger{z-index:3;background:#fcf5df;border:5px solid #fcf5df;border-radius:9px;width:34%;height:65%;position:absolute;top:0;left:22%;transform:rotate(-5deg);box-shadow:0 2px 3px #50392226}.journey-passenger .flow-photo{object-fit:contain;width:100%;max-width:none;height:100%;max-height:none;box-shadow:none;border:0;border-radius:4px;margin:0;display:block}.journey-house{opacity:0;width:27%;max-height:88%;position:absolute;bottom:26px;right:3%;transform:translate(20px)}.journey-wheel{transform-box:fill-box;transform-origin:50%}#flow-overlay[data-journey=driving] :is(.journey-car,.journey-traveler){animation:1.7s ease-in-out infinite journey-ride}#flow-overlay[data-journey=driving] .journey-wheel{animation:1.4s linear infinite journey-wheel-turn}#flow-overlay[data-journey=driving] .journey-road{animation:2.8s linear infinite journey-road-pass}#flow-overlay[data-journey=driving] .journey-tree{animation:8s linear infinite journey-tree-pass}#journey-motion{color:var(--muted);text-underline-offset:3px;background:0 0;border-color:#0000;text-decoration:underline}#flow-overlay[data-journey=unpacking]{animation:.2s ease-in 1.3s both journey-arrival-fade}#flow-overlay:is([data-journey=arrived],[data-journey=unpacking]) :is(.journey-car,.journey-traveler){transition:transform .35s ease-out;transform:translate(-10%)}#flow-overlay:is([data-journey=arrived],[data-journey=unpacking]) .journey-house{opacity:1;transition:opacity .25s ease-out,transform .35s ease-out;transform:none}#flow-overlay:is([data-journey=arrived],[data-journey=unpacking]) .journey-tree{opacity:0}#flow-overlay[data-journey=unpacking] .journey-traveler{transition:none;animation:1.3s linear both journey-walk}#flow-overlay[data-journey=unpacking] .journey-passenger{transform-origin:50% 100%;animation:1.3s ease-in-out both journey-waddle}#flow-overlay[data-motion=paused] .journey *{animation-play-state:paused}[data-theme=booth] .journey-hill{background:#c3afd9}[data-theme=booth] .journey-tree:before{background:#baa6c7}@keyframes journey-ride{0%,to{transform:translateY(0)rotate(-.3deg)}50%{transform:translateY(-2px)rotate(.3deg)}}@keyframes journey-wheel-turn{to{transform:rotate(360deg)}}@keyframes journey-road-pass{to{background-position:-132px 12px}}@keyframes journey-tree-pass{0%{transform:translate(180px)}to{transform:translate(-460px)}}@keyframes journey-walk{0%,28%{left:16%;transform:translate(-10%)}to{left:87.5%;transform:translate(-39%)}}@keyframes journey-waddle{0%{animation-timing-function:ease-out;top:0;transform:translateY(0)rotate(-5deg)scaleY(1)}8%{animation-timing-function:cubic-bezier(.4,0,.65,1);top:0;transform:translateY(-6px)rotate(-5deg)scaleY(1)}24%{animation-timing-function:ease-out;top:35%;transform:translateY(0)rotate(-5deg)scaleY(.97)}28%{top:35%;transform:translateY(0)rotate(-5deg)scaleY(1)}40%{top:35%;transform:translateY(-3px)rotate(5deg)}52%{top:35%;transform:translateY(0)rotate(-5deg)}64%{top:35%;transform:translateY(-3px)rotate(5deg)}76%{top:35%;transform:translateY(0)rotate(-5deg)}88%{top:35%;transform:translateY(-3px)rotate(5deg)}to{top:35%;transform:translateY(0)rotate(0)}}@keyframes journey-arrival-fade{0%{opacity:1}to{opacity:0}}@media (height<=650px){.flow-overlay{padding:52px 18px 18px}.journey{--journey-height:clamp(100px,27dvh,160px);--journey-car-width:54%;width:min(380px,80vw);margin-bottom:12px}.flow-overlay h2{font-size:20px;line-height:1.4}#flow-detail{margin:9px 0 14px;font-size:13px;line-height:1.55}}@media (height<=430px) and (width>=560px){.flow-overlay{grid-template-columns:minmax(170px,40%) minmax(0,1fr);align-content:center;justify-items:center;column-gap:24px;padding:52px 30px 18px;display:grid}.journey{--journey-height:170px;grid-row:1/4;width:100%;margin:0}.flow-overlay h2,#flow-detail,.flow-actions{grid-column:2}}@media (prefers-reduced-motion:reduce){.journey *{transition:none!important;animation:none!important}#flow-overlay[data-journey=unpacking]{animation:none}}.comparison-control{border:1px solid var(--line);border-radius:12px;padding:14px}.comparison-control h3{margin:0 0 8px;font-size:17px;font-weight:400}.comparison-control button{width:100%;padding:10px}.comparison-control details{margin-top:10px}#comparison-overlay{z-index:1;pointer-events:none;position:absolute;inset:0}.comparison-label{text-align:center;color:var(--ink);font-size:14px;line-height:1.3;position:absolute;transform:translate(-50%)}#comparison-metrics{bottom:max(10px,env(safe-area-inset-bottom));text-align:center;font-family:var(--font-values);color:var(--ink);font-size:12px;line-height:1.45;position:absolute;left:10px;right:10px}#comparison-metrics p{white-space:pre-line;margin:3px 0}#experience:not([data-flow=ready]) #comparison-overlay,#experience[data-comparison] #hint{visibility:hidden}#experience[data-comparison] .scene-brand{display:none}#experience[data-comparison] .scene-toolbar{justify-content:flex-end}@media (width<=480px){#experience[data-comparison] .scene-actions{flex-wrap:wrap;justify-content:flex-end}#comparison-metrics{font-size:12px}}@media (height<=500px){#comparison-memory{display:none}#comparison-metrics{line-height:1.25}}#mesh-render-error{border:1px solid var(--line);border-radius:1rem;max-width:28rem;padding:1.5rem}#mesh-render-error::backdrop{background:#21172aaa}#mesh-render-error button{margin:.5rem .5rem 0 0}.frame-notice{color:#402c21;pointer-events:none;z-index:4;background:#fff9e9ee;border-radius:.75rem;max-width:32rem;padding:.65rem 1rem;font-size:.875rem;position:absolute;bottom:1rem;left:1rem;right:1rem}#door-handle{pointer-events:none;color:#fff8df;text-shadow:0 1px 3px #32200f;z-index:1;background:#3e2c151c;border:1px solid #fff8dc66;border-radius:50%;place-items:center;width:44px;height:44px;font-family:system-ui,sans-serif;font-size:22px;display:grid;position:absolute;transform:translate(-50%,-50%)}#door-handle[hidden],#door-controls[hidden]{display:none}#door-controls{left:max(16px,env(safe-area-inset-left));bottom:max(88px,env(safe-area-inset-bottom));z-index:2;flex-direction:column;align-items:flex-start;gap:6px;display:flex;position:absolute}#door-toggle{border:1px solid var(--line);background:var(--cream);min-width:88px;min-height:44px;color:var(--ink);border-radius:6px;padding:8px 13px}#door-help{color:var(--ink);background:var(--cream);border-radius:4px;padding:3px 7px;font-size:12px}#door-toggle:focus-visible{outline-offset:3px;outline:3px solid #996130}.scene-motion{top:calc(76px + env(safe-area-inset-top));right:max(16px,env(safe-area-inset-right));z-index:4;align-items:flex-start;gap:8px;display:flex;position:absolute}.scene-motion[hidden]{display:none}.scene-motion>button,#motion-tools>summary,#door-toggle{color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;background:0 0;border:0;border-radius:4px;padding:8px 10px;font-size:14px}.scene-motion>button{align-items:center;gap:6px;display:flex}.scene-motion>button[aria-pressed=true]{text-underline-offset:5px;text-decoration:underline}#motion-tools{background:0 0;border:0;margin:0;position:relative}#motion-tools>summary{cursor:pointer;align-items:center;list-style:none;display:flex}#motion-tools>summary::-webkit-details-marker{display:none}#motion-tools>summary:after{content:"+";margin-left:6px}#motion-tools[open]>summary:after{content:"−"}#motion-tools .motion-panel{color:#fffdf6;background:#302b25f5;border:1px solid #fff5;border-radius:10px;width:min(290px,100vw - 32px);max-height:calc(100dvh - 165px);padding:16px;position:absolute;top:100%;right:0;overflow:auto;box-shadow:0 6px 24px #0003}.motion-panel .control-help,.motion-panel .range-ends{color:#ede6dc}.motion-panel .control-help{font-size:14px}.motion-panel button{color:#fffdf6;min-height:44px;box-shadow:none;background:0 0;border:1px solid #fff5;margin:4px 0}.scene-motion button:focus-visible,#motion-tools>summary:focus-visible,#door-toggle:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#door-controls{left:max(16px,env(safe-area-inset-left));bottom:calc(56px + env(safe-area-inset-bottom))}#door-toggle{text-underline-offset:5px;min-width:88px;text-decoration:underline}#hint,[data-theme=booth] #hint{bottom:calc(20px + env(safe-area-inset-bottom));max-width:calc(100% - 24px);box-shadow:none;color:#fffdf6;white-space:nowrap;text-shadow:0 1px 3px #211910,0 0 8px #211910,0 0 14px #211910;opacity:0;z-index:2;background:0 0;border:0;border-radius:0;padding:0;font-size:14px;line-height:1.5;transition:none}#hint[data-phase=in]{animation:.6s ease-out both scene-hint-in}#hint[data-phase=hold]{opacity:1}#hint[data-phase=out]{animation:.8s ease-in both scene-hint-out}@keyframes scene-hint-in{0%{opacity:0}to{opacity:1}}@keyframes scene-hint-out{0%{opacity:1}to{opacity:0}}#gyro-notice{top:calc(125px + env(safe-area-inset-top));font-size:14px;bottom:auto}@media (width<=480px){.scene-motion{top:calc(67px + env(safe-area-inset-top));gap:2px;right:10px}}@media (prefers-reduced-motion:reduce){#hint[data-phase]{animation:none}#hint[data-phase=in],#hint[data-phase=hold]{opacity:1}}#hint{white-space:normal;text-wrap:balance}.photo-tip{color:var(--ink);margin:-12px 0 18px;font-size:14px;line-height:1.7}#sample-dialog{border:1px solid var(--line);background:var(--cream);width:min(520px,100% - 28px);max-height:calc(100dvh - 28px);color:var(--ink);overscroll-behavior:contain;border-radius:12px;padding:20px;overflow:auto}#sample-dialog::backdrop{background:#201a1366}.sample-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.sample-heading h2{margin:0;font-size:21px;line-height:1.4}#sample-close{border-radius:5px;flex:none;padding:6px 12px}#sample-description{color:var(--muted);margin:10px 0 18px;font-size:13px}.sample-choices{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;display:grid}.sample-choices button{border:2px solid var(--line);text-align:left;background:var(--cream);border-radius:7px;flex-direction:column;align-items:stretch;min-width:0;padding:6px;display:flex}.sample-choices button[aria-pressed=true]{background:#e9dec6;border-color:#79583e;box-shadow:0 0 0 1px #79583e}.sample-choices img{object-fit:contain;background:#e6dfcf;border-radius:3px;width:100%;height:120px}.sample-choices span{margin-top:6px;font-size:12px;line-height:1.5}.sample-choices small{color:#67492f;font-size:11px}.sample-footer{background:var(--cream);padding:16px 0 4px;position:sticky;bottom:-20px}#sample-confirm{color:#fffaf0;background:#6e4932;border-radius:5px;width:100%;min-height:48px}@media (width<=420px){.sample-choices{grid-template-columns:repeat(2,minmax(0,1fr))}.sample-choices img{height:110px}}.pet-name-field{text-align:left;flex-direction:column;gap:7px;display:flex}.pet-name-field label{margin:0;font-size:15px;display:block}.pet-name-field input{width:100%;min-width:0;min-height:44px;color:var(--ink);font:inherit;background:#fffaf080;border:1px solid #a89170;border-radius:5px;padding:10px 12px;font-size:17px}.pet-name-field input::placeholder{color:#817565;opacity:1}.pet-name-field small{color:var(--muted);font-size:11px;line-height:1.5}.pet-name-field .name-storage-notice{color:#77472d}.entry-name-field{flex-shrink:0;width:min(100%,280px);margin:0 0 18px}.settings-name-field{margin:0 0 22px}#welcome-name,#entry-photo-button,#flow-title{overflow-wrap:anywhere}#entry-photo-button{max-width:100%}#internal-controls[hidden]{display:none!important}.arrival-count{color:var(--muted);margin:8px 0 0;font-size:12px;line-height:1.6}#settings-dialog .arrival-count{margin:0 0 18px}.welcome{justify-content:flex-start}.welcome>*{flex-shrink:0;max-width:100%}.welcome .entry-door{margin-top:auto}#entry-photo-step{margin-bottom:0}.entry-step{flex-direction:column;flex-shrink:0;align-items:center;gap:12px;width:min(100%,360px);display:flex}.entry-step>*{flex-shrink:0;max-width:100%}.entry-step .entry-name-field{width:100%;margin:0}.entry-step .photo-tip{margin:0}.entry-step .primary-upload{min-height:48px}.entry-step .entry-samples{margin:0}#entry-name-edit{align-self:center;min-height:44px;margin:0 0 16px;font-size:14px}#paste-tip span{white-space:nowrap}.welcome[data-step=name] #entry-name-step{margin-bottom:auto}.scene-actions{flex-wrap:wrap;justify-content:flex-end}#entry-notices{width:min(100%,360px);color:var(--muted);touch-action:pan-y pinch-zoom;flex-shrink:0;grid-template-columns:44px minmax(0,1fr) 44px;align-items:center;margin:8px 0 auto;display:grid}#entry-notices>button{min-width:44px;min-height:44px;box-shadow:none;color:var(--ink);background:0 0;border:0;padding:0;font-family:system-ui,sans-serif;font-size:24px}.notice-slides{align-items:center;min-width:0;display:grid}#entry-notices .entry-notice-slide{overflow-wrap:anywhere;word-break:keep-all;visibility:hidden;grid-area:1/1;margin:0;padding:0;font-size:13px;line-height:1.65}#entry-notices .entry-notice-slide[data-active=true]{visibility:visible}#entry-notices .entry-notice-slide[hidden]{display:none}#notice-position{opacity:.75;grid-column:2;font-family:inherit;font-size:10px;line-height:1.4}#entry-notices[hidden]{display:none}@media (width<=640px){.welcome[data-step=photo]{padding-bottom:max(16px,env(safe-area-inset-bottom))}.welcome[data-step=photo] #entry-photo-step{margin-bottom:24px}.welcome[data-step=photo] #entry-notices{margin-top:auto;margin-bottom:0}}.scene-toolbar{grid-template-columns:auto minmax(0,1fr);align-items:start;gap:6px 12px;display:grid}.scene-brand{white-space:nowrap;padding-top:10px}.scene-actions{grid-column:2;min-width:0}.scene-motion{flex-direction:column;grid-column:1/-1;justify-self:end;align-items:flex-end;gap:6px;max-width:100%;display:flex;position:static}#gyro,#gyro[aria-pressed=true],#gyro[aria-busy=true]{color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;background:0 0;border:0;border-radius:4px;padding:8px 10px;text-decoration:underline}#scene-motion[hidden]{display:none}#gyro-notice{width:auto;max-width:min(290px,100%);color:var(--ink);background:var(--cream);text-shadow:none;margin:0;padding:8px 12px;font-size:13px;position:static;inset:auto;transform:none}#panel-view{color:var(--ink);gap:16px}#panel-view select{color:var(--ink);background:var(--cream)}#panel-view .control-help{margin:0}#panel-view button{min-height:44px}#tool-tabs{grid-template-columns:repeat(3,minmax(0,1fr))}#gyro:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#credits-dialog{border:1px solid var(--line);background:var(--cream);width:min(400px,100% - 32px);max-height:calc(100dvh - 32px);color:var(--ink);border-radius:12px;padding:24px;overflow:auto}#credits-dialog::backdrop{background:#201a1366}.credits-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.credits-heading h2{margin:0;font-size:22px}#credits-close{min-height:44px;padding:6px 12px}.credits-info{gap:6px;margin:20px 0;display:grid}.credits-info dt{color:var(--muted);font-size:13px}.credits-info dd{overflow-wrap:anywhere;margin:0 0 10px}#credits-dialog a{color:var(--ink);text-underline-offset:4px}.credits-licenses{padding:8px 0;font-size:13px;display:inline-block}#experience[data-flow=entry] #scene-zoom-reset,#experience[data-flow=entry] #comparison-exit{display:none}#export-dialog{border:1px solid var(--line);background:var(--cream);width:min(560px,100% - 24px);max-height:calc(100dvh - 24px);color:var(--ink);border-radius:12px;padding:20px;overflow:auto}#export-dialog::backdrop{background:#201a1380}.export-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.export-heading h2{margin:0;font-size:22px}#export-dialog button,.export-actions a{min-height:44px;padding:9px 12px}.export-choices,.export-actions{flex-wrap:wrap;gap:8px;margin-top:16px;display:flex}#export-status{font-size:14px;line-height:1.6}#export-preview{object-fit:contain;border:1px solid var(--line);background-color:#fff;background-image:linear-gradient(45deg,#ddd 25%,#0000 25%),linear-gradient(-45deg,#ddd 25%,#0000 25%),linear-gradient(45deg,#0000 75%,#ddd 75%),linear-gradient(-45deg,#0000 75%,#ddd 75%);background-position:0 0,0 8px,8px -8px,-8px 0;background-size:16px 16px;width:100%;max-height:50dvh;display:block}#export-preview[hidden]{display:none}.export-actions a{color:var(--cream);background:var(--ink);border-radius:6px;align-items:center;display:inline-flex}.export-actions a[hidden]{display:none}#gyro-recenter{right:max(16px,env(safe-area-inset-right));bottom:calc(56px + env(safe-area-inset-bottom));z-index:3;color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;background:0 0;border:0;border-radius:4px;padding:8px 10px;text-decoration:underline;position:absolute}#gyro-recenter:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#first-guide{display:none}#guide-scene-target{pointer-events:none;width:52%;height:27%;position:absolute;top:28%;left:24%}.behind-glass-tour{font-family:var(--font-ui);color:var(--ink);background:var(--cream);border:1px solid var(--line);border-radius:10px;width:min(340px,100vw - 32px);min-width:0;max-width:calc(100vw - 32px);padding:18px;font-weight:400;overflow:visible;box-shadow:0 4px 20px #201a1326}.behind-glass-tour .driver-popover-title{font-family:inherit;font-size:21px;font-weight:400;line-height:1.5}.behind-glass-tour .driver-popover-description{font-family:inherit;font-size:15px;line-height:1.8}.behind-glass-tour .driver-popover-footer button{min-height:44px;font:inherit;text-shadow:none;border:1px solid var(--line);border-radius:5px;padding:8px 14px;font-size:14px}.behind-glass-tour .driver-popover-next-btn{background:var(--ink);color:var(--cream)}.behind-glass-tour .driver-popover-prev-btn{color:var(--ink);background:0 0}.behind-glass-tour .driver-popover-close-btn{width:auto;height:auto;min-height:44px;font:inherit;color:var(--muted);box-shadow:none;background:0 0;border:0;margin:0 0 8px auto;padding:4px 8px;font-size:13px;display:block;position:static}.behind-glass-tour .driver-popover-progress-text{font:inherit;color:var(--muted);font-size:12px}.behind-glass-tour .driver-popover-arrow-side-top{border-top-color:var(--cream)}.behind-glass-tour .driver-popover-arrow-side-bottom{border-bottom-color:var(--cream)}.behind-glass-tour button:focus-visible{outline:2px solid var(--ink);outline-offset:3px}.behind-glass-tour .guide-popover-content{max-height:max(80px,calc(100dvh - 68px - env(safe-area-inset-top) - env(safe-area-inset-bottom)));overflow:auto}.behind-glass-tour .driver-popover-arrow-side-left{border-left-color:var(--cream)}.behind-glass-tour .driver-popover-arrow-side-right{border-right-color:var(--cream)}.scene-toolbar{grid-template-columns:minmax(0,1fr) auto;align-items:start}.scene-brand{display:none}#scene-menu-open{color:#fffdf6;min-width:44px;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;background:0 0;border:0;border-radius:4px;grid-area:1/1;justify-self:start;padding:8px 10px;font-size:14px;text-decoration:underline}#scene-menu-open:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}.scene-toolbar .scene-motion{grid-area:1/2;min-width:0;max-width:min(65vw,290px)}.scene-toolbar .scene-actions{grid-area:1/2}#experience:not([data-flow=entry]) .scene-actions{display:none}#scene-menu{width:min(440px,100%);max-width:100%;max-height:calc(100dvh - max(24px,env(safe-area-inset-top)));padding:20px max(20px,env(safe-area-inset-right)) max(20px,env(safe-area-inset-bottom)) max(20px,env(safe-area-inset-left));border:1px solid var(--line);background:var(--cream);color:var(--ink);overscroll-behavior:contain;border-bottom:0;border-radius:18px 18px 0 0;margin:auto auto 0;overflow:auto}#scene-menu::backdrop{background:#201a1380}.scene-menu-heading{justify-content:space-between;align-items:center;gap:16px;margin-bottom:8px;display:flex}.scene-menu-heading h2{margin:0;font-size:22px}#scene-menu-close{min-width:44px;min-height:44px;color:var(--muted);box-shadow:none;background:0 0;border:0;padding:8px}.scene-menu-items{flex-direction:column;display:flex}.scene-menu-items>button{text-align:left;border:0;border-bottom:1px solid var(--line);width:100%;min-height:52px;color:var(--ink);box-shadow:none;background:0 0;border-radius:0;padding:12px 4px;font-family:inherit;font-size:16px}.scene-menu-items>button:last-child{border-bottom:0}.scene-menu-items>button:disabled{opacity:.45}#scene-menu button:focus-visible{outline:2px solid var(--ink);outline-offset:-2px}#scene-menu-open[hidden],.scene-menu-items>button[hidden]{display:none}.scene-toolbar{grid-template-columns:minmax(0,1fr) 44px minmax(0,1fr);column-gap:6px}.scene-toolbar .scene-motion,.scene-toolbar .scene-actions{grid-column:3}#sample-home{color:#fffdf6;width:44px;min-height:44px;box-shadow:none;background:0 0;border:0;border-radius:4px;grid-area:1/2;place-items:center;padding:8px;display:grid}#sample-home svg{filter:drop-shadow(0 1px 2px #211910)}#sample-home:focus-visible,#photo-adjust-open:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#sample-home[hidden]{display:none}#gyro{white-space:nowrap;padding-inline:4px}#photo-adjust-open{left:50%;bottom:max(12px,env(safe-area-inset-bottom));z-index:3;color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;white-space:nowrap;background:0 0;border:0;border-radius:4px;padding:8px 12px;font-size:14px;text-decoration:underline;position:absolute;transform:translate(-50%)}#photo-adjust-panel{z-index:4;left:50%;bottom:max(12px,env(safe-area-inset-bottom));border:1px solid var(--line);width:min(400px,100% - 24px);max-height:45dvh;color:var(--ink);background:var(--cream);border-radius:12px;padding:12px 16px;position:absolute;overflow:auto;transform:translate(-50%);box-shadow:0 3px 16px #201a1326}.photo-adjust-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.photo-adjust-heading strong{font-size:17px;font-weight:400}#photo-adjust-panel button{min-height:44px;padding:8px 12px}#photo-adjust-done{color:var(--cream);background:var(--ink)}#photo-adjust-panel label{align-items:center;gap:8px;margin-top:8px;font-size:14px;display:flex}#photo-adjust-zoom{flex:1;min-width:0;min-height:44px}#photo-adjust-help{word-break:keep-all;margin:8px 0 0;font-size:13px;line-height:1.6}#photo-adjust-reset{color:var(--muted);box-shadow:none;background:0 0;border:0;font-size:13px;padding-left:0!important}#photo-adjust-panel[hidden],#photo-adjust-open[hidden]{display:none}#home-dialog{border:1px solid var(--line);background:var(--cream);width:min(380px,100% - 32px);max-height:calc(100dvh - 32px);color:var(--ink);border-radius:12px;padding:24px;overflow:auto}#home-dialog::backdrop{background:#201a1380}#home-title{word-break:keep-all;margin:0 0 12px;font-size:22px;line-height:1.5}#home-detail{color:var(--muted);font-size:14px;line-height:1.7}.home-actions{flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:20px;display:flex}.home-actions button{min-height:44px;padding:10px 14px}#home-confirm{color:var(--cream);background:var(--ink)}#hint,[data-theme=booth] #hint{bottom:calc(112px + env(safe-area-inset-bottom))}.peeking-experiment{border-top:1px solid var(--line,#cfc3ad);margin-top:20px;padding-top:18px}.peeking-experiment h3{margin:0 0 8px;font-size:16px}.peeking-experiment p{color:var(--ink,#3e3429);margin:8px 0 12px;font-size:13px;line-height:1.65}.peeking-experiment button{width:100%;min-height:44px;margin-top:8px;padding:10px 12px;font-size:14px}.peeking-experiment [hidden],.peeking-preview-dialog [hidden]{display:none!important}.peeking-preview-dialog{overscroll-behavior:contain;border:1px solid var(--line,#cfc3ad);background:var(--cream,#f7f1e5);width:min(760px,100% - 32px);max-width:760px;max-height:calc(100dvh - 32px);color:var(--ink,#3e3429);box-sizing:border-box;border-radius:12px;margin:auto;padding:24px;overflow:auto}.peeking-preview-dialog::backdrop{background:#201a13a6}.peeking-preview-dialog h2{margin:0 0 10px;font-size:20px;line-height:1.4}.peeking-preview-dialog p{overflow-wrap:anywhere;font-size:14px;line-height:1.6}.peeking-preview-dialog #peeking-error{color:#862d25}.peeking-comparison{grid-template-columns:1fr 1fr;gap:14px;margin:18px 0;display:grid}.peeking-comparison figure{min-width:0;margin:0}.peeking-preview-surface{aspect-ratio:1;background-color:#fff;background-image:repeating-conic-gradient(#e3dfd5 0% 25%,#0000 0% 50%);background-size:20px 20px;border:1px solid #aa9c85;border-radius:6px;place-items:center;display:grid;overflow:hidden}.peeking-preview-surface img{object-fit:contain;width:100%;min-width:0;height:100%;min-height:0;display:block}.peeking-comparison figcaption{margin-top:7px;font-size:13px;line-height:1.4}.peeking-actions{flex-wrap:wrap;gap:10px;margin-top:20px;display:flex}.peeking-actions button{min-height:44px;padding:10px 14px;font-size:14px}.peeking-actions #peeking-accept{color:#3e3429;background:#ede4d2;border-color:#aa9674}.peeking-experiment button:focus-visible,.peeking-preview-dialog button:focus-visible{outline-offset:3px;outline:3px solid #765534}@media (width<=480px){.peeking-preview-dialog{width:calc(100% - 20px);max-height:calc(100dvh - 20px);padding:18px}.peeking-comparison{gap:8px}.peeking-comparison figcaption{font-size:12px}.peeking-actions button{flex:calc(50% - 10px)}} diff --git a/dist/assets/index-D7twsXVD.css b/dist/assets/index-D7twsXVD.css new file mode 100644 index 0000000..0c4feb5 --- /dev/null +++ b/dist/assets/index-D7twsXVD.css @@ -0,0 +1 @@ +@font-face{font-family:BM Kkubulim;src:url(/fonts/BMKkubulim.woff)format("woff");font-style:normal;font-weight:400;font-display:swap}:root{--font-ui:"BM Kkubulim","Apple SD Gothic Neo","Noto Sans KR",system-ui,sans-serif;--font-values:ui-monospace,"SFMono-Regular",Consolas,monospace;font-family:var(--font-ui);color:#453653;font-synthesis:none;--ink:#453653;--muted:#71637f;--purple:#7651a8;--lavender:#e4d6fb;--cream:#fffbf2;--apricot:#ffd5b4;--line:#d9cbea;--shadow:#b29bc9;--radius:24px;background:#f1ebff;font-weight:400}*{box-sizing:border-box}body{margin:0;font-size:16px;line-height:1.65}html[data-font-loading] #app{visibility:hidden;opacity:0}button,input,select{font:inherit;color:inherit}strong,b{font-weight:400}output,input[type=number],pre,code{font-family:var(--font-values);letter-spacing:normal;font-weight:400}button,select,summary,.upload,input[type=range]{-webkit-tap-highlight-color:transparent}button,select,input[type=number]{min-height:44px}button{cursor:pointer}button:disabled{cursor:default;color:#867d8b;box-shadow:none;background:#f0ebf2;border-color:#d9d1df}button:focus-visible,select:focus-visible,input:focus-visible,summary:focus-visible,a:focus-visible,#canvas-wrap:focus-visible{outline-offset:4px;outline:3px solid #6b439d}button,select{border:1px solid var(--line);background:var(--cream);border-radius:14px}button{transition:transform .16s,box-shadow .16s,background .16s}button:not(:disabled):active,.upload:active{box-shadow:0 1px 0 var(--shadow);transform:translateY(2px)scale(.97)}[hidden]{display:none!important}#app{max-width:1600px;margin:0 auto}.app-header{flex-wrap:wrap;align-items:center;gap:24px;padding:28px 44px 26px;display:flex}.brand{letter-spacing:-1.4px;color:var(--ink);align-items:center;gap:10px;font-size:29px;font-weight:400;line-height:.83;text-decoration:none;display:flex}.brand-second{display:block}.brand-mark{color:#77559e;font-size:45px;font-weight:400;line-height:1}.brand-dot{color:#bd6545;align-self:flex-end;font-size:38px}.header-note{color:var(--muted);margin-top:5px;font-size:14px}.primary-upload{background:var(--apricot);color:#593c31;white-space:nowrap;border:1.5px solid #a76948;justify-content:center;align-items:center;gap:7px;min-height:48px;margin-left:auto;padding:10px 20px;font-weight:400;transition:transform .16s;display:flex;box-shadow:0 4px #cc9b7b}.primary-upload>span{font-size:23px;font-weight:400;line-height:1}.upload{cursor:pointer;border-radius:16px;position:relative}.upload input[type=file],.sr-only{clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;position:absolute!important;overflow:hidden!important}.upload:focus-within{outline-offset:4px;outline:3px solid #6b439d}main{grid-template-columns:minmax(0,1fr) 366px;align-items:start;gap:28px;padding:0 44px;display:grid}.visual-column{min-width:0;position:sticky;top:20px}.photo-mat{background:var(--cream);border:1px solid #d0bddf;border-radius:28px;padding:20px 20px 0;box-shadow:0 6px #d3c4e3,0 16px 32px #70508b0d}.preview-heading{justify-content:space-between;align-items:center;gap:12px;margin-bottom:15px;display:flex}.eyebrow{letter-spacing:1.8px;color:#79628e;margin:0 0 5px;font-size:12px;font-weight:400}.preview-chip{color:#71558e;background:#f0e5ff;border:1px solid #dfcdec;border-radius:18px;padding:7px 11px;font-size:12px;line-height:1.25}.stage{background:#f7f0e5;border:1px solid #e4d9eb;border-radius:16px;height:clamp(410px,62vh,740px);position:relative;overflow:hidden}#canvas-wrap{touch-action:none;border-radius:inherit;position:absolute;inset:0}#canvas-wrap:focus-visible{outline-offset:-4px}#canvas-wrap canvas{cursor:grab;border-radius:inherit;width:100%;height:100%;display:block}#canvas-wrap canvas.is-dragging{cursor:grabbing}#empty{z-index:1;text-align:center;pointer-events:none;color:var(--muted);background:#f7f0e5ed;flex-direction:column;justify-content:center;align-items:center;gap:16px;padding:24px;display:flex;position:absolute;inset:0}#empty strong{letter-spacing:-.6px;color:var(--ink);font-size:clamp(19px,2vw,26px)}#empty>span:last-child{font-size:14px;line-height:1.8}.empty-star{color:#a082bf;font-size:62px;line-height:1.2}#hint{color:#665177;text-align:center;pointer-events:none;background:#fffbf2ed;border:1px solid #d4c2e6;border-radius:25px;width:max-content;max-width:calc(100% - 28px);margin:0;padding:10px 16px;font-size:13px;transition:opacity .25s;position:absolute;bottom:18px;left:50%;transform:translate(-50%)}.photo-caption{color:#7c6a88;justify-content:space-between;align-items:center;gap:12px;min-height:55px;padding:3px 4px;font-size:13px;display:flex}.caption-spark{color:#97b;letter-spacing:5px;white-space:nowrap;font-size:26px}.processing-card{align-items:center;gap:14px;padding:22px 4px 10px;display:flex}.processing-copy{flex:1;min-width:0}#status{overflow-wrap:anywhere;margin:0;font-size:14px}#depth-provenance{color:var(--muted);overflow-wrap:anywhere;margin:6px 0 0;font-size:12px;line-height:1.6}#ai-depth{flex:none;padding:9px 14px;font-size:13px}.editor-heading{justify-content:space-between;align-items:center;margin:0 0 18px;padding:3px 4px;display:flex}.editor-heading h1{letter-spacing:-.8px;margin:5px 0 0;font-size:25px;line-height:1.3}.editor-sticker{color:#8e573c;background:var(--apricot);border:1px solid #dfb49c;border-radius:15px;place-items:center;width:47px;height:47px;font-size:29px;display:grid;transform:rotate(9deg);box-shadow:0 3px #dbc9ca}aside{background:#faf6ff;border:1px solid #d4c1e6;border-radius:28px;min-width:0;padding:23px 22px;box-shadow:0 5px #d8cbea}#tool-tabs{background:#eadff4;border:1px solid #dfd0ec;border-radius:18px;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px;margin-bottom:20px;padding:5px;display:grid}#tool-tabs button{color:#715b87;min-width:0;min-height:44px;box-shadow:none;background:0 0;border:1px solid #0000;border-radius:12px;justify-content:center;align-items:center;gap:6px;padding:8px 3px;font-size:14px;font-weight:400;display:flex}#tool-tabs button[aria-selected=true]{background:var(--cream);color:#573672;border-color:#d5c4e5;box-shadow:0 2px #ccb8dd}#tool-tabs button>span{font-size:20px;font-weight:400;line-height:1}.tool-panel{gap:20px;min-width:0;display:grid}#pattern-cards{grid-template-columns:repeat(3,minmax(0,1fr));gap:9px;display:grid}.pattern-card{background:#fffcf7;border:2px solid #e5d9ed;border-radius:16px;flex-direction:column;align-items:stretch;min-width:0;padding:7px 6px 10px;display:flex;box-shadow:0 3px #e3d7eb}.pattern-card[aria-pressed=true]{background:#eee1ff;border-color:#8057aa;animation:.22s ease-out selection-pop;box-shadow:0 3px #9875b7}.pattern-swatch{border:1px solid #b7a6bd;border-radius:9px;height:75px;margin-bottom:9px;display:block;position:relative;overflow:hidden}.swatch-gobang{background-color:#cab7df;background-image:repeating-linear-gradient(0deg,#0000 0 17px,#7d69825c 18px,#fffbf2bf 20px,#ac94b369 23px),repeating-linear-gradient(90deg,#0000 0 17px,#7d69825c 18px,#fffbf2bf 20px,#ac94b369 23px),linear-gradient(135deg,#b3abd3,#e6cbb5 50%,#bcbad6)}.swatch-color{background-color:#d3b1cd;background-image:conic-gradient(#d8b898 25%,#796880 0 50%,#ebd9c1 0 75%,#b39db9 0);background-size:37px 37px}.swatch-fine{background-color:#c8bfd6;background-image:repeating-linear-gradient(0deg,#0000 0 8px,#f8f0e6bf 9px,#927caa80 11px),repeating-linear-gradient(90deg,#0000 0 8px,#f8f0e6bf 9px,#927caa80 11px),linear-gradient(125deg,#c3b0da,#edd5bf)}.pattern-name{letter-spacing:-.3px;font-size:14px;font-weight:400}.pattern-detail{color:#6d587b;margin-top:3px;font-size:12px;line-height:1.4}.control-help{color:var(--muted);word-break:keep-all;margin:-8px 0 0;font-size:12px;line-height:1.7}.range-control{gap:4px;font-size:14px;font-weight:400;display:grid}.range-control>span:first-child{justify-content:space-between;align-items:center;gap:12px;display:flex}output{color:#744fa0;text-align:center;font-variant-numeric:tabular-nums;background:#eae0f5;border-radius:8px;min-width:38px;padding:3px 8px;font-size:13px;font-weight:400}input[type=range]{appearance:none;cursor:pointer;accent-color:#8660ad;background:0 0;width:100%;min-width:0;min-height:44px;margin:0}input[type=range]::-webkit-slider-runnable-track{background:#dac9eb;border-radius:8px;height:7px}input[type=range]::-webkit-slider-thumb{appearance:none;background:#8861b3;border:3px solid #fffbf2;border-radius:50%;width:23px;height:23px;margin-top:-8px;box-shadow:0 0 0 1px #9d7fb5,0 2px #b59bc9}input[type=range]::-moz-range-track{background:#dac9eb;border-radius:8px;height:7px}input[type=range]::-moz-range-thumb{background:#8861b3;border:3px solid #fffbf2;border-radius:50%;width:18px;height:18px;box-shadow:0 0 0 1px #9d7fb5}.range-ends{color:#7a6a87;justify-content:space-between;margin-top:-8px;font-size:12px;font-weight:400;display:flex}.inline-control{justify-content:space-between;align-items:center;gap:15px;font-size:14px;font-weight:400;display:flex}.inline-control select{width:120px}.core-optics{display:grid}.quiet-button,.tactile-button{min-height:44px;padding:11px 16px;font-size:14px;font-weight:400}.quiet-button{background:#fffbf2;box-shadow:0 2px #ddcfe7}.tactile-button{color:#593979;background:#e1cdfa;border:1px solid #aa88c6;box-shadow:0 3px #b69acb}.section-intro{text-align:center;padding:12px 0 4px}.section-intro h2{margin:8px 0;font-size:18px}.section-intro p{color:var(--muted);margin:0;font-size:14px;line-height:1.8}.intro-symbol{color:#9b6347;background:#f5e2d1;border-radius:20px;place-items:center;width:64px;height:64px;margin:0 auto 13px;font-size:36px;display:grid}.section-intro.compact{text-align:left;padding:0}.section-intro.compact h2{margin-top:0}details{border-top:1px solid #dfd2e8;margin-top:24px}summary{cursor:pointer;justify-content:space-between;align-items:center;gap:12px;min-height:52px;padding:8px 2px;font-size:14px;font-weight:400;list-style:none;display:flex}summary::-webkit-details-marker{display:none}summary>span{color:#8f70a8;font-size:21px;font-weight:400}details[open]>summary>span{transform:rotate(45deg)}.details-content{gap:14px;padding:8px 0 14px;display:grid}.details-content>label{gap:6px;font-size:14px;display:grid}.details-content input[type=number],select{background:#fffcf8;border:1px solid #cdbadb;border-radius:12px;width:100%;min-width:0;padding:10px 12px;font-size:14px}#test-photo{max-width:100%}.sample-strip{grid-template-columns:repeat(5,minmax(0,1fr));gap:5px;display:grid}.sample-strip img{aspect-ratio:1;object-fit:cover;border:2px solid #fff;border-radius:10px;width:100%;box-shadow:0 2px #d9c9e5}.local-note{text-align:center;color:var(--muted);margin:16px 0 0;font-size:12px;line-height:1.7}#developer-tools{margin-top:0}#developer-tools>summary{color:#79678b;font-size:13px;font-weight:400}#developer-tools .upload{text-align:center;background:#efe6f9;border:1px solid #cdbadb;min-height:44px;padding:10px 12px;font-size:14px;display:grid}#developer-tools details{margin-top:0}#developer-tools .control-note{color:#73637e;margin:0;font-size:12px;line-height:1.65}.reference-strip{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;min-width:0;display:grid}.reference-strip figure{background:#fffcf8;border:1px solid #d7c6e4;border-radius:12px;flex-direction:column;gap:5px;min-width:0;margin:0;padding:6px;display:flex}.reference-strip img{object-fit:contain;border-radius:7px;width:100%;height:120px;display:block}.reference-strip figcaption{text-align:center;color:#746180;font-size:12px}#reference-status{color:#9b3c38;grid-column:1/-1;margin:0;font-size:12px}#depth-inspection-canvas{cursor:crosshair;width:100%;height:auto;margin:10px 0}#depth-inspection pre,#depth-debug{white-space:pre-wrap;overflow-wrap:anywhere;color:#6b577b;max-width:100%;font-size:12px}.depth-coordinates{grid-template-columns:1fr 1fr;gap:8px;display:grid}.depth-coordinates label{gap:5px;font-size:13px;display:grid}.depth-coordinates input{width:100%;min-width:0}.app-footer{letter-spacing:.4px;color:#73607f;justify-content:space-between;gap:20px;padding:28px 48px 22px;font-size:12px;display:flex}.app-footer>span:last-child{font-style:italic}@keyframes selection-pop{0%{transform:scale(.96)}65%{transform:scale(1.035)}to{transform:scale(1)}}@media (hover:hover){button:not(:disabled):hover{filter:brightness(.98)}.pattern-card:hover{border-color:#aa88c6}.primary-upload:hover{background:#ffcca6}}@media (width>=1600px){.stage{height:740px}}@media (width<=1100px){.app-header{padding:24px 28px}main{grid-template-columns:minmax(0,1fr) 340px;gap:22px;padding:0 28px}aside{padding:21px 18px}.photo-mat{padding:16px 16px 0}.stage{height:clamp(410px,61vh,660px)}.processing-card{flex-direction:column;align-items:flex-start;gap:10px}.preview-heading .eyebrow{letter-spacing:1px}.preview-chip{display:none}}@media (width<=850px){.app-header{padding:24px 24px 22px}main{flex-direction:column;gap:18px;padding:0 24px;display:flex}.visual-column{width:100%;position:static}.photo-mat{padding:18px 18px 0}.stage{height:clamp(360px,60vh,610px)}aside{width:100%;padding:23px 24px}.editor-heading{margin-bottom:17px}.processing-card{flex-direction:row;align-items:center;padding:20px 4px 0}.pattern-swatch{height:88px}.tool-panel{gap:22px}.app-footer{padding:24px 28px}.preview-chip{display:inline-block}.header-note{display:none}}@media (width<=480px){.app-header{gap:12px;padding:21px 17px 19px}.brand{letter-spacing:-1px;gap:7px;font-size:24px}.brand-mark{font-size:35px}.brand-dot{font-size:31px}.primary-upload{border-radius:14px;min-height:44px;padding:9px 12px;font-size:13px}.primary-upload>span{font-size:20px}main{gap:17px;padding:0 12px}.photo-mat{border-radius:23px;padding:11px 11px 0}.preview-heading{gap:6px;margin:2px 2px 11px}.eyebrow{letter-spacing:1.2px;font-size:12px}.preview-chip{padding:5px 8px;font-size:12px}.stage{border-radius:13px;height:clamp(320px,49svh,455px)}.photo-caption{min-height:45px;padding:0 4px;font-size:12px}.caption-spark{font-size:22px}#hint{padding:8px 10px;font-size:12px;bottom:13px}#empty{gap:13px;padding:20px}#empty strong{font-size:19px}.empty-star{font-size:49px}.processing-card{flex-direction:column;align-items:flex-start;gap:9px;padding:19px 5px 0}#status{font-size:13px}#ai-depth{min-height:44px;padding:8px 12px;font-size:12px}aside{border-radius:24px;padding:21px 17px}.editor-heading h1{font-size:23px}.editor-sticker{border-radius:12px;width:40px;height:40px;font-size:26px}.editor-heading .eyebrow{font-size:12px}.pattern-swatch{height:76px}.pattern-detail{font-size:12px}.pattern-name{font-size:14px}#pattern-cards{gap:8px}.tool-panel{gap:20px}.app-footer{padding:22px 19px;font-size:12px}.app-footer>span:last-child{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition:none!important;animation:none!important}button:not(:disabled):active,.upload:active{transform:none}}html,body,#app{width:100%;min-height:100%}body{overflow:hidden}#app{max-width:none}#experience{width:100%;height:100dvh;min-height:320px;margin:0;padding:0;display:block;position:relative;overflow:hidden}#experience .stage{background:var(--room);border:0;border-radius:0;width:100%;height:100%;position:absolute;inset:0}#canvas-wrap,#canvas-wrap canvas{border-radius:0}#canvas-wrap{transition:opacity .65s}#experience:not([data-flow=ready]) #canvas-wrap{opacity:0;pointer-events:none}#experience:not([data-flow=ready]) #hint{visibility:hidden}.scene-toolbar{z-index:2;padding:max(18px,env(safe-area-inset-top)) max(22px,env(safe-area-inset-right)) 12px max(22px,env(safe-area-inset-left));pointer-events:none;justify-content:space-between;align-items:center;gap:16px;display:flex;position:absolute;top:0;left:0;right:0}.scene-toolbar>*{pointer-events:auto}.scene-brand{color:var(--ink);letter-spacing:-.5px;font-size:15px;font-weight:400;text-decoration:none}.scene-actions{align-items:center;gap:7px;display:flex}.scene-actions button,.scene-actions .upload{border:1px solid var(--line);background:var(--cream);min-height:44px;color:var(--ink);border-radius:6px;place-items:center;padding:8px 13px;font-size:14px;display:grid;box-shadow:0 1px 3px #35261510}#experience[data-flow=entry] .scene-brand,#experience:not([data-flow=ready]) .scene-actions>.upload{visibility:hidden}.welcome,.flow-overlay{background:var(--room);text-align:center;flex-direction:column;justify-content:center;align-items:center;padding:70px 24px 36px;display:flex;position:absolute;inset:0;overflow:auto}.welcome h1{letter-spacing:0;margin:8px 0 15px;font-family:inherit;font-size:clamp(30px,4.5vw,48px);font-weight:400;line-height:1.35}.entry-kicker{color:var(--muted);letter-spacing:.8px;margin:19px 0 0;font-size:13px}.welcome .primary-upload{color:#fffaf0;background:#6e4932;border:1px solid #63422d;border-radius:5px;min-width:208px;margin:0;padding:12px 23px;font-size:15px;box-shadow:0 2px 3px #4223111c}.entry-samples{min-height:44px;color:var(--muted);text-underline-offset:4px;background:0 0;border:0;border-radius:0;margin:10px 0 0;padding:8px 14px;font-size:13px;text-decoration:underline}.entry-privacy{color:var(--muted);margin:27px 0 0;font-size:12px}.entry-door{border:3px solid #79583e;border-bottom-width:7px;border-radius:2px;width:39px;height:59px;padding:3px;position:relative}.entry-door:before{content:"";background:#a38851;border:1px solid #735d35;width:4px;height:8px;position:absolute;bottom:15px;right:-3px}.entry-door>span{opacity:.6;background:#b8c0b3;border:1px solid #8b967f;width:100%;height:37px;display:block}.flow-overlay{z-index:1}.flow-photo{object-fit:contain;border:6px solid var(--cream);width:auto;max-width:min(43vw,190px);height:auto;max-height:27svh;margin-bottom:30px;display:block;box-shadow:0 2px 8px #49341d1f}.flow-overlay h2{letter-spacing:-.6px;word-break:keep-all;max-width:500px;margin:0;font-size:clamp(20px,3vw,27px);font-weight:400;line-height:1.6}#flow-detail{max-width:470px;color:var(--muted);overflow-wrap:anywhere;margin:13px 0 23px;font-size:14px;line-height:1.8}.flow-actions{flex-wrap:wrap;justify-content:center;align-items:center;gap:10px;max-width:450px;display:flex}.flow-actions button,.flow-actions .upload{border:1px solid var(--line);background:var(--cream);border-radius:5px;min-height:44px;padding:10px 15px;font-size:14px}#flow-flat{background:0 0}#hint{bottom:max(25px,env(safe-area-inset-bottom));border:1px solid var(--line);background:var(--cream);max-width:calc(100% - 40px);color:var(--ink);border-radius:4px;padding:11px 18px;font-size:14px;line-height:1.65;box-shadow:0 2px 10px #382a1410}#hint strong{font-size:15px;font-weight:400;display:block}#hint .hint-secondary{color:var(--muted);font-size:12px;display:block}#settings-dialog{border:0;border-left:1px solid var(--line);background:var(--cream);width:min(410px,100%);max-width:100%;height:100dvh;max-height:100dvh;color:var(--ink);overscroll-behavior:contain;border-radius:0;margin:0 0 0 auto;padding:0}#settings-dialog::backdrop{background:#201a1366}#settings-dialog aside{width:100%;min-height:100%;padding:25px 24px max(24px,env(safe-area-inset-bottom));box-shadow:none;border:0;border-radius:0}#settings-dialog .editor-heading{margin-bottom:17px;padding:0}.editor-heading h2{letter-spacing:-.5px;margin:0;font-size:20px}#settings-close{background:0 0;border-radius:5px;padding:7px 12px;font-size:13px}.theme-setting{grid-template-columns:auto minmax(0,1fr);align-items:center;gap:20px;padding-bottom:22px;font-size:14px;display:grid}.theme-setting select{width:100%}#settings-dialog .processing-card{border-top:1px solid var(--line);flex-direction:column;align-items:stretch;margin-top:20px;padding-top:20px}#settings-dialog .processing-card button{width:100%}:root{--room:#f1ebff}:root[data-theme=wood]{color:#3e3429;--room:#e6dfcf;--ink:#3e3429;--muted:#726554;--cream:#f8f4e9;--purple:#705039;--lavender:#e8dfcf;--apricot:#e0d1b5;--line:#cfc3ad;--shadow:#b1a084;background:#e6dfcf}[data-theme=wood] button,[data-theme=wood] select,[data-theme=wood] .upload{border-radius:5px}[data-theme=wood] button:not(:disabled):active,[data-theme=wood] .upload:active{box-shadow:none;transform:translateY(1px)}[data-theme=wood] button:focus-visible,[data-theme=wood] select:focus-visible,[data-theme=wood] input:focus-visible,[data-theme=wood] summary:focus-visible,[data-theme=wood] a:focus-visible,[data-theme=wood] #canvas-wrap:focus-visible,[data-theme=wood] .upload:focus-within{outline-color:#765534}[data-theme=wood] aside{background:#f8f4e9}[data-theme=wood] #tool-tabs{background:0 0;border:0;border-bottom:1px solid #cfc3ad;border-radius:0;gap:0;padding:0}[data-theme=wood] #tool-tabs button{color:#756651;border-radius:0}[data-theme=wood] #tool-tabs button[aria-selected=true]{box-shadow:none;color:#3e3429;background:0 0;border:0;border-bottom:2px solid #785735}[data-theme=wood] .pattern-card{box-shadow:none;background:#faf7ed;border:1px solid #cfc3ad;border-radius:4px;padding:5px 5px 9px}[data-theme=wood] .pattern-card[aria-pressed=true]{background:#e9dfca;border:1px solid #725334;animation:none;box-shadow:inset 0 0 0 1px #725334}[data-theme=wood] .pattern-swatch{filter:saturate(.35)sepia(.12);border-color:#a99b84;border-radius:1px}[data-theme=wood] .pattern-detail{color:#6c5d47}[data-theme=wood] output{color:#614831;background:#e9e0ce;border-radius:3px}[data-theme=wood] input[type=range]{accent-color:#84633f}[data-theme=wood] input[type=range]::-webkit-slider-runnable-track{background:#d1c5ae;height:4px}[data-theme=wood] input[type=range]::-webkit-slider-thumb{background:#856344;width:20px;height:20px;margin-top:-8px;box-shadow:0 0 0 1px #a28967}[data-theme=wood] input[type=range]::-moz-range-track{background:#d1c5ae;height:4px}[data-theme=wood] input[type=range]::-moz-range-thumb{background:#856344;width:16px;height:16px;box-shadow:0 0 0 1px #a28967}[data-theme=wood] .range-ends,[data-theme=wood] #developer-tools>summary,[data-theme=wood] #developer-tools .control-note,[data-theme=wood] #depth-inspection pre,[data-theme=wood] #depth-debug,[data-theme=wood] .reference-strip figcaption{color:#726554}[data-theme=wood] .quiet-button,[data-theme=wood] .tactile-button{box-shadow:none;color:#584630;background:#ede4d2;border-color:#baa98d}[data-theme=wood] .intro-symbol{color:#816440;background:#e9dfcc;border-radius:4px}[data-theme=wood] details{border-color:#d6cbb9}[data-theme=wood] summary>span{color:#8b7657}[data-theme=wood] .details-content input[type=number],[data-theme=wood] select{background:#fffdf6;border-color:#cfc3ad}[data-theme=wood] .sample-strip img{box-shadow:none;border-radius:3px}[data-theme=wood] #developer-tools .upload{background:#e9e0ce;border-color:#cfc3ad}[data-theme=wood] .reference-strip figure{background:#fffdf6;border-color:#cfc3ad;border-radius:3px}[data-theme=booth] .welcome .primary-upload{background:var(--apricot);color:#593c31;border-color:#a76948;border-radius:16px;box-shadow:0 4px #cc9b7b}[data-theme=booth] .welcome h1{font-family:inherit;font-weight:400}[data-theme=booth] .entry-door{border-color:#967ab1}[data-theme=booth] .scene-actions button,[data-theme=booth] .scene-actions .upload,[data-theme=booth] #hint{border-radius:18px}@media (width<=480px){.scene-toolbar{padding:14px 14px 8px}.scene-brand{font-size:13px}.scene-actions{gap:5px}.scene-actions button,.scene-actions .upload{padding:7px 10px;font-size:14px}#settings-dialog{border-top:1px solid var(--line);border-radius:12px 12px 0 0;width:100%;height:90dvh;max-height:90dvh;margin:auto 0 0}#settings-dialog aside{padding:21px 20px max(28px,env(safe-area-inset-bottom))}.welcome{padding-top:64px}#hint{bottom:max(18px,env(safe-area-inset-bottom));padding:9px 13px;font-size:12px}#hint strong{font-size:14px}}@media (height<=590px){.welcome{justify-content:flex-start}.entry-door{display:none}.welcome h1{font-size:27px;line-height:1.35}.entry-privacy{margin-top:14px}.flow-photo{max-height:20svh;margin-bottom:16px}}@media (prefers-reduced-motion:reduce){#canvas-wrap{transition:none}}@media (height<=590px){#hint{padding:8px 12px;font-size:12px;bottom:12px}#hint strong,#hint .hint-secondary{display:none}}#gyro-notice{bottom:max(20px,env(safe-area-inset-bottom));width:max-content;max-width:calc(100% - 40px);color:var(--ink);background:var(--cream);border:1px solid var(--line);text-align:center;pointer-events:none;z-index:5;border-radius:14px;margin:0;padding:10px 14px;font-size:14px;line-height:1.6;position:absolute;left:50%;transform:translate(-50%)}#experience:not([data-flow=ready]) #gyro-notice{display:none}#render-recovery{border:1px solid var(--line);background:var(--cream);width:min(420px,100% - 36px);color:var(--ink);text-align:center;border-radius:12px;padding:28px}#render-recovery::backdrop{background:var(--room)}#render-recovery h2{font-size:24px;font-weight:400;line-height:1.4}#render-recovery p{font-size:15px}#render-reload{border-color:var(--line);padding:10px 24px}.journey{--journey-height:clamp(144px,30dvh,236px);--journey-car-width:58%;width:min(460px,88vw);height:var(--journey-height);flex:none;margin:0 0 24px;position:relative;overflow:hidden}.journey-scenery{position:absolute;inset:0;overflow:hidden}.journey-sun{opacity:.65;background:#dfbb73;border-radius:50%;width:34px;height:34px;position:absolute;top:9%;right:15%}.journey-cloud{background:var(--cream);border-radius:50%;width:65px;height:13px;position:absolute;top:21%;left:16%}.journey-cloud:before{content:"";background:inherit;border-radius:50%;width:30px;height:24px;position:absolute;bottom:0;left:17px}.journey-hill{opacity:.45;background:#b6bc9c;border-radius:50% 50% 0 0;width:95%;height:45%;position:absolute;bottom:26px;left:-8%}.journey-tree{background:#9b8563;width:9px;height:55px;position:absolute;bottom:29px;right:18%}.journey-tree:before{content:"";background:#9ca883;border-radius:50% 50% 42% 42%;width:43px;height:54px;position:absolute;top:-22px;left:-17px}.journey-road{background:repeating-linear-gradient(90deg,#0000 0 22px,#bcb099 22px 44px,#0000 44px 66px) 0 12px/132px 2px repeat-x;border-top:2px solid #ada289;height:20px;position:absolute;bottom:11px;left:0;right:0}.journey-car,.journey-traveler{width:min(var(--journey-car-width),calc((var(--journey-height) - 38px) * 5 / 3));aspect-ratio:5/3;transform-origin:50% 85%;max-width:267px;position:absolute;bottom:24px;left:16%}.journey-traveler{z-index:3;pointer-events:none}.journey-car-body{z-index:2;width:100%;height:100%;position:absolute;inset:0;overflow:visible}.journey-passenger{z-index:3;background:#fcf5df;border:5px solid #fcf5df;border-radius:9px;width:34%;height:65%;position:absolute;top:0;left:22%;transform:rotate(-5deg);box-shadow:0 2px 3px #50392226}.journey-passenger .flow-photo{object-fit:contain;width:100%;max-width:none;height:100%;max-height:none;box-shadow:none;border:0;border-radius:4px;margin:0;display:block}.journey-house{opacity:0;width:27%;max-height:88%;position:absolute;bottom:26px;right:3%;transform:translate(20px)}.journey-wheel{transform-box:fill-box;transform-origin:50%}#flow-overlay[data-journey=driving] :is(.journey-car,.journey-traveler){animation:1.7s ease-in-out infinite journey-ride}#flow-overlay[data-journey=driving] .journey-wheel{animation:1.4s linear infinite journey-wheel-turn}#flow-overlay[data-journey=driving] .journey-road{animation:2.8s linear infinite journey-road-pass}#flow-overlay[data-journey=driving] .journey-tree{animation:8s linear infinite journey-tree-pass}#journey-motion{color:var(--muted);text-underline-offset:3px;background:0 0;border-color:#0000;text-decoration:underline}#flow-overlay[data-journey=unpacking]{animation:.2s ease-in 1.3s both journey-arrival-fade}#flow-overlay:is([data-journey=arrived],[data-journey=unpacking]) :is(.journey-car,.journey-traveler){transition:transform .35s ease-out;transform:translate(-10%)}#flow-overlay:is([data-journey=arrived],[data-journey=unpacking]) .journey-house{opacity:1;transition:opacity .25s ease-out,transform .35s ease-out;transform:none}#flow-overlay:is([data-journey=arrived],[data-journey=unpacking]) .journey-tree{opacity:0}#flow-overlay[data-journey=unpacking] .journey-traveler{transition:none;animation:1.3s linear both journey-walk}#flow-overlay[data-journey=unpacking] .journey-passenger{transform-origin:50% 100%;animation:1.3s ease-in-out both journey-waddle}#flow-overlay[data-motion=paused] .journey *{animation-play-state:paused}[data-theme=booth] .journey-hill{background:#c3afd9}[data-theme=booth] .journey-tree:before{background:#baa6c7}@keyframes journey-ride{0%,to{transform:translateY(0)rotate(-.3deg)}50%{transform:translateY(-2px)rotate(.3deg)}}@keyframes journey-wheel-turn{to{transform:rotate(360deg)}}@keyframes journey-road-pass{to{background-position:-132px 12px}}@keyframes journey-tree-pass{0%{transform:translate(180px)}to{transform:translate(-460px)}}@keyframes journey-walk{0%,28%{left:16%;transform:translate(-10%)}to{left:87.5%;transform:translate(-39%)}}@keyframes journey-waddle{0%{animation-timing-function:ease-out;top:0;transform:translateY(0)rotate(-5deg)scaleY(1)}8%{animation-timing-function:cubic-bezier(.4,0,.65,1);top:0;transform:translateY(-6px)rotate(-5deg)scaleY(1)}24%{animation-timing-function:ease-out;top:35%;transform:translateY(0)rotate(-5deg)scaleY(.97)}28%{top:35%;transform:translateY(0)rotate(-5deg)scaleY(1)}40%{top:35%;transform:translateY(-3px)rotate(5deg)}52%{top:35%;transform:translateY(0)rotate(-5deg)}64%{top:35%;transform:translateY(-3px)rotate(5deg)}76%{top:35%;transform:translateY(0)rotate(-5deg)}88%{top:35%;transform:translateY(-3px)rotate(5deg)}to{top:35%;transform:translateY(0)rotate(0)}}@keyframes journey-arrival-fade{0%{opacity:1}to{opacity:0}}@media (height<=650px){.flow-overlay{padding:52px 18px 18px}.journey{--journey-height:clamp(100px,27dvh,160px);--journey-car-width:54%;width:min(380px,80vw);margin-bottom:12px}.flow-overlay h2{font-size:20px;line-height:1.4}#flow-detail{margin:9px 0 14px;font-size:13px;line-height:1.55}}@media (height<=430px) and (width>=560px){.flow-overlay{grid-template-columns:minmax(170px,40%) minmax(0,1fr);align-content:center;justify-items:center;column-gap:24px;padding:52px 30px 18px;display:grid}.journey{--journey-height:170px;grid-row:1/4;width:100%;margin:0}.flow-overlay h2,#flow-detail,.flow-actions{grid-column:2}}@media (prefers-reduced-motion:reduce){.journey *{transition:none!important;animation:none!important}#flow-overlay[data-journey=unpacking]{animation:none}}.comparison-control{border:1px solid var(--line);border-radius:12px;padding:14px}.comparison-control h3{margin:0 0 8px;font-size:17px;font-weight:400}.comparison-control button{width:100%;padding:10px}.comparison-control details{margin-top:10px}#comparison-overlay{z-index:1;pointer-events:none;position:absolute;inset:0}.comparison-label{text-align:center;color:var(--ink);font-size:14px;line-height:1.3;position:absolute;transform:translate(-50%)}#comparison-metrics{bottom:max(10px,env(safe-area-inset-bottom));text-align:center;font-family:var(--font-values);color:var(--ink);font-size:12px;line-height:1.45;position:absolute;left:10px;right:10px}#comparison-metrics p{white-space:pre-line;margin:3px 0}#experience:not([data-flow=ready]) #comparison-overlay,#experience[data-comparison] #hint{visibility:hidden}#experience[data-comparison] .scene-brand{display:none}#experience[data-comparison] .scene-toolbar{justify-content:flex-end}@media (width<=480px){#experience[data-comparison] .scene-actions{flex-wrap:wrap;justify-content:flex-end}#comparison-metrics{font-size:12px}}@media (height<=500px){#comparison-memory{display:none}#comparison-metrics{line-height:1.25}}#mesh-render-error{border:1px solid var(--line);border-radius:1rem;max-width:28rem;padding:1.5rem}#mesh-render-error::backdrop{background:#21172aaa}#mesh-render-error button{margin:.5rem .5rem 0 0}.frame-notice{color:#402c21;pointer-events:none;z-index:4;background:#fff9e9ee;border-radius:.75rem;max-width:32rem;padding:.65rem 1rem;font-size:.875rem;position:absolute;bottom:1rem;left:1rem;right:1rem}#door-handle{pointer-events:none;color:#fff8df;text-shadow:0 1px 3px #32200f;z-index:1;background:#3e2c151c;border:1px solid #fff8dc66;border-radius:50%;place-items:center;width:44px;height:44px;font-family:system-ui,sans-serif;font-size:22px;display:grid;position:absolute;transform:translate(-50%,-50%)}#door-handle[hidden],#door-controls[hidden]{display:none}#door-controls{left:max(16px,env(safe-area-inset-left));bottom:max(88px,env(safe-area-inset-bottom));z-index:2;flex-direction:column;align-items:flex-start;gap:6px;display:flex;position:absolute}#door-toggle{border:1px solid var(--line);background:var(--cream);min-width:88px;min-height:44px;color:var(--ink);border-radius:6px;padding:8px 13px}#door-help{color:var(--ink);background:var(--cream);border-radius:4px;padding:3px 7px;font-size:12px}#door-toggle:focus-visible{outline-offset:3px;outline:3px solid #996130}.scene-motion{top:calc(76px + env(safe-area-inset-top));right:max(16px,env(safe-area-inset-right));z-index:4;align-items:flex-start;gap:8px;display:flex;position:absolute}.scene-motion[hidden]{display:none}.scene-motion>button,#motion-tools>summary,#door-toggle{color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;background:0 0;border:0;border-radius:4px;padding:8px 10px;font-size:14px}.scene-motion>button{align-items:center;gap:6px;display:flex}.scene-motion>button[aria-pressed=true]{text-underline-offset:5px;text-decoration:underline}#motion-tools{background:0 0;border:0;margin:0;position:relative}#motion-tools>summary{cursor:pointer;align-items:center;list-style:none;display:flex}#motion-tools>summary::-webkit-details-marker{display:none}#motion-tools>summary:after{content:"+";margin-left:6px}#motion-tools[open]>summary:after{content:"−"}#motion-tools .motion-panel{color:#fffdf6;background:#302b25f5;border:1px solid #fff5;border-radius:10px;width:min(290px,100vw - 32px);max-height:calc(100dvh - 165px);padding:16px;position:absolute;top:100%;right:0;overflow:auto;box-shadow:0 6px 24px #0003}.motion-panel .control-help,.motion-panel .range-ends{color:#ede6dc}.motion-panel .control-help{font-size:14px}.motion-panel button{color:#fffdf6;min-height:44px;box-shadow:none;background:0 0;border:1px solid #fff5;margin:4px 0}.scene-motion button:focus-visible,#motion-tools>summary:focus-visible,#door-toggle:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#door-controls{left:max(16px,env(safe-area-inset-left));bottom:calc(56px + env(safe-area-inset-bottom))}#door-toggle{text-underline-offset:5px;min-width:88px;text-decoration:underline}#hint,[data-theme=booth] #hint{bottom:calc(20px + env(safe-area-inset-bottom));max-width:calc(100% - 24px);box-shadow:none;color:#fffdf6;white-space:nowrap;text-shadow:0 1px 3px #211910,0 0 8px #211910,0 0 14px #211910;opacity:0;z-index:2;background:0 0;border:0;border-radius:0;padding:0;font-size:14px;line-height:1.5;transition:none}#hint[data-phase=in]{animation:.6s ease-out both scene-hint-in}#hint[data-phase=hold]{opacity:1}#hint[data-phase=out]{animation:.8s ease-in both scene-hint-out}@keyframes scene-hint-in{0%{opacity:0}to{opacity:1}}@keyframes scene-hint-out{0%{opacity:1}to{opacity:0}}#gyro-notice{top:calc(125px + env(safe-area-inset-top));font-size:14px;bottom:auto}@media (width<=480px){.scene-motion{top:calc(67px + env(safe-area-inset-top));gap:2px;right:10px}}@media (prefers-reduced-motion:reduce){#hint[data-phase]{animation:none}#hint[data-phase=in],#hint[data-phase=hold]{opacity:1}}#hint{white-space:normal;text-wrap:balance}.photo-tip{color:var(--ink);margin:-12px 0 18px;font-size:14px;line-height:1.7}#sample-dialog{border:1px solid var(--line);background:var(--cream);width:min(520px,100% - 28px);max-height:calc(100dvh - 28px);color:var(--ink);overscroll-behavior:contain;border-radius:12px;padding:20px;overflow:auto}#sample-dialog::backdrop{background:#201a1366}.sample-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.sample-heading h2{margin:0;font-size:21px;line-height:1.4}#sample-close{border-radius:5px;flex:none;padding:6px 12px}#sample-description{color:var(--muted);margin:10px 0 18px;font-size:13px}.sample-choices{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;display:grid}.sample-choices button{border:2px solid var(--line);text-align:left;background:var(--cream);border-radius:7px;flex-direction:column;align-items:stretch;min-width:0;padding:6px;display:flex}.sample-choices button[aria-pressed=true]{background:#e9dec6;border-color:#79583e;box-shadow:0 0 0 1px #79583e}.sample-choices img{object-fit:contain;background:#e6dfcf;border-radius:3px;width:100%;height:120px}.sample-choices span{margin-top:6px;font-size:12px;line-height:1.5}.sample-choices small{color:#67492f;font-size:11px}.sample-footer{background:var(--cream);padding:16px 0 4px;position:sticky;bottom:-20px}#sample-confirm{color:#fffaf0;background:#6e4932;border-radius:5px;width:100%;min-height:48px}@media (width<=420px){.sample-choices{grid-template-columns:repeat(2,minmax(0,1fr))}.sample-choices img{height:110px}}.pet-name-field{text-align:left;flex-direction:column;gap:7px;display:flex}.pet-name-field label{margin:0;font-size:15px;display:block}.pet-name-field input{width:100%;min-width:0;min-height:44px;color:var(--ink);font:inherit;background:#fffaf080;border:1px solid #a89170;border-radius:5px;padding:10px 12px;font-size:17px}.pet-name-field input::placeholder{color:#817565;opacity:1}.pet-name-field small{color:var(--muted);font-size:11px;line-height:1.5}.pet-name-field .name-storage-notice{color:#77472d}.entry-name-field{flex-shrink:0;width:min(100%,280px);margin:0 0 18px}.settings-name-field{margin:0 0 22px}#welcome-name,#entry-photo-button,#flow-title{overflow-wrap:anywhere}#entry-photo-button{max-width:100%}#internal-controls[hidden]{display:none!important}.arrival-count{color:var(--muted);margin:8px 0 0;font-size:12px;line-height:1.6}.flow-overlay{padding-bottom:max(64px,calc(env(safe-area-inset-bottom) + 44px))}.flow-overlay>.arrival-count{left:24px;right:24px;bottom:max(18px,env(safe-area-inset-bottom));margin:0;position:absolute}#settings-dialog .arrival-count{margin:0 0 18px}.welcome{justify-content:flex-start}.welcome>*{flex-shrink:0;max-width:100%}.welcome .entry-door{margin-top:auto}#entry-photo-step{margin-bottom:0}.entry-step{flex-direction:column;flex-shrink:0;align-items:center;gap:12px;width:min(100%,360px);display:flex}.entry-step>*{flex-shrink:0;max-width:100%}.entry-step .entry-name-field{width:100%;margin:0}.entry-step .photo-tip{margin:0}.entry-step .primary-upload{min-height:48px}.entry-step .entry-samples{margin:0}#entry-name-edit{align-self:center;min-height:44px;margin:0 0 16px;font-size:14px}#paste-tip span{white-space:nowrap}.welcome[data-step=name] #entry-name-step{margin-bottom:auto}.scene-actions{flex-wrap:wrap;justify-content:flex-end}#entry-notices{width:min(100%,360px);color:var(--muted);touch-action:pan-y pinch-zoom;flex-shrink:0;grid-template-columns:44px minmax(0,1fr) 44px;align-items:center;margin:8px 0 auto;display:grid}#entry-notices>button{min-width:44px;min-height:44px;box-shadow:none;color:var(--ink);background:0 0;border:0;padding:0;font-family:system-ui,sans-serif;font-size:24px}.notice-slides{align-items:center;min-width:0;display:grid}#entry-notices .entry-notice-slide{overflow-wrap:anywhere;word-break:keep-all;visibility:hidden;grid-area:1/1;margin:0;padding:0;font-size:13px;line-height:1.65}#entry-notices .entry-notice-slide[data-active=true]{visibility:visible}#entry-notices .entry-notice-slide[hidden]{display:none}#notice-position{opacity:.75;grid-column:2;font-family:inherit;font-size:10px;line-height:1.4}#entry-notices[hidden]{display:none}@media (width<=640px){.welcome[data-step=photo]{padding-bottom:max(16px,env(safe-area-inset-bottom))}.welcome[data-step=photo] #entry-photo-step{margin-bottom:24px}.welcome[data-step=photo] #entry-notices{margin-top:auto;margin-bottom:0}}.scene-toolbar{grid-template-columns:auto minmax(0,1fr);align-items:start;gap:6px 12px;display:grid}.scene-brand{white-space:nowrap;padding-top:10px}.scene-actions{grid-column:2;min-width:0}.scene-motion{flex-direction:column;grid-column:1/-1;justify-self:end;align-items:flex-end;gap:6px;max-width:100%;display:flex;position:static}#gyro,#gyro[aria-pressed=true],#gyro[aria-busy=true]{color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;background:0 0;border:0;border-radius:4px;padding:8px 10px;text-decoration:underline}#scene-motion[hidden]{display:none}#gyro-notice{width:auto;max-width:min(290px,100%);color:var(--ink);background:var(--cream);text-shadow:none;margin:0;padding:8px 12px;font-size:13px;position:static;inset:auto;transform:none}#panel-view{color:var(--ink);gap:16px}#panel-view select{color:var(--ink);background:var(--cream)}#panel-view .control-help{margin:0}#panel-view button{min-height:44px}#tool-tabs{grid-template-columns:repeat(3,minmax(0,1fr))}#gyro:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#credits-dialog{border:1px solid var(--line);background:var(--cream);width:min(400px,100% - 32px);max-height:calc(100dvh - 32px);color:var(--ink);border-radius:12px;padding:24px;overflow:auto}#credits-dialog::backdrop{background:#201a1366}.credits-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.credits-heading h2{margin:0;font-size:22px}#credits-close{min-height:44px;padding:6px 12px}.credits-info{gap:6px;margin:20px 0;display:grid}.credits-info dt{color:var(--muted);font-size:13px}.credits-info dd{overflow-wrap:anywhere;margin:0 0 10px}#credits-dialog a{color:var(--ink);text-underline-offset:4px}.credits-licenses{padding:8px 0;font-size:13px;display:inline-block}#experience[data-flow=entry] #scene-zoom-reset,#experience[data-flow=entry] #comparison-exit{display:none}#export-dialog{border:1px solid var(--line);background:var(--cream);width:min(560px,100% - 24px);max-height:calc(100dvh - 24px);color:var(--ink);border-radius:12px;padding:20px;overflow:auto}#export-dialog::backdrop{background:#201a1380}.export-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.export-heading h2{margin:0;font-size:22px}#export-dialog button,.export-actions a{min-height:44px;padding:9px 12px}.export-choices,.export-actions{flex-wrap:wrap;gap:8px;margin-top:16px;display:flex}#export-status{font-size:14px;line-height:1.6}#export-preview{object-fit:contain;border:1px solid var(--line);background-color:#fff;background-image:linear-gradient(45deg,#ddd 25%,#0000 25%),linear-gradient(-45deg,#ddd 25%,#0000 25%),linear-gradient(45deg,#0000 75%,#ddd 75%),linear-gradient(-45deg,#0000 75%,#ddd 75%);background-position:0 0,0 8px,8px -8px,-8px 0;background-size:16px 16px;width:100%;max-height:50dvh;display:block}#export-preview[hidden]{display:none}.export-actions a{color:var(--cream);background:var(--ink);border-radius:6px;align-items:center;display:inline-flex}.export-actions a[hidden]{display:none}#gyro-recenter{right:max(16px,env(safe-area-inset-right));bottom:calc(56px + env(safe-area-inset-bottom));z-index:3;color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;background:0 0;border:0;border-radius:4px;padding:8px 10px;text-decoration:underline;position:absolute}#gyro-recenter:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#first-guide{display:none}#guide-scene-target{pointer-events:none;width:52%;height:27%;position:absolute;top:28%;left:24%}.behind-glass-tour{font-family:var(--font-ui);color:var(--ink);background:var(--cream);border:1px solid var(--line);border-radius:10px;width:min(340px,100vw - 32px);min-width:0;max-width:calc(100vw - 32px);padding:18px;font-weight:400;overflow:visible;box-shadow:0 4px 20px #201a1326}.behind-glass-tour .driver-popover-title{font-family:inherit;font-size:21px;font-weight:400;line-height:1.5}.behind-glass-tour .driver-popover-description{font-family:inherit;font-size:15px;line-height:1.8}.behind-glass-tour .driver-popover-footer button{min-height:44px;font:inherit;text-shadow:none;border:1px solid var(--line);border-radius:5px;padding:8px 14px;font-size:14px}.behind-glass-tour .driver-popover-next-btn{background:var(--ink);color:var(--cream)}.behind-glass-tour .driver-popover-prev-btn{color:var(--ink);background:0 0}.behind-glass-tour .driver-popover-close-btn{width:auto;height:auto;min-height:44px;font:inherit;color:var(--muted);box-shadow:none;background:0 0;border:0;margin:0 0 8px auto;padding:4px 8px;font-size:13px;display:block;position:static}.behind-glass-tour .driver-popover-progress-text{font:inherit;color:var(--muted);font-size:12px}.behind-glass-tour .driver-popover-arrow-side-top{border-top-color:var(--cream)}.behind-glass-tour .driver-popover-arrow-side-bottom{border-bottom-color:var(--cream)}.behind-glass-tour button:focus-visible{outline:2px solid var(--ink);outline-offset:3px}.behind-glass-tour .guide-popover-content{max-height:max(80px,calc(100dvh - 68px - env(safe-area-inset-top) - env(safe-area-inset-bottom)));overflow:auto}.behind-glass-tour .driver-popover-arrow-side-left{border-left-color:var(--cream)}.behind-glass-tour .driver-popover-arrow-side-right{border-right-color:var(--cream)}.scene-toolbar{grid-template-columns:minmax(0,1fr) auto;align-items:start}.scene-brand{display:none}#scene-menu-open{color:#fffdf6;min-width:44px;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;background:0 0;border:0;border-radius:4px;grid-area:1/1;justify-self:start;padding:8px 10px;font-size:14px;text-decoration:underline}#scene-menu-open:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}.scene-toolbar .scene-motion{grid-area:1/2;min-width:0;max-width:min(65vw,290px)}.scene-toolbar .scene-actions{grid-area:1/2}#experience:not([data-flow=entry]) .scene-actions{display:none}#scene-menu{width:min(440px,100%);max-width:100%;max-height:calc(100dvh - max(24px,env(safe-area-inset-top)));padding:20px max(20px,env(safe-area-inset-right)) max(20px,env(safe-area-inset-bottom)) max(20px,env(safe-area-inset-left));border:1px solid var(--line);background:var(--cream);color:var(--ink);overscroll-behavior:contain;border-bottom:0;border-radius:18px 18px 0 0;margin:auto auto 0;overflow:auto}#scene-menu::backdrop{background:#201a1380}.scene-menu-heading{justify-content:space-between;align-items:center;gap:16px;margin-bottom:8px;display:flex}.scene-menu-heading h2{margin:0;font-size:22px}#scene-menu-close{min-width:44px;min-height:44px;color:var(--muted);box-shadow:none;background:0 0;border:0;padding:8px}.scene-menu-items{flex-direction:column;display:flex}.scene-menu-items>button{text-align:left;border:0;border-bottom:1px solid var(--line);width:100%;min-height:52px;color:var(--ink);box-shadow:none;background:0 0;border-radius:0;padding:12px 4px;font-family:inherit;font-size:16px}.scene-menu-items>button:last-child{border-bottom:0}.scene-menu-items>button:disabled{opacity:.45}#scene-menu button:focus-visible{outline:2px solid var(--ink);outline-offset:-2px}#scene-menu-open[hidden],.scene-menu-items>button[hidden]{display:none}.scene-toolbar{grid-template-columns:minmax(0,1fr) 44px minmax(0,1fr);column-gap:6px}.scene-toolbar .scene-motion,.scene-toolbar .scene-actions{grid-column:3}#sample-home{color:#fffdf6;width:44px;min-height:44px;box-shadow:none;background:0 0;border:0;border-radius:4px;grid-area:1/2;place-items:center;padding:8px;display:grid}#sample-home svg{filter:drop-shadow(0 1px 2px #211910)}#sample-home:focus-visible,#photo-adjust-open:focus-visible{outline-offset:2px;outline:2px solid #fffdf6;box-shadow:0 0 0 5px #302b25}#sample-home[hidden]{display:none}#gyro{white-space:nowrap;padding-inline:4px}#photo-adjust-open{left:50%;bottom:max(12px,env(safe-area-inset-bottom));z-index:3;color:#fffdf6;min-height:44px;box-shadow:none;text-shadow:0 1px 3px #211910,0 0 7px #211910;text-underline-offset:5px;white-space:nowrap;background:0 0;border:0;border-radius:4px;padding:8px 12px;font-size:14px;text-decoration:underline;position:absolute;transform:translate(-50%)}#photo-adjust-panel{z-index:4;left:50%;bottom:max(12px,env(safe-area-inset-bottom));border:1px solid var(--line);width:min(400px,100% - 24px);max-height:45dvh;color:var(--ink);background:var(--cream);border-radius:12px;padding:12px 16px;position:absolute;overflow:auto;transform:translate(-50%);box-shadow:0 3px 16px #201a1326}.photo-adjust-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.photo-adjust-heading strong{font-size:17px;font-weight:400}#photo-adjust-panel button{min-height:44px;padding:8px 12px}#photo-adjust-done{color:var(--cream);background:var(--ink)}#photo-adjust-panel label{align-items:center;gap:8px;margin-top:8px;font-size:14px;display:flex}#photo-adjust-zoom{flex:1;min-width:0;min-height:44px}#photo-adjust-help{word-break:keep-all;margin:8px 0 0;font-size:13px;line-height:1.6}#photo-adjust-reset{color:var(--muted);box-shadow:none;background:0 0;border:0;font-size:13px;padding-left:0!important}#photo-adjust-panel[hidden],#photo-adjust-open[hidden]{display:none}#home-dialog{border:1px solid var(--line);background:var(--cream);width:min(380px,100% - 32px);max-height:calc(100dvh - 32px);color:var(--ink);border-radius:12px;padding:24px;overflow:auto}#home-dialog::backdrop{background:#201a1380}#home-title{word-break:keep-all;margin:0 0 12px;font-size:22px;line-height:1.5}#home-detail{color:var(--muted);font-size:14px;line-height:1.7}.home-actions{flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:20px;display:flex}.home-actions button{min-height:44px;padding:10px 14px}#home-confirm{color:var(--cream);background:var(--ink)}#hint,[data-theme=booth] #hint{bottom:calc(112px + env(safe-area-inset-bottom))}.driver-popover{all:unset;font-family:var(--driver-popover-font-family,"Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif);box-sizing:border-box;color:#2d2d2d;z-index:1000000000;background-color:#fff;border-radius:5px;min-width:250px;max-width:300px;margin:0;padding:15px;position:fixed;top:0;right:0;box-shadow:0 1px 10px #0006}.driver-popover-title{zoom:1;margin:0;font-size:19px;font-weight:700;line-height:1.5;display:block;position:relative}.driver-popover-close-btn{all:unset;cursor:pointer;color:#d2d2d2;z-index:1;text-align:center;width:32px;height:28px;font-size:18px;font-weight:500;transition:color .2s;position:absolute;top:0;right:0}.driver-popover-close-btn:hover,.driver-popover-close-btn:focus{color:#2d2d2d}.driver-popover-title[style*=block]+.driver-popover-description{margin-top:5px}.driver-popover-description{zoom:1;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.5}.driver-popover-footer{text-align:right;zoom:1;justify-content:space-between;align-items:center;margin-top:15px;display:flex}.driver-popover-progress-text{color:#727272;zoom:1;font-size:13px;font-weight:400}.driver-popover-footer-btn{all:unset;box-sizing:border-box;color:#2d2d2d;cursor:pointer;zoom:1;background-color:#fff;border:1px solid #ccc;border-radius:3px;outline:0;padding:3px 7px;font-size:12px;line-height:1.3;text-decoration:none;display:inline-block}.driver-popover-footer .driver-popover-btn-disabled{opacity:.5;pointer-events:none}.driver-popover-footer-btn:hover,.driver-popover-footer-btn:focus{background-color:#f7f7f7}.driver-popover-navigation-btns{flex-grow:1;justify-content:flex-end;display:flex}.driver-popover-navigation-btns button+button{margin-left:4px}.driver-popover-arrow{content:"";border:5px solid #fff;position:absolute}.driver-popover-arrow-side-over{display:none}.driver-popover-arrow-side-left{border-top-color:#0000;border-bottom-color:#0000;border-right-color:#0000;left:100%}.driver-popover-arrow-side-right{border-top-color:#0000;border-bottom-color:#0000;border-left-color:#0000;right:100%}.driver-popover-arrow-side-top{border-bottom-color:#0000;border-left-color:#0000;border-right-color:#0000;top:100%}.driver-popover-arrow-side-bottom{border-top-color:#0000;border-left-color:#0000;border-right-color:#0000;bottom:100%}.driver-popover-arrow-side-center,.driver-popover-arrow-none{display:none}.driver-active .driver-overlay{pointer-events:none}.driver-active.driver-no-scroll{overflow:hidden}.driver-active *{pointer-events:none}.driver-active .driver-active-element,.driver-active .driver-active-element *,.driver-popover,.driver-popover *{pointer-events:auto}@keyframes animate-fade-in{0%{opacity:0}to{opacity:1}}.driver-fade .driver-overlay{animation:animate-fade-in var(--driver-animation-duration,.4s) ease-in-out}.driver-fade .driver-popover{animation:animate-fade-in var(--driver-animation-duration,.4s)}.driver-active-element-parent-no-scroll{overflow:hidden!important}.driver-no-interaction,.driver-no-interaction *{pointer-events:none!important}.peeking-experiment{border-top:1px solid var(--line,#cfc3ad);margin-top:20px;padding-top:18px}.peeking-experiment h3{margin:0 0 8px;font-size:16px}.peeking-experiment p{color:var(--ink,#3e3429);margin:8px 0 12px;font-size:13px;line-height:1.65}.peeking-experiment button{width:100%;min-height:44px;margin-top:8px;padding:10px 12px;font-size:14px}.peeking-experiment [hidden],.peeking-preview-dialog [hidden]{display:none!important}.peeking-preview-dialog{overscroll-behavior:contain;border:1px solid var(--line,#cfc3ad);background:var(--cream,#f7f1e5);width:min(760px,100% - 32px);max-width:760px;max-height:calc(100dvh - 32px);color:var(--ink,#3e3429);box-sizing:border-box;border-radius:12px;margin:auto;padding:24px;overflow:auto}.peeking-preview-dialog::backdrop{background:#201a13a6}.peeking-preview-dialog h2{margin:0 0 10px;font-size:20px;line-height:1.4}.peeking-preview-dialog p{overflow-wrap:anywhere;font-size:14px;line-height:1.6}.peeking-preview-dialog #peeking-error{color:#862d25}.peeking-comparison{grid-template-columns:1fr 1fr;gap:14px;margin:18px 0;display:grid}.peeking-comparison figure{min-width:0;margin:0}.peeking-preview-surface{aspect-ratio:1;background-color:#fff;background-image:repeating-conic-gradient(#e3dfd5 0% 25%,#0000 0% 50%);background-size:20px 20px;border:1px solid #aa9c85;border-radius:6px;place-items:center;display:grid;overflow:hidden}.peeking-preview-surface img{object-fit:contain;width:100%;min-width:0;height:100%;min-height:0;display:block}.peeking-comparison figcaption{margin-top:7px;font-size:13px;line-height:1.4}.peeking-actions{flex-wrap:wrap;gap:10px;margin-top:20px;display:flex}.peeking-actions button{min-height:44px;padding:10px 14px;font-size:14px}.peeking-actions #peeking-accept{color:#3e3429;background:#ede4d2;border-color:#aa9674}.peeking-experiment button:focus-visible,.peeking-preview-dialog button:focus-visible{outline-offset:3px;outline:3px solid #765534}@media (width<=480px){.peeking-preview-dialog{width:calc(100% - 20px);max-height:calc(100dvh - 20px);padding:18px}.peeking-comparison{gap:8px}.peeking-comparison figcaption{font-size:12px}.peeking-actions button{flex:calc(50% - 10px)}} diff --git a/dist/assets/index-BYcEjj7E.js b/dist/assets/index-DoRt0pZc.js similarity index 99% rename from dist/assets/index-BYcEjj7E.js rename to dist/assets/index-DoRt0pZc.js index 2364e86..42d4002 100644 --- a/dist/assets/index-BYcEjj7E.js +++ b/dist/assets/index-DoRt0pZc.js @@ -4170,4 +4170,4 @@ void main() { #include } `,Dh=class extends q{constructor(e,t,n=.25,r=0){let i=new za(1,1,128,128),a=new ya({uniforms:{uTexture:{value:e},uDepthMap:{value:t},uDepthScale:{value:V.clamp(n,0,.4)},uDepthBias:{value:r},uIsVideo:{value:!1},uUsePhotoAlpha:{value:!1}},vertexShader:Th,fragmentShader:Eh,alphaToCoverage:!0});super(i,a)}setTexture(e){this.material.uniforms.uTexture.value=e}setDepthMap(e){this.material.uniforms.uDepthMap.value=e}setDepthScale(e){this.material.uniforms.uDepthScale.value=V.clamp(e,0,.4)}setVideo(e){this.material.uniforms.uIsVideo.value=e}get depthMap(){return this.material.uniforms.uDepthMap.value}},Oh=[{name:`nose`,x:235,y:310},{name:`left-eye`,x:198,y:278},{name:`right-eye`,x:249,y:273},{name:`face`,x:221,y:267},{name:`left-ear`,x:158,y:213},{name:`right-ear`,x:262,y:206},{name:`body`,x:139,y:419}],kh=class{values=null;width=0;height=0;sampleKind=``;setSample(e){let t=e.naturalWidth||e.width,n=e.naturalHeight||e.height,r=document.createElement(`canvas`);r.width=t,r.height=n;let i=r.getContext(`2d`);if(!i||t<1||n<1){this.clear();return}i.drawImage(e,0,0,t,n),this.values=i.getImageData(0,0,t,n).data,this.width=t,this.height=n,this.sampleKind=`sample`}clear(){this.values=null,this.width=0,this.height=0,this.sampleKind=``}update(e,t,n,r,i,a,o){if(!this.values||!e||!t||this.sampleKind===``)return``;e.updateMatrixWorld(),t.updateMatrixWorld(!0);let s=a+(o-r)*n,c=Math.max(0,.6-s),l=[`cameraX=${e.position.x.toFixed(3)} sample=${this.sampleKind}`,`contentBaseZ=${a.toFixed(3)} maxFrontZ=${s.toFixed(3)} glassGap=${c.toFixed(3)}`],u=new W,d=new W,f=new W;for(let a of Oh){let o=this.sampleBilinear(a.x,a.y),s=(a.x+.5)/this.width,c=1-(a.y+.5)/this.height;u.set(s-.5,c-.5,(o-r)*n),d.copy(u),t.localToWorld(d),f.copy(d).project(e);let p=(f.x*.5+.5)*i;l.push(`${a.name}: depth=${o.toFixed(3)} worldZ=${d.z.toFixed(3)} projectedX=${p.toFixed(3)}px`)}return l.join(` -`)}sampleBilinear(e,t){if(!this.values||this.width<1||this.height<1)return 0;let n=V.clamp(e,0,this.width-1),r=V.clamp(t,0,this.height-1),i=Math.floor(n),a=Math.floor(r),o=Math.min(i+1,this.width-1),s=Math.min(a+1,this.height-1),c=n-i,l=r-a,u=this.gray(i,a),d=this.gray(o,a),f=this.gray(i,s),p=this.gray(o,s);return V.lerp(V.lerp(u,d,c),V.lerp(f,p,c),l)}gray(e,t){return this.values[(t*this.width+e)*4]/255}},Ah=class{canvas=document.querySelector(`#depth-inspection-canvas`);summary=document.querySelector(`#depth-inspection-summary`);point=document.querySelector(`#depth-inspection-point`);xInput=document.querySelector(`#depth-inspection-x`);yInput=document.querySelector(`#depth-inspection-y`);image=null;data=null;normalized=null;overlay=document.createElement(`canvas`);max=0;gap=0;scale=0;constructor(e){this.canvas.addEventListener(`click`,e=>{let t=this.canvas.getBoundingClientRect();this.xInput.value=String(Math.min(this.canvas.width-1,Math.floor((e.clientX-t.left)/t.width*this.canvas.width))),this.yInput.value=String(Math.min(this.canvas.height-1,Math.floor((e.clientY-t.top)/t.height*this.canvas.height))),this.updatePoint()},{signal:e}),[this.xInput,this.yInput].forEach(t=>t.addEventListener(`input`,()=>this.updatePoint(),{signal:e}))}setDepth(e,t){let{data:n,width:r,height:i}=t.image;if(this.image=e instanceof HTMLImageElement?e:null,this.data=n&&r*i>1?n:null,this.normalized=t.userData.normalizedDepth??null,this.canvas.hidden=!this.image||!this.data,this.point.textContent=``,this.canvas.hidden||!this.data){this.summary.textContent=`사진과 깊이를 불러오세요.`;return}this.canvas.width=this.overlay.width=r,this.canvas.height=this.overlay.height=i,this.xInput.max=String(r-1),this.yInput.max=String(i-1);let a=this.overlay.getContext(`2d`),o=a.createImageData(r,i),s=0,c=0,l=0,u=0;this.max=0;for(let e=0;ethis.max&&(this.max=Number(this.data[e*4])/255,u=e);let d=-1/0;for(let e=0;ed&&(d=n,u=e),n===1&&(s+=1),t===1&&(c+=1),n>=Sh.nearThreshold&&(l+=1);let r=n===1?[255,55,180]:t===1?[0,240,255]:n>=Sh.nearThreshold?[255,210,40]:null;r&&o.data.set([...r,210],e*4)}a.putImageData(o,0,0);let f=e=>(100*e/(r*i)).toFixed(4);this.summary.textContent=`${r}×${i} · 최대 depth=${this.max.toFixed(5)}\n${this.normalized?`모델`:`입력`} 최대 1: ${s}px (${f(s)}%)\n8비트 depth=1: ${c}px (${f(c)}%)\ndepth≥${Sh.nearThreshold}: ${l}px (${f(l)}%)\n최대 위치: (${u%r}, ${Math.floor(u/r)})`,this.xInput.value=String(u%r),this.yInput.value=String(Math.floor(u/r)),this.updatePoint()}updateDistance(e,t){this.gap=e,this.scale=t,this.updatePoint()}updatePoint(){if(!this.data||!this.image)return;let e=Math.max(0,Math.min(this.canvas.width-1,Math.round(Number(this.xInput.value)))),t=Math.max(0,Math.min(this.canvas.height-1,Math.round(Number(this.yInput.value)))),n=t*this.canvas.width+e,r=Number(this.data[n*4])/255,i=this.gap+(this.max-r)*this.scale;this.point.textContent=`픽셀 (${e}, ${t})\n${this.normalized?`모델 상대 깊이: ${this.normalized[n].toFixed(6)}\n`:``}8비트 깊이: ${r.toFixed(6)}\n최대 표면 간격: ${this.gap.toFixed(4)}\n선택 지점 간격: ${i.toFixed(4)}\n뒤로 물러난 양: ${((this.max-r)*this.scale).toFixed(4)}`;let a=this.canvas.getContext(`2d`);a.drawImage(this.image,0,0,this.canvas.width,this.canvas.height),a.drawImage(this.overlay,0,0),a.strokeStyle=`#ffffff`,a.lineWidth=Math.max(1,this.canvas.width/250),a.beginPath(),a.arc(e+.5,t+.5,Math.max(3,this.canvas.width/50),0,Math.PI*2),a.stroke()}},jh=class{meshes;geometries;constructor(e){this.geometries=Array.from({length:4},(e,t)=>{let n=new Zi;return n.setAttribute(`position`,new Bi(new Float32Array(12),3)),n.setIndex([0,1,2,0,2,3]),n.setAttribute(`uv`,new Ui(t<2?[0,0,0,1,1,1,1,0]:[0,0,1,0,1,1,0,1],2)),n.computeVertexNormals(),n}),this.meshes=this.geometries.map(t=>new q(t,e))}update(e,t,n,r,i,a){let o=e*.5,s=t*.5,c=n*.5,l=r*.5,u=Math.min(e,t)*.002,d=i+u,f=Math.max(0,c-u),p=Math.max(0,l-u),m=[[[-o-u,-s-u,d],[-o-u,s+u,d],[-f,p,a],[-f,-p,a]],[[o+u,s+u,d],[o+u,-s-u,d],[f,-p,a],[f,p,a]],[[-o-u,s+u,d],[o+u,s+u,d],[f,p,a],[-f,p,a]],[[o+u,-s-u,d],[-o-u,-s-u,d],[-f,-p,a],[f,-p,a]]];for(let e=0;ee.dispose())}},Mh=class{group=new Lc;pocket=new Na(new W(1,0,0),1);material=new ud({color:10320214,roughness:.86,clippingPlanes:[this.pocket]});geometry=new da(1,1,1);vertical=new q(this.geometry,this.material);horizontal=new q(this.geometry,this.material);width=1;open=0;constructor(){this.group.name=`experimental-structural-door-grid`,this.group.add(this.vertical,this.horizontal),this.group.visible=!1}resize(e,t,n){this.width=e;let r=Math.min(e,t),i=.065*r;this.vertical.scale.set(i,t,.11*r),this.vertical.position.set(0,0,n+.038*r),this.horizontal.scale.set(e,i,.11*r),this.horizontal.position.set(0,.015*t,n+.038*r),this.pocket.constant=e/2+.05*r,this.setOpen(this.open)}setOpen(e){this.open=V.clamp(e,0,1),this.group.position.x=this.open===0?0:-this.width*this.open}dispose(){this.group.removeFromParent(),this.geometry.dispose(),this.material.dispose()}},Nh=.74;function Ph(e,t){let n=Om(e,Nh)*.82,r=Om(e,t)*.82,i=n*Nh*.8,a=n*.8,o=[r*t*.8,r*.8,.6];return{width:i,height:a,cameraBounds:o,clearanceScale:Math.min(i,a,...o.slice(0,2))}}function Fh(e,t,n,r,i,a,o){let s=e.height,c=e.width,l=Math.min(.48*s,.43*c/(Math.max(.01,n.width)*t/Math.max(.01,n.height)))*i,u=l/Math.max(.01,n.height),d=u*t,f=.24*c+a*.35*c,p=-.56*s+l+o*.35*s;return{x:f-(n.x+n.width/2-.5)*d,y:p-(.5-n.y)*u,z:r,width:d,height:u}}var Ih=`modulepreload`,Lh=function(e){return`/`+e},Rh={},zh=function(e){return e.pathname.endsWith(`.css`)},Bh=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e,i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)}r=o(t.map(t=>{t=Lh(t,n);let r=s(t);if(r.href in Rh)return;Rh[r.href]=!0;let i=zh(r);if(e===void 0){e={all:new Set,styles:new Set};let t=document.getElementsByTagName(`link`);for(let n=t.length-1;n>=0;n--){let r=t[n];e.all.add(r.href),r.rel===`stylesheet`&&e.styles.add(r.href)}}if((i?e.styles:e.all).has(r.href))return;let o=document.createElement(`link`);if(o.rel=i?`stylesheet`:Ih,i||(o.as=`script`),o.crossOrigin=``,o.href=r.href,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),i)return new Promise((e,t)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${r}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};function Vh(e,t,n){let r=e.querySelector(`#internal-controls`),i=e.querySelector(`#settings-dialog`),a=new AbortController,o={signal:a.signal},s=(t,n,r=``)=>{let i=e.createElement(t);return i.id=n,i.textContent=r,i},c=(e,t)=>{let n=s(`button`,e,t);return n.type=`button`,n},l=s(`section`,`peeking-experiment`);l.className=`peeking-experiment`,l.setAttribute(`aria-labelledby`,`peeking-title`);let u=s(`h3`,`peeking-title`,`마당에서 빼꼼`),d=s(`p`,`peeking-limitations`,`가벼운 누끼 실험이라 털이 잘리거나 배경이 남을 수 있어요. 사진 속 자세를 새로 만들지 않으며, 옆에서 보면 납작해 보일 수 있어요.`),f=s(`p`,`peeking-route-note`,`할머니집 + B에서 보여요. A·포토부스·비교에서는 잠시 원본 사진을 보여줘요.`),p=c(`peeking-choose`,`마당에서 빼꼼 · 실험`);p.setAttribute(`aria-describedby`,`peeking-limitations peeking-route-note`);let m=s(`input`,`peeking-photo`);m.type=`file`,m.accept=`image/*`,m.hidden=!0,m.setAttribute(`aria-label`,`마당 실험에 사용할 사진 선택`);let h=c(`peeking-toggle`,`원본 사진으로 돌아가기`);l.append(u,d,f,p,m,h),r.append(l);let g=s(`dialog`,`peeking-preview-dialog`);g.className=`peeking-preview-dialog`,g.setAttribute(`aria-labelledby`,`peeking-preview-title`),g.setAttribute(`aria-describedby`,`peeking-preview-note`);let _=s(`h2`,`peeking-preview-title`,`누끼를 먼저 확인해 주세요`),v=s(`p`,`peeking-preview-note`,`털·귀·발과 남은 배경을 확인해 주세요. 괜찮을 때만 마당에 배치해요.`),y=s(`p`,`peeking-progress`);y.setAttribute(`role`,`status`),y.setAttribute(`aria-live`,`polite`),y.setAttribute(`aria-atomic`,`true`);let b=s(`p`,`peeking-error`);b.setAttribute(`role`,`alert`);let x=s(`div`,`peeking-comparison`);x.className=`peeking-comparison`;let S=s(`img`,`peeking-original`);S.alt=`배경을 포함한 원본 사진`;let C=s(`img`,`peeking-cutout`);C.alt=`배경 제거 결과, 체크무늬는 투명한 부분`;for(let[e,t,n]of[[S,`원본 사진`,`original`],[C,`누끼 · 체크무늬는 투명`,`cutout`]]){let r=s(`figure`,`peeking-figure-${n}`),i=s(`div`,`peeking-surface-${n}`);i.className=`peeking-preview-surface`,i.append(e),r.append(i,s(`figcaption`,`peeking-caption-${n}`,t)),x.append(r)}let w=s(`p`,`peeking-warning`),T=s(`div`,`peeking-actions`);T.className=`peeking-actions`;let E=c(`peeking-accept`,`이 누끼로 배치`),D=c(`peeking-retry`,`다시 시도하기`),O=c(`peeking-another`,`다른 사진 선택`),k=c(`peeking-cancel`,`취소`);T.append(E,D,O,k),g.append(_,v,y,b,x,w,T),e.body.append(g);let A={available:!1,enabled:!1,busy:!1},j=null,M=null,N=!1,P=()=>{p.disabled=A.busy||N,h.hidden=!A.available,h.disabled=!A.available||A.busy||N,h.textContent=A.enabled?`원본 사진으로 돌아가기`:`마당 실험 다시 보기`,h.setAttribute(`aria-pressed`,String(A.enabled)),E.disabled=!j?.result||A.busy||N},F=()=>{S.removeAttribute(`src`),C.removeAttribute(`src`),x.hidden=!0,w.hidden=!0,w.textContent=``,b.hidden=!0,b.textContent=``,D.hidden=!0,g.setAttribute(`aria-busy`,`false`),P()},I=()=>{g.open&&g.close(),!N&&i.open&&p.isConnected&&!p.disabled&&p.focus({preventScroll:!0})},ee=()=>{let e=j;j=null,M=null,e?.controller.abort(),e?.result?.dispose(),e?.preparation?.dispose(),F(),y.textContent=``,I()},te=async e=>{if(N||A.busy||!i.open)return;ee(),M=e;let t={controller:new AbortController,preparation:null,result:null};j=t;let n=()=>!N&&j===t&&!t.controller.signal.aborted&&i.open;y.textContent=`누끼 미리보기를 준비하는 중…`,g.setAttribute(`aria-busy`,`true`),g.showModal(),k.focus({preventScroll:!0}),P();try{let{CutoutPreparation:r}=await Bh(async()=>{let{CutoutPreparation:e}=await import(`./CutoutPreparation-9rCu4swh.js`);return{CutoutPreparation:e}},[]);if(!n())return;t.preparation=new r;let i=await t.preparation.prepare(e,e=>{n()&&(y.textContent=e)},t.controller.signal);if(!n()){i.dispose(),t.preparation.dispose();return}t.result=i,S.src=i.originalUrl,C.src=i.cutoutUrl,x.hidden=!1;let a=[];i.warnings.includes(`multiple-foreground`)&&a.push(`여러 대상이 남아 있을 수 있어요.`),i.warnings.includes(`tiny-foreground`)&&a.push(`남은 대상이 아주 작아요. 다른 사진이 더 나을 수 있어요.`),w.textContent=a.join(` `),w.hidden=a.length===0,y.textContent=`결과를 확인한 뒤 직접 배치해 주세요.`,g.setAttribute(`aria-busy`,`false`),P()}catch(e){if(!n())return;t.preparation?.dispose(),t.preparation=null,b.textContent=e instanceof Error?e.message:`누끼를 준비하지 못했어요. 다시 시도하거나 다른 사진을 골라 주세요.`,b.hidden=!1,D.hidden=!1,y.textContent=`사진은 아직 바뀌지 않았어요.`,g.setAttribute(`aria-busy`,`false`),P()}},ne=()=>{N||A.busy||!i.open||(ee(),m.value=``,m.click())};p.addEventListener(`click`,ne,o),O.addEventListener(`click`,ne,o),m.addEventListener(`change`,()=>{let e=m.files?.[0];m.value=``,e&&te(e)},o),D.addEventListener(`click`,()=>{M&&te(M)},o),k.addEventListener(`click`,ee,o),g.addEventListener(`cancel`,e=>{e.preventDefault(),e.stopPropagation(),ee()},o),g.addEventListener(`close`,()=>{!g.open&&j&&ee()},o),i.addEventListener(`close`,()=>{i.open||ee()},o),E.addEventListener(`click`,()=>{if(N||A.busy||!j?.result||!j.preparation)return;let{result:e,preparation:t}=j;j=null,M=null;let r=!1,i={...e,dispose(){r||(r=!0,e.dispose(),t.dispose())}};F(),I(),n.onAccept(i)},o),h.addEventListener(`click`,()=>{!N&&A.available&&!A.busy&&n.onToggle(!A.enabled)},o);let re=()=>{N||(N=!0,ee(),a.abort(),t.removeEventListener(`abort`,re),l.remove(),g.remove())};return t.addEventListener(`abort`,re,{once:!0}),F(),t.aborted&&re(),{cancel:ee,dispose:re,setState(e){N||(A={...e},P())}}}var Hh=document.querySelector(`#canvas-wrap`),Uh=document.querySelector(`#status`),Wh=document.querySelector(`#depth-provenance`),Gh=document.querySelector(`#ai-depth`),Kh=document.querySelector(`#empty`),qh=document.querySelector(`#hint`);qh.dataset.phase=`hidden`;var X=new Jc({antialias:!0}),Jh=new Xf;X.localClippingEnabled=!0,X.setPixelRatio(Math.min(devicePixelRatio,1.5)),Hh.append(X.domElement);var Yh=new Yc,Xh=new Yc;Yh.background=new K(16249061);var Zh=new wa(40,1,.1,100);Zh.position.z=3;var Qh=new za(1,1),$h=document.createElement(`canvas`);$h.width=$h.height=512;var eg=$h.getContext(`2d`);function tg(e){let t=Sp[e],n=eg.createLinearGradient(0,0,512,512);t.room.forEach((e,t)=>n.addColorStop(t/2,e)),eg.fillStyle=n,eg.fillRect(0,0,512,512),eg.fillStyle=t.light,eg.fillRect(75,50,115,340),eg.fillStyle=t.mullion,eg.fillRect(320,0,28,512)}tg(`wood`);var ng=new Gl($h);ng.colorSpace=Xt;var rg=new Mi({map:ng}),ig=new q(Qh,rg);Yh.add(ig);var ag=Ch.flatTexture(),og=new Dh(ng,ag,.25,0),sg=og.material,cg=sg.uniforms;Yh.add(og);var Z={uSceneZoom:{value:1},uSceneOffset:{value:new H},uSceneTexture:{value:ng},uSceneDepth:{value:ng},uProtectionDepthMap:cg.uDepthMap,uPetWorldToLocal:{value:new G},uContentViewProjection:{value:new G},uContentInverseViewProjection:{value:new G},uContentCameraPosition:{value:new W},uLightPosition:{value:new W(.6,.8,2.6)},uBackgroundColor:{value:Yh.background.clone()},uGlassZ:{value:.6},uSourceZ:{value:.56},uGridSize:{value:tp.grid},uMosaicStyle:{value:2},uStrength:{value:1},uGlossStrength:{value:.3},uCurvature:{value:1},uRegionStrength:{value:0},uRegionAvailable:{value:0},uRegionAtlasSize:{value:new H(104,104)},uRegionGridSize:{value:new H(13,13)},uRegionPaletteSize:{value:new H(65,13)},uRegionPalette:{value:ng},uRegionAtlas:{value:ng},uViewOffset:{value:new H},uPaneRect:{value:new rr(0,0,1,1)},uResolution:{value:new H},uTime:{value:0},uPetSize:{value:new H(1,1)},uPaneSize:{value:new H(1,1)}},lg={value:ng},ug={value:new H(1,1)};Object.assign(Z,{uRegionHistory:lg,uDepthEvidenceRange:ug,uEnvironmentStrength:{value:$f},uGobangSurface:{value:new rr(tp.heightPerCell,tp.flatHalfWidth,tp.refractiveIndex,tp.thickness)},uGobangBevelRound:{value:tp.bevelRound},uGobangEnvironmentStrength:{value:tp.environmentStrength},uDepthCorrection:{value:new H(bh.blend,bh.maxCellCorrection)}});var dg=new da(1,1,1),fg=[new Mi({color:11837637}),new Mi({color:12824531}),new Mi({color:10323632}),new Mi({color:14272486}),new Mi({color:11178429}),new Mi({color:12626386})],pg=new q(dg,fg),mg=new q(dg,fg),hg=new q(dg,fg),gg=new q(dg,fg);Xh.add(pg,mg,hg,gg);var _g=new Mi({color:fg[1].color,side:2}),vg=new jh(_g);Xh.add(...vg.meshes);var yg=new Zm(Xh,[pg,mg,hg,gg],vg,fg,_g),bg=document.querySelector(`#frame-notice`),xg=document.querySelector(`#frame-retry`),Sg=document.querySelector(`#house-retry`),Cg=!1,wg=!1;function Tg(){bg.hidden=!Cg&&!wg,xg.hidden=!Cg,Sg.hidden=!wg,bg.textContent=[Cg?`나무 창틀을 불러오지 못해 임시 창틀을 보여드려요.`:``,wg?`집 주변 공간을 불러오지 못해 창문만 보여드려요.`:``,Cg||wg?`설정에서 다시 불러올 수 있어요.`:``].filter(Boolean).join(` `)}var Eg=new Fm(Xh,(e,t)=>{yg.setAssetActive(e),Cg=t===`error`,Tg(),Jh.invalidate()}),Dg=new Jm(Xh,e=>{wg=e===`error`,Tg(),Jh.invalidate()}),Og=Ym(og);Xh.add(Og.mesh);var kg=new pp,Ag=new Mh;Xh.add(Ag.group);var jg=null,Mg=null,Ng=null,Pg=!1,Fg=null,Ig=null,Lg=null;function Rg(){return!!(jg&&Ng&&Pg&&Eg.isWood&&p_===`b`&&!v_)}function zg(){return Rg()?Ng:Vg}function Bg(){Fg?.cancel(),Mg?.dispose(),Mg=null,Ng?.dispose(),Ng=null,jg?.dispose(),jg=null,Pg=!1,Fg?.setState({available:!1,enabled:!1,busy:a_||s_||c_})}var Vg=ng,Hg=!1,Ug=1,Wg=1,Gg=1,Kg=1,qg=0,Jg=0,Yg=V.lerp(ep.minGap,ep.maxGap,ep.defaultPercent/100),Xg=!1,Zg=!1,Qg=`noglass`,$g=new Kf,e_=null,t_=null,n_=!1,r_=0,i_=0,a_=!1,o_=!1,s_=!1,c_=!1,l_=!1,u_=null,d_=null,f_=new vp(X,og),p_=`b`,m_=`b`,h_=0,g_=!1,__=null,v_=!1,y_=0,b_=1,x_=null,S_=null,C_=0,w_=new Yf,T_=document.querySelector(`#comparison-toggle`),E_=document.querySelector(`#comparison-exit`),D_=document.querySelector(`#comparison-overlay`),O_=document.querySelector(`#comparison-state`),k_=document.querySelector(`#comparison-timing`),A_=document.querySelector(`#comparison-memory`),Q=new AbortController;xg.addEventListener(`click`,()=>{Eg.load()},{signal:Q.signal}),Sg.addEventListener(`click`,()=>{Dg.load()},{signal:Q.signal});var j_=!1,M_=new uh,N_=document.defaultView?.matchMedia?.(`(prefers-reduced-motion: reduce)`),P_=Af(()=>document.defaultView?.localStorage),F_=zf({visitorId:Pf({getStorage:()=>document.defaultView?.localStorage,randomUUID:()=>globalThis.crypto.randomUUID()}),makeDogId:(e,t)=>Ff(e,t,(e,t)=>globalThis.crypto.subtle.digest(e,t)),transport:Rf(),onCount:e=>Vf([...document.querySelectorAll(`[data-arrival-count]`)],e)}),I_=null,L_=null,R_=null;function z_(){F_?.invalidate(),R_=null}function B_(e){return!F_||!I_||e!==L_||c_||g_||l_?null:(R_===null&&(R_=F_.begin(I_.origin,I_.name)),R_)}Tf(document,Q.signal);var $=Cp(document,Q.signal,e=>{Yh.background.set(Sp[e].background),Z.uBackgroundColor.value.copy(Yh.background),M_.cancel(),yg.apply(e),Eg.apply(e),Dg.apply(e),tg(e),ng.needsUpdate=!0,u_?.invalidate(),j_&&ev()},()=>{nv(),Lg?.start()},e=>{nb(e)},P_,iv,e=>{Bv(),mv.hold(),kv.setPaused(e||$.isBlocked()),rv(),Jh.invalidate()});function V_(e,t=e){Uh.textContent=e,$.setDetail(t)}function H_(){return $.canAdjustPhoto()&&!l_&&!c_&&!g_&&!a_&&!s_&&!o_&&!Hg&&Vg!==ng&&p_===`b`&&Qg===`final`&&!v_&&!Rg()}function U_(){return $.canExportPhoto()&&!l_&&!c_&&!g_&&!a_&&!s_&&!o_&&!Hg&&Vg!==ng&&p_===`b`&&Qg===`final`&&!v_&&!Rg()}async function W_(e,t){if(!U_())throw Error(`사진 준비가 끝난 뒤 일반 화면에서 저장해 주세요.`);let n=r_,r=await Sf(X,document,e,t,t=>{f_.sync({width:Z.uPaneSize.value.x,height:Z.uPaneSize.value.y,grid:Z.uGridSize.value,curvature:Z.uCurvature.value},Z.uGlassZ.value,Z.uLightPosition.value,Yh.background),f_.syncReveal(vg.meshes,Xh),f_.syncCourtyard(null),f_.renderForExport(Zh,Xh,t,e===`photo`)});if(n!==r_||t.aborted||!U_())throw new DOMException(`Cancelled`,`AbortError`);return r}Ig=Cf(document,Q.signal,U_,W_,()=>$.refreshBlocking());var G_=new Ah(Q.signal);function K_(){Fg?.setState({available:!!jg,enabled:Pg,busy:a_||o_||s_||c_||l_}),ry.disabled=c_||Vg===ng||Hg||a_||o_||l_,Gh.disabled=c_||Vg===ng||Hg||a_||o_||s_||l_,Gh.textContent=s_?`사진 분석 중…`:`AI 입체감 만들기`}var q_=new wh(e=>{!l_&&s_&&V_(e)});function J_(){z_(),i_+=1,q_.cancel(),s_=!1,o_=!1,K_()}function Y_(){e_&&e_.dispose(),e_=null}var X_=0;function Z_(){return Z.uGlassZ.value-Yg-(X_-cg.uDepthBias.value)*cg.uDepthScale.value}function Q_(){Y_(),t_=null,Xg=!1,n_=!1}function $_(){Jh.invalidate(),cg.uUsePhotoAlpha.value=Rg(),cg.uTexture.value=zg(),Ag.group.visible=Rg(),kg.setEnabled(Rg()),Yh.background.copy(Rg()?kg.uniforms.uYardSkyColor.value:new K(Sp[Eg.isWood?`wood`:`booth`].background)),Z.uBackgroundColor.value.copy(Yh.background);let e=Z_(),t=(3-e)/3,n=Wg*(Kg-1)*.5*qg*t,r=Gg*(Kg-1)*.5*Jg*t;if(ig.scale.set(Wg*Kg*t,Gg*Kg*t,1),ig.position.set(n,r,e),og.scale.copy(ig.scale),og.position.copy(ig.position),Z.uSourceZ.value=e,vg.update(Z.uPaneSize.value.x,Z.uPaneSize.value.y,Wg*(3-e)/3,Gg*(3-e)/3,Z.uGlassZ.value,e),Rg()&&jg){let t=Ph(Zh.aspect,Ug),n=jg.bounds,r=Fh(t,Ug,{x:n.x0/jg.width,y:n.y0/jg.height,width:(n.x1-n.x0)/jg.width,height:(n.y1-n.y0)/jg.height},e,Kg,qg,Jg);og.position.set(r.x,r.y,r.z),og.scale.set(r.width,r.height,1);let i=r.y+(.5-n.y1/jg.height)*r.height,a=-t.height/2-.1*t.width;kg.setDogContact(r.x+(n.x0/jg.width+(n.x1-n.x0)/jg.width/2-.5)*r.width,e,.2*t.width*Kg,Math.max(0,1-Math.abs(i-a)/(.1*t.height))*.42),vg.update(t.width,t.height,t.width,t.height,Z.uGlassZ.value,Z.uGlassZ.value-.08*Math.min(t.width,t.height))}G_.updateDistance(Yg,cg.uDepthScale.value)}function ev(){Jh.invalidate(),Bv();let e=Hh.getBoundingClientRect();X.setSize(e.width,e.height,!1),x_=__?qf(e.width,e.height,b_).panes:null;let t=x_?x_[0]:e;x_&&(x_.forEach((t,n)=>{let r=document.querySelector(n===0?`#comparison-label-a`:`#comparison-label-b`);r.style.left=`${t.x+t.width/2}px`,r.style.top=`${t.y-32}px`,r.style.width=`${e.width<720?e.width-20:(e.width-36)/2}px`}),__.resize(Math.max(1,Math.floor(t.width*X.getPixelRatio())),Math.max(1,Math.floor(t.height*X.getPixelRatio())))),Zh.aspect=t.width/t.height,yv.updateProjection();let n=Rg()?.74:Ug,r=Om(t.width/t.height,n)*zm(Eg.isWood?`wood`:`booth`);Wg=r*n,Gg=r,$_(),Z.uPetSize.value.set(Wg,Gg),Z.uResolution.value.set(t.width,t.height);let i=4.8*Math.tan(V.degToRad(Zh.fov/2));Z.uPetSize.value.set(i*Zh.aspect,i),Z.uPaneSize.value.set(Wg*(3-Z.uGlassZ.value)/3,Gg*(3-Z.uGlassZ.value)/3),vg.update(Z.uPaneSize.value.x,Z.uPaneSize.value.y,Wg*(3-Z_())/3,Gg*(3-Z_())/3,Z.uGlassZ.value,Z_()),u_?.resize(Math.max(1,Math.floor(t.width*X.getPixelRatio())),Math.max(1,Math.floor(t.height*X.getPixelRatio())));let a=Z.uPaneSize.value.x,o=Z.uPaneSize.value.y,s=Math.min(a,o)*.052,c=s*1.5,l=Z.uGlassZ.value+c*.25;if(pg.position.set(-(a+s)*.5,0,l),mg.position.set((a+s)*.5,0,l),hg.position.set(0,(o+s)*.5,l),gg.position.set(0,-(o+s)*.5,l),pg.scale.set(s,o,c),mg.scale.set(s,o,c),hg.scale.set(a+s*2,s,c),gg.scale.set(a+s*2,s,c),yg.update(a,o,Z.uGlassZ.value,s,c),Eg.resize(a,o,Z.uGlassZ.value),Rg()){let e=Ph(Zh.aspect,Ug);Dg.resize(a,o,Z.uGlassZ.value,e.clearanceScale,{grid:Z.uGridSize.value,curvature:Z.uCurvature.value}),mv.setRoomBounds(a,o,Z.uGlassZ.value),kg.resize(a,o,Z.uGlassZ.value),Ag.resize(a,o,Z.uGlassZ.value),vg.update(a,o,a,o,Z.uGlassZ.value,Z.uGlassZ.value-.08*Math.min(a,o))}else Dg.resize(a,o,Z.uGlassZ.value,void 0,{grid:Z.uGridSize.value,curvature:Z.uCurvature.value}),mv.setRoomBounds(a,o,Z.uGlassZ.value,Eg.isWood);let u=6*Math.tan(V.degToRad(20)),d=u*Zh.aspect;Z.uPaneRect.value.set(Math.max(0,.5-Wg/(2*d)),Math.max(0,.5-Gg/(2*u)),Math.min(1,.5+Wg/(2*d)),Math.min(1,.5+Gg/(2*u)))}function tv(){rv()}function nv(){rv()}function rv(e){$g.interact(performance.now(),e),qh.dataset.phase=`hidden`}function iv(){r_+=1,pv.cancelPending(),J_(),I_=null,L_=null,Fg?.cancel(),Mg?.dispose(),Mg=null,Q_(),a_=!1,Bv(),kv.setPaused(!0),rv(),K_()}function av(e=`personal`,t=!0){z_(),I_=F_&&t?Object.freeze({origin:e,name:P_.name}):null,L_=null,I_&&(R_=F_.begin(I_.origin,I_.name)),$.setMediaOrigin(e),Bv(),$.setPhoto(``),$.setState(`loading`),V_(`사진을 읽고 있어요.`)}function ov(){$.stopPhotoAdjust(),Bv(),kv.disconnect(),mv.reset(),Z.uViewOffset.value.copy(mv.update(0,Zy)),Zh.updateMatrixWorld(!0),xv(1),Kg=1,qg=Jg=0,Vv(0),Jh.invalidate()}function sv(e,t,n){let r=Mg;Mg=null,Bg(),r&&!n?(jg=r,Ng=new nr(r.cutoutImage),Ng.colorSpace=Xt,Ng.needsUpdate=!0,Pg=!0,Kg=1,qg=Jg=0):r?.dispose(),Vg!==ng&&Vg.dispose(),Vg=e,Hg=!!n,a_=!1,Ug=t,L_=!n&&I_?e:null,n&&z_(),Xg=!1,n||ov(),$y(),e.colorSpace=Xt,cg.uTexture.value=zg(),rg.map=e,rg.needsUpdate=!0,$.setPhoto(e.image instanceof HTMLImageElement?e.image.src:``),Kh.style.display=`none`,ev(),K_()}function cv(e){Jh.invalidate(),cg.uDepthMap.value!==ag&&cg.uDepthMap.value.dispose(),cg.uDepthMap.value=e,e.colorSpace=``,ug.value.fromArray(Ch.evidenceRange(e));let t=e.image?.data;if(X_=0,t&&t.length>=4)for(let e=0;e{let r=Xg&&e_!==null,i=n_,a=!n&&!r;sv(e,t,n),og.setVideo(!!n),cv(e_??Ch.flatTexture()),e_=null,r&&t_?fv.setSample(t_):fv.clear(),t_=null,Zg=i,n_=!1,Wh.hidden=!(r||Zg),r?Wh.textContent=`수작업 테스트 Depth · AI 추정 아님`:Zg&&(Wh.textContent=`Depth 없음 · 평면 사진 테스트`),lv(`final`),a||($.setState(`ready`),nv()),iy&&(iy.textContent=`이 사진으로 해보기`),a&&eb(!0)},e=>{let t=a_&&!!e;a_=!1,K_(),(e||!s_)&&V_(e);let n=!!e&&!t&&Hg;uv.hidden=!n,e?(z_(),Mg?.dispose(),Mg=null,$.setState(`error`,!1,n),Q_(),iy&&(iy.textContent=`이 사진으로 해보기`)):Hg&&$.setState(`ready`)});uv.onclick=()=>pv.retry();var mv=new ph(Zh),hv;try{hv=window.localStorage}catch{}var gv=Uf(hv);mv.setCompositionMode(gv),Dg.setCompositionMode(gv);var _v=document.querySelector(`#camera-composition`),vv=document.querySelector(`#camera-composition-note`);_v.value=gv,_v.addEventListener(`change`,()=>{gv=_v.value===`legacy`?`legacy`:`wall`,mv.setCompositionMode(gv),Dg.setCompositionMode(gv);let e=Wf(hv,gv);vv.textContent=(gv===`legacy`?`기존의 넓은 방 구도로 돌아왔어요. `:`벽 옆에서 보는 실험 구도예요. `)+(e?`선택은 이 브라우저에 저장돼요.`:`선택을 저장하지 못했어요. 새로고침하면 이번 선택이 유지되지 않을 수 있어요.`),mv.update(0,Zy),Zh.updateMatrixWorld(!0),Jh.invalidate()},{signal:Q.signal});var yv=new fh(Zh),bv=document.querySelector(`#scene-zoom-reset`);function xv(e,t,n){yv.setZoom(e,t,n),Z.uSceneZoom.value=yv.value,Z.uSceneOffset.value.copy(yv.offset),bv.hidden=yv.value===1}bv.addEventListener(`click`,()=>{xv(1),rv()},{signal:Q.signal});var Sv=document.querySelector(`#gyro`),Cv=document.querySelector(`#gyro-label`),wv=document.querySelector(`#scene-motion`),Tv=wf(globalThis.navigator);Lg=Oe(document,Q.signal,Tv,()=>$.canShowFirstGuide(),()=>{$.refreshBlocking(),ey(performance.now()),Uv(),!Q.signal.aborted&&!$.isBlocked()&&Hh.focus({preventScroll:!0})});var Ev=document.querySelector(`#gyro-recenter`),Dv=document.querySelector(`#gyro-status`),Ov=document.querySelector(`#gyro-notice`),kv=new vh((e,t)=>mv.setView(e,t),(e,t)=>{let n=e===`active`||e===`paused`||e===`waiting`;Cv.textContent=e===`permission`?`권한 요청 취소`:e===`waiting`?`기울기 연결 중`:n?`기울기 켜짐`:`기울기 연결`,Sv.setAttribute(`aria-label`,n?`${Cv.textContent}, 끄기`:Cv.textContent),Sv.setAttribute(`aria-pressed`,String(n)),Sv.setAttribute(`aria-busy`,String(e===`permission`||e===`waiting`)),Ev.hidden=!Tv||e!==`active`&&e!==`paused`||$.isBlocked()&&!$.isGuideOpen()||$.isPhotoAdjusting(),Dv.textContent=t,Ov.textContent=e===`unavailable`?t:``,Ov.hidden=e!==`unavailable`||!Tv||$.isBlocked(),e===`unavailable`&&rv()},()=>({x:mv.target.x,y:mv.target.y}),()=>rv(`tilt`)),Av=null,jv=document.querySelector(`#door-handle`),Mv=document.querySelector(`#door-controls`),Nv=document.querySelector(`#door-toggle`),Pv=document.querySelector(`#door-notice`),Fv=new W,Iv=new vf,Lv=new Na(new W(0,0,1));function Rv(){return p_===`b`&&!v_&&Qg===`final`&&Eg.isWood&&Eg.isReady}function zv(){return Rv()&&Vg!==ng&&!$.isBlocked()&&!$.isPhotoAdjusting()&&!c_&&!g_&&!document.hidden}function Bv(){$v.cancelGesture(),M_.cancel()}function Vv(e){M_.set(e),Uv()}function Hv(e){M_.moveTo(e,performance.now(),!!N_?.matches),Uv()}function Uv(){let e=Rv(),t=zv(),n=M_.value,r=e?n:0;Ag.setOpen(r),Eg.setOpen(r),f_.setSlide(-Z.uPaneSize.value.x*r);let i=$.isGuideOpen()&&e&&Vg!==ng&&!c_&&!g_&&!document.hidden;Mv.hidden=!t&&!i,Nv.disabled=!t&&!i;let a=M_.target>.001;Nv.textContent=a?`문 닫기`:`문 열기`,Nv.setAttribute(`aria-label`,`문 ${Math.round(n*100)}% 열림. ${a?`닫기`:`열기`}. 방향키로 조금씩, Home으로 닫기, End로 열기`),Pv.textContent=v_?`A·B 비교는 닫힌 문으로 표시해요. 비교를 끝내면 열림 위치가 돌아와요.`:p_===`a`?`A 진단은 닫힌 문으로 표시해요. B로 돌아가면 열림 위치가 돌아와요.`:Qg===`final`?Eg.isWood?Eg.isReady?`손잡이만 드래그하면 문, 나머지 영역은 시점 이동이에요. 두 손가락은 항상 확대·축소해요.`:`나무 창틀을 불러온 뒤 손잡이를 밀어 열 수 있어요.`:`미닫이는 할머니집 창가 테마에서 사용할 수 있어요.`:`미닫이는 Final에서 사용할 수 있어요. 진단 화면은 닫힌 상태이며 열림 위치는 보존해요.`;let o=t?Eg.handlePosition(Fv):null;if(jv.hidden=!o,o){let e=X.domElement.getBoundingClientRect();o.project(Zh),jv.hidden=o.z<-1||o.z>1||Math.abs(o.x)>1||Math.abs(o.y)>1,jv.style.left=`${(o.x+1)*e.width/2}px`,jv.style.top=`${(1-o.y)*e.height/2}px`}}function Wv(e){let t=X.domElement.getBoundingClientRect();return!t.width||!t.height?null:(Iv.setFromCamera(new H((e.x-t.left)/t.width*2-1,1-(e.y-t.top)/t.height*2),Zh),Lv.constant=-Z.uGlassZ.value,Iv.ray.intersectPlane(Lv,Fv)?.x??null)}Nv.addEventListener(`click`,()=>{zv()&&($v.cancelGesture(),rv(M_.target>.001?`door-close`:`door-open`),Hv(M_.target>.001?0:1))},{signal:Q.signal}),Nv.addEventListener(`keydown`,e=>{if(!zv())return;let t=e.key===`Home`?0:e.key===`End`?1:e.key===`ArrowLeft`?M_.target+.1:e.key===`ArrowRight`?M_.target-.1:null;if(t===null)return;e.preventDefault(),$v.cancelGesture();let n=Math.max(0,Math.min(1,t));rv(n===M_.target?void 0:n1e-8?V.clamp(l/s,-1,1):0,Jg=c>1e-8?V.clamp(u/c,-1,1):0,$_(),$y()}function Zv(e,t,n=t){let r=Jv(t),i=Jv(n);r&&i&&Xv(e,r,i)}function Qv(e,t){Zv(Kg,{x:0,y:0},{x:e*2,y:t*2})}var $v=new lh(X.domElement,(e,t)=>{$.isBlocked()||($.isPhotoAdjusting()?Qv(e,t):(mv.add(e,t),kv.syncManualView()),rv(`drag`))},rv,{getZoom:()=>$.isPhotoAdjusting()?Kg:yv.value,setZoom:(e,t,n)=>{$.isPhotoAdjusting()?Zv(e,t,n):xv(e,t,n)},isEnabled:()=>!$.isBlocked(),getBounds:e=>{if(!x_)return X.domElement.getBoundingClientRect();let t=X.domElement.getBoundingClientRect(),n=S_??Jf(x_,e.x-t.left,e.y-t.top);return n?{left:t.left+n.x,top:t.top+n.y,width:n.width,height:n.height}:null},subjectDrag:{begin:e=>{if($.isPhotoAdjusting())return qv=Yv(e),!!qv;if(!zv())return!1;let t=Eg.handlePosition(Fv);if(!t)return!1;let n=X.domElement.getBoundingClientRect();t.project(Zh);let r=n.left+(t.x+1)*n.width/2,i=n.top+(1-t.y)*n.height/2;if(t.z<-1||t.z>1||Math.abs(e.x-r)>22||Math.abs(e.y-i)>22)return!1;mv.hold();let a=Wv(e);return a!==null&&(M_.cancel(),Av={startX:a,open:M_.value,screenX:e.x,screenY:e.y,moved:!1},!0)},move:e=>{if($.isPhotoAdjusting()){let t=Yv(e);t&&qv&&Xv(Kg,qv,t),qv=t;return}if(!Av||!zv())return;let t=Wv(e);if(t===null)return;Av.moved||=Math.hypot(e.x-Av.screenX,e.y-Av.screenY)>5;let n=M_.value;Vv(Av.open-(t-Av.startX)/Z.uPaneSize.value.x),Av.moved&&M_.value!==n&&rv(M_.value>n?`door-open`:`door-close`)},end:e=>{if(qv=null,$.isPhotoAdjusting()){Av=null;return}!e&&Av&&!Av.moved&&zv()&&(rv(Av.open>.001?`door-close`:`door-open`),Hv(Av.open>.001?0:1)),Av=null}},onGestureChange:(e,t)=>{e||(S_=null),t&&(mv.hold(),M_.cancel()),kv.setPaused(e||$.isBlocked()||$.isPhotoAdjusting())}});X.domElement.addEventListener(`pointerdown`,e=>{if(x_&&!S_){let t=X.domElement.getBoundingClientRect();S_=Jf(x_,e.clientX-t.left,e.clientY-t.top)}},{capture:!0,signal:Q.signal}),document.addEventListener(`visibilitychange`,()=>{Jh.invalidate(),document.hidden&&Bv()},{signal:Q.signal}),document.querySelector(`#settings-open`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),document.querySelector(`#scene-menu-open`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),document.querySelector(`#sample-home`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),document.querySelector(`#entry-samples`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),wv.addEventListener(`click`,()=>rv(),{signal:Q.signal});function ey(e){Ig?.setAvailable(U_());let t=$.isPhotoAdjusting(),n=H_();t&&!n&&$.stopPhotoAdjust(),document.querySelector(`#photo-adjust-open`).hidden=!n||t||$.isBlocked();let r=$.isBlocked()||$.isPhotoAdjusting()||c_||g_||document.hidden,i=$.isGuideOpen()&&!c_&&!g_&&!document.hidden;Ev.hidden=r&&!i||!Tv||kv.state!==`active`&&kv.state!==`paused`;let a=r&&!i||!Tv;wv.hidden!==a&&(wv.hidden=a),!r&&kv.state===`active`&&Lg?.recenter();let o=r||!Tv||kv.state!==`unavailable`;Ov.hidden!==o&&(Ov.hidden=o);let s=$g.update(e,{enabled:!r&&!$v.isInteracting&&!v_&&!M_.isAnimating,tiltActive:kv.state===`active`,sliding:zv(),doorOpen:M_.value,reducedMotion:!!N_?.matches}),c=s?.phase??`hidden`;s&&qh.textContent!==s.text&&(qh.textContent=s.text),qh.dataset.phase!==c&&(qh.dataset.phase=c)}var ty=document.querySelector(`#image`),ny=document.querySelector(`#video`),ry=document.querySelector(`#depth-image`),iy=document.querySelector(`#sample`),ay=document.querySelector(`#test-photo`),oy=document.querySelector(`#reference-strip`),sy=document.querySelector(`#reference-status`),cy=[document.querySelector(`#reference-image-1`),document.querySelector(`#reference-image-2`)];oy.hidden=!1;var ly=()=>{sy.hidden=!1};cy.forEach(e=>e.addEventListener(`error`,ly,{signal:Q.signal})),Promise.all([Bh(()=>import(`./reference1-BphJMCNh.js`),[]),Bh(()=>import(`./reference2-DHNjbprc.js`),[])]).then(([e,t])=>{l_||(cy[0].src=e.default,cy[1].src=t.default)}).catch(()=>{l_||ly()});var uy=document.querySelector(`#effect`),dy=document.querySelector(`#view-mode`),fy=document.querySelector(`#sensitivity`),py=document.querySelector(`#depth-scale`),my=document.querySelector(`#camera-offset`),hy=document.querySelector(`#grid-size`),gy=document.querySelector(`#gridOut`),_y=document.querySelector(`#mosaic-style`),vy=_y.closest(`label`),yy=document.querySelector(`#curvature-controls`),by=document.querySelector(`#region-fixed-note`),xy=document.querySelector(`#curvature`),Sy=document.querySelector(`#light-x`),Cy=document.querySelector(`#light-y`),wy=document.querySelector(`#lightXOut`),Ty=document.querySelector(`#lightYOut`),Ey=document.querySelector(`#cameraOut`),Dy=document.querySelector(`#photo-glass-distance`),Oy=document.querySelector(`#photoGlassDistanceOut`),ky=document.querySelector(`#sensitivityOut`),Ay=document.querySelector(`#depthOut`),jy=document.querySelector(`#photo-zoom`),My=document.querySelector(`#photoZoomOut`),Ny=document.querySelector(`#photo-pan-x`),Py=document.querySelector(`#photoPanXOut`),Fy=document.querySelector(`#photo-pan-y`),Iy=document.querySelector(`#photoPanYOut`),Ly=document.querySelector(`#photo-reset`),Ry=document.querySelector(`#reset`),zy=document.querySelector(`#glass-renderer`),By=document.querySelector(`#renderer-notice`),Vy=document.querySelector(`#mesh-render-error`);async function Hy(){return u_||(d_||=Bh(async()=>{let{createOriginalGlassRenderer:e}=await import(`./OriginalGlassRenderer-DLs_logl.js`);return{createOriginalGlassRenderer:e}},[]).then(({createOriginalGlassRenderer:e})=>{if(l_)throw Error(`Scene disposed`);return u_=e({renderer:X,scene:Yh,frameScene:Xh,camera:Zh,petDepth:og,uniforms:Z,depthUniforms:cg,emptyTex:ng,regionHistoryUniform:lg,state:()=>({mode:Qg,active:Vg,activeIsVideo:Hg,effect:uy.value,style:_y.value})}),u_.setEffect(uy.value),ev(),u_}).finally(()=>{d_=null}),d_)}function Uy(){p_===`b`&&m_===`b`&&!v_&&(u_?.dispose(),u_=null)}function Wy(){let e=p_===`a`;zy.value=p_,document.querySelector(`#pattern-cards`).hidden=uy.value!==`mosaic`,uy.disabled=!e,document.querySelectorAll(`[data-pattern]`).forEach(t=>{t.hidden=!e&&t.dataset.pattern!==`2`}),By.textContent=e?`A 진단 모드 · 기존 무늬와 화면 기반 굴절`:`기본 B · 실제 고방 메시 + 맞춤 굴절`+(f_.environmentOnly?` · 환경광만`:``),Qy()}async function Gy(e){Bv();let t=++h_;m_=e;try{if(e===`a`&&await Hy(),l_||c_||t!==h_){Uy();return}Bv(),p_=e,v_&&Yy(),e===`b`&&(uy.value=`mosaic`,_y.value=`2`,Z.uMosaicStyle.value=2,Z.uRegionStrength.value=0,Z.uStrength.value=1,u_?.setEffect(`mosaic`),document.querySelectorAll(`[data-pattern]`).forEach(e=>e.setAttribute(`aria-pressed`,String(e.dataset.pattern===`2`)))),Uy(),Wy(),ev(),g_&&(g_=!1,Vy.close(),$.setRenderLost(!1))}catch{t===h_&&(m_=p_),Uy(),zy.value=p_,By.textContent=`A 진단 렌더러를 불러오지 못했어요. 현재 화면을 유지해요.`}}function Ky(){c_||l_||g_||(z_(),g_=!0,Bv(),kv.setPaused(!0),$.setRenderLost(!0),v_&&Yy(`B 렌더링이 멈췄어요. 복구 방법을 선택해주세요.`),Vy.showModal())}Vy.addEventListener(`cancel`,e=>e.preventDefault(),{signal:Q.signal}),document.querySelector(`#mesh-retry`).addEventListener(`click`,()=>{c_||l_||(f_.dispose(),f_=new vp(X,og),Jh.invalidate(),g_=!1,Vy.close(),$.setRenderLost(!1),Wy())},{signal:Q.signal}),document.querySelector(`#mesh-use-a`).addEventListener(`click`,()=>{Gy(`a`)},{signal:Q.signal}),zy.addEventListener(`change`,()=>{Gy(zy.value===`a`?`a`:`b`)},{signal:Q.signal});function qy(e){if(p_===`a`){u_.render(e);return}if(Qg===`rgb`||Qg===`depth`){X.setRenderTarget(null),X.render(Yh,Zh);return}try{f_.sync({width:Z.uPaneSize.value.x,height:Z.uPaneSize.value.y,grid:Z.uGridSize.value,curvature:Z.uCurvature.value},Z.uGlassZ.value,Z.uLightPosition.value,Yh.background),f_.syncReveal(vg.meshes,Xh),f_.syncCourtyard(Rg()?kg:null),f_.render(Zh,Xh,Qg===`final`||Qg===`glass`,null,Qg!==`glass`)}catch{Ky()}}function Jy(){return uy.value===`mosaic`&&_y.value===`2`&&(Qg===`final`||Qg===`noglass`)}function Yy(e=`비교를 끝냈어요. 선택한 단독 렌더러로 돌아왔어요.`){y_+=1,v_=!1,Bv(),S_=null,__?.dispose(),__=null,x_=null,Uy(),X.info.autoReset=!0,D_.hidden=!0,E_.hidden=!0,T_.textContent=`비교 켜기 · 추가 렌더 비용`,T_.setAttribute(`aria-pressed`,`false`),O_.textContent=e,document.querySelector(`#experience`).removeAttribute(`data-comparison`),w_.reset(),c_||ev()}async function Xy(){if(v_){Yy();return}if(Vg===ng||s_||o_||a_){O_.textContent=`사진 준비가 끝난 뒤 비교를 켜주세요.`;return}if(c_||l_||!Jy()){O_.textContent=`고방유리와 Final 또는 No Glass를 선택한 뒤 비교를 켜주세요.`;return}Bv(),v_=!0;let e=++y_;T_.textContent=`비교 준비 취소`,O_.textContent=`굴절 보정 B를 준비하고 있어요.`;try{let{PhysicalGlassComparison:t}=await Bh(async()=>{let{PhysicalGlassComparison:e}=await import(`./PhysicalGlassComparison-B37yDBlH.js`);return{PhysicalGlassComparison:e}},[]);if(await Hy(),l_||c_||e!==y_||!v_){Uy();return}if(!Jy()){Yy(`고방유리 Final / No Glass에서 비교할 수 있어요.`);return}b_=Zh.aspect,__=new t(X,Yh.background),Bv(),rv(),X.info.autoReset=!1,w_.reset(),k_.textContent=`첫 프레임을 준비하는 중…`,A_.textContent=``,C_=0,D_.hidden=!1,E_.hidden=!1,T_.textContent=`비교 끝내기`,T_.setAttribute(`aria-pressed`,`true`),O_.textContent=`A 기존 코드 / 굴절 보정 B · 실제 메시 + 맞춤 굴절. 두 화면의 드래그·확대·거리·깊이를 공유해요.`,document.querySelector(`#comparison-label-b`).textContent=f_.environmentOnly?`굴절 보정 B · 맞춤 굴절 (환경광만)`:`굴절 보정 B · 맞춤 굴절`,document.querySelector(`#experience`).setAttribute(`data-comparison`,`true`),ev(),document.querySelector(`#settings-dialog`).close(),Hh.focus({preventScroll:!0})}catch{Yy(`비교 렌더러를 준비하지 못했어요. 단독 화면을 유지해요.`)}}T_.addEventListener(`click`,()=>{Xy()},{signal:Q.signal}),E_.addEventListener(`click`,()=>{Yy(),Hh.focus({preventScroll:!0})},{signal:Q.signal});for(let e of[uy,_y,dy])e?.addEventListener(`change`,()=>{queueMicrotask(()=>{v_&&!Jy()&&Yy(`다른 무늬·진단 화면을 선택해 비교를 끝냈어요.`)})},{signal:Q.signal});var Zy=1;function Qy(){let e=uy.value===`mosaic`;vy&&(vy.style.display=e?`grid`:`none`),_y.disabled=!e,yy&&(yy.hidden=!e,yy.style.display=e?`grid`:`none`),by&&(by.hidden=!e,by.textContent=_y.value===`2`?`고방유리 · 표면 요철에 따른 굴절 · 색면 처리 없음`:_y.value===`0`?`Ref1 옵션 2 · 색면 단순화 1 · 굴절 1 (고정)`:`기존 촘촘 유리 · 굴절 1 (고정)`),[Sy,Cy,xy].forEach(t=>{t&&(t.disabled=!e)})}function $y(){jy&&(jy.value=Kg.toFixed(2)),My&&(My.value=Kg.toFixed(2)),document.querySelector(`#photo-adjust-zoom`).value=Kg.toFixed(2),document.querySelector(`#photo-adjust-value`).value=Kg.toFixed(2),document.querySelector(`#photo-adjust-help`).textContent=Kg<=1.001?`사진을 확대한 뒤 드래그해서 위치를 맞춰주세요`:`드래그·방향키로 이동 · 두 손가락·휠로 확대`,Ny&&(Ny.value=qg.toFixed(2)),Py&&(Py.value=qg.toFixed(2)),Fy&&(Fy.value=Jg.toFixed(2)),Iy&&(Iy.value=Jg.toFixed(2))}async function eb(e=!1){if(Gh.disabled||!(Vg.image instanceof HTMLImageElement))return;let t=Vg,n=B_(t),r=Vg.image,i=++i_;s_=!0,Bv(),$.startJourney(),V_(`출발 준비 중이에요. 처음에는 조금 더 걸릴 수 있어요.`),K_();try{let a=await q_.getDepthMap(r);if(l_||i!==i_||Vg!==t||Hg){a.dispose();return}cv(a),fv.clear(),Zg=!1,Wh.hidden=!1,Wh.textContent=`AI 추정 · Depth Anything V2 ${xh.modelName} · 입력 ${xh.inputSize} (상대 깊이, 0=뒤 · 1=앞)`,lv(`final`),!c_&&!g_&&n!==null&&n===R_&&F_?.arrived(n),$.setState(`ready`),V_(e?`입체감 준비 완료! 사진을 살짝 움직여보세요.`:`새 입체감을 적용했어요. 사진을 움직여 확인해보세요.`),nv()}catch(e){!l_&&i===i_&&(z_(),$.setState(`error`,!0),V_(`사진 분석 실패: ${e instanceof Error?e.message:`알 수 없는 오류`}. 다시 시도하거나 평면 사진으로 볼 수 있어요.`,`사진을 준비하지 못했어요. 다시 시도하거나 다른 사진을 골라 주세요. 평면 사진으로 볼 수도 있어요.`))}finally{i===i_&&(s_=!1,K_())}}Gh.addEventListener(`click`,()=>{eb()},{signal:Q.signal}),Fg=Vh(document,Q.signal,{onAccept(e){if(c_||l_){e.dispose();return}tv(),r_+=1,J_(),pv.cancelPending(),Q_(),Mg?.dispose(),Mg=e,a_=!0,av(),K_(),pv.load(new File([e.originalBlob],`peeking-original.png`,{type:`image/png`}))},onToggle(e){!jg||a_||s_||c_||(Bv(),Pg=e,Kg=1,qg=Jg=0,$y(),ev(),lv(Qg),u_?.invalidate(),Fg?.setState({available:!0,enabled:e,busy:!1}))}});function tb(e){return c_||l_||!e.type.startsWith(`image/`)?!1:(Fg?.cancel(),Mg?.dispose(),Mg=null,tv(),r_+=1,J_(),av(),a_=!0,K_(),Q_(),pv.load(e),!0)}ty.onchange=e=>{let t=e.target,n=t.files?.[0];n&&tb(n),t.value=``},Ef(document,Q.signal,()=>!l_&&!c_&&!g_&&$.canAcceptPhotoPaste(),tb),ny.onchange=e=>{let t=e.target,n=t.files?.[0];n&&!c_&&(Fg?.cancel(),Mg?.dispose(),Mg=null,tv(),r_+=1,J_(),av(`personal`,!1),a_=!0,K_(),Q_(),pv.load(n)),t.value=``},document.querySelector(`#photo-adjust-open`).addEventListener(`click`,()=>{H_()&&!$.isBlocked()&&($.startPhotoAdjust(),$y())},{signal:Q.signal}),document.querySelector(`#photo-adjust-zoom`).addEventListener(`input`,e=>{$.isPhotoAdjusting()&&H_()&&(Kg=V.clamp(Number(e.target.value)||1,1,3),$_(),$y())},{signal:Q.signal}),document.querySelector(`#photo-adjust-reset`).addEventListener(`click`,()=>{$.isPhotoAdjusting()&&H_()&&(Kg=1,qg=Jg=0,$_(),$y())},{signal:Q.signal}),jy?.addEventListener(`input`,e=>{Kg=Number(e.target.value),$_(),$y()},{signal:Q.signal}),Ny?.addEventListener(`input`,e=>{qg=Number(e.target.value),$_(),$y()},{signal:Q.signal}),Fy?.addEventListener(`input`,e=>{Jg=Number(e.target.value),$_(),$y()},{signal:Q.signal}),Ly?.addEventListener(`click`,()=>{Kg=1,qg=0,Jg=0,$_(),$y()},{signal:Q.signal});async function nb(e){if(c_||l_||![`dog1`,`dog2`,`dog3`,`dog4`,`dog5`].includes(e))return;tv(),ay.value=e,$.setSampleName?.({dog1:`호두`,dog2:`두부`,dog3:`보리`,dog4:`콩이`,dog5:`누렁이`}[e]),Fg?.cancel(),Mg?.dispose(),Mg=null;let t=++r_,n=`/assets/samples/${e}.jpg`;J_(),a_=!0,av(`sample`),K_(),pv.cancelPending(),Q_(),iy&&(iy.textContent=`사진을 불러오는 중…`),V_(``);try{let e=await fetch(n);if(!e.ok)throw Error(`image`);let r=await e.blob();if(l_||t!==r_)return;n_=!0,pv.load(new File([r],n.split(`/`).pop()??`test-photo`,{type:e.headers.get(`content-type`)??`image/jpeg`}))}catch{!l_&&t===r_&&(z_(),a_=!1,K_(),$.setState(`error`),Q_(),V_(`샘플 사진을 읽지 못했습니다. 다른 사진을 고르거나 다시 시도해 주세요.`),iy&&(iy.textContent=`이 사진으로 해보기`))}}iy?.addEventListener(`click`,()=>{nb(ay.value)},{signal:Q.signal}),uy.addEventListener(`change`,e=>{u_?.setEffect(e.target.value),Qy()},{signal:Q.signal}),dy?.addEventListener(`change`,e=>lv(e.target.value),{signal:Q.signal}),fy.oninput=e=>{let t=Number(e.target.value);Zy=t,ky.value=t.toFixed(2)},py?.addEventListener(`input`,e=>{let t=Math.min(Number(e.target.value),.4);cg.uDepthScale.value=t,$_(),u_?.invalidate(),Ay&&(Ay.value=t.toFixed(2))},{signal:Q.signal}),my.addEventListener(`input`,e=>{let t=Number(e.target.value);mv.setMaxOffset(t),Ey.value=t.toFixed(2)},{signal:Q.signal}),Dy.addEventListener(`input`,e=>{let t=Number(e.target.value);Yg=V.lerp(ep.minGap,ep.maxGap,t/100),$_(),Oy.value=`${t.toFixed(0)}%`},{signal:Q.signal}),hy.addEventListener(`input`,e=>{let t=Number(e.target.value);Z.uGridSize.value=t,gy.value=t.toFixed(0),ev()},{signal:Q.signal}),_y.addEventListener(`change`,e=>{if(uy.value!==`mosaic`)return;let t=Number(e.target.value);Z.uMosaicStyle.value=t,Z.uGridSize.value=t===0?13:t===2?tp.grid:24,Z.uRegionStrength.value=+(t===0),Z.uStrength.value=1,hy.value=String(Z.uGridSize.value),gy.value=String(Z.uGridSize.value),ev(),Qy()},{signal:Q.signal}),xy?.addEventListener(`change`,e=>{Z.uCurvature.value=e.target.value===`-1`?-1:1},{signal:Q.signal}),Sy?.addEventListener(`input`,e=>{let t=Number(e.target.value);Z.uLightPosition.value.x=t,wy&&(wy.value=t.toFixed(2))},{signal:Q.signal}),Cy?.addEventListener(`input`,e=>{let t=Number(e.target.value);Z.uLightPosition.value.y=t,Ty&&(Ty.value=t.toFixed(2))},{signal:Q.signal}),ry?.addEventListener(`change`,async()=>{if(c_){ry.value=``;return}let e=ry.files?.[0];if(!e||Vg===ng||Hg||a_)return;J_();let t=i_;o_=!0,Bv(),$.setState(`loading`),V_(`깊이 이미지를 읽고 있어요.`),K_(),fv.clear();let n=URL.createObjectURL(e),r=null;try{let e=new Image;if(e.src=n,await e.decode(),l_||t!==i_)return;if(Ug>0&&Math.abs(e.width/e.height-Ug)>.02)throw Error(`aspect`);if(r=Ch.toTexture(e),l_||t!==i_){r.dispose(),r=null;return}cv(r),r=null,Wh.hidden=!1,Wh.textContent=`직접 올린 깊이 이미지 · AI 추정 아님 (0=뒤, 1=앞)`,V_(`직접 올린 깊이 이미지를 적용했어요.`),$.setState(`ready`),nv()}catch{!l_&&t===i_&&(V_(`깊이 이미지를 읽지 못했거나 사진과 종횡비가 다릅니다.`),$.setState(`error`,Vg!==ng&&!Hg))}finally{r?.dispose(),URL.revokeObjectURL(n),t===i_&&(ry.value=``,o_=!1,K_())}},{signal:Q.signal}),Ry.onclick=()=>{mv.reset(),kv.reset(),xv(1)},Sv.onclick=()=>{Tv&&!$.isBlocked()&&!$.isPhotoAdjusting()&&kv.toggle()},Ev.addEventListener(`click`,()=>{$.isBlocked()||$.isPhotoAdjusting()||(mv.reset(),kv.reset())},{signal:Q.signal}),document.querySelector(`#scene-guide-replay`).addEventListener(`click`,()=>Lg?.start(!0),{signal:Q.signal}),document.querySelector(`#guide-replay`).addEventListener(`click`,()=>{let e=document.querySelector(`#settings-dialog`);e.open&&(e.addEventListener(`close`,()=>Lg?.start(!0),{once:!0,signal:Q.signal}),e.close())},{signal:Q.signal}),Hh.addEventListener(`keydown`,e=>{if($.isBlocked())return;let t=e.key===`ArrowLeft`?[-.06,0]:e.key===`ArrowRight`?[.06,0]:e.key===`ArrowUp`?[0,.06]:e.key===`ArrowDown`?[0,-.06]:null;t&&(e.preventDefault(),$.isPhotoAdjusting()?Qv(t[0],t[1]):(mv.add(t[0],t[1]),kv.syncManualView()),rv(`drag`))},{signal:Q.signal}),document.querySelectorAll(`[data-pick-photo]`).forEach(e=>e.addEventListener(`click`,()=>ty.click(),{signal:Q.signal})),document.querySelector(`#flow-retry`).addEventListener(`click`,()=>{Hg?pv.retry():eb()},{signal:Q.signal}),document.querySelector(`#flow-flat`).addEventListener(`click`,()=>{Vg!==ng&&(z_(),cv(Ch.flatTexture()),lv(`final`),Wh.hidden=!1,Wh.textContent=`입체감 없는 평면 사진 · AI 추정 아님`,$.setState(`ready`),nv())},{signal:Q.signal}),bp(document,Q.signal);var rb=new wp(X.domElement,document.querySelector(`#render-recovery`),document.querySelector(`#render-reload`),()=>{c_=!0,h_+=1,m_=p_,Vy.open&&Vy.close(),v_&&Yy(`그래픽 연결이 끊겨 비교를 종료했어요. 복구 후 선택한 단독 렌더러로 돌아가요.`);let e=s_||o_||a_;$.setRenderLost(!0),Bv(),kv.setPaused(!0),rv(),Fg?.cancel(),Mg?.dispose(),Mg=null,r_+=1,pv.cancelPending(!0),a_=!1,ry.value=``,J_(),Q_(),e&&($.setState(`error`,Vg!==ng&&!Hg),V_(`그래픽 연결이 끊겨 사진 준비를 멈췄어요. 화면이 복구되면 다시 시도하거나 평면 사진으로 볼 수 있어요.`))},()=>{u_?.invalidate(),f_.restore(),ev(),c_=!1,g_=!1,$.setRenderLost(!1),K_()},()=>window.location.reload()),ib=new ResizeObserver(ev);ib.observe(Hh),ev(),lv(`final`),Qy(),K_(),Wy(),Eg.load(),j_=!0,Dg.load(),F_?.start();var ab=performance.now(),ob=0;function sb(){let e=new Set([`uTime`,`uSceneTexture`,`uSceneDepth`,`uRegionPalette`,`uRegionAtlas`,`uRegionHistory`]),t=Object.entries({...Z,...cg}).filter(([t])=>!e.has(t)).map(([e,t])=>{let n=t.value;if(n instanceof nr){let t=n===Vg&&Hg?n.image:null,r=t&&typeof t.requestVideoFrameCallback!=`function`?t.currentTime:n.version;return`${e}:${n.uuid}:${r}`}return n&&typeof n.toArray==`function`?`${e}:${n.toArray().join(`,`)}`:`${e}:${n}`});return[p_,Qg,__?`comparison`:`single`,uy.value,_y.value,X.domElement.width,X.domElement.height,Eg.isReady,Dg.isReady,Eg.isWood,...Zh.matrixWorld.elements,...Zh.projectionMatrix.elements,...og.matrixWorld.elements,M_.value,...t].join(`|`)}function cb(e){let t=Math.min((e-ab)/1e3,.1);if(ab=e,kv.setPaused($.isBlocked()||$.isPhotoAdjusting()||$v.isInteracting),ey(e),M_.update(e,zv(),!!N_?.matches),Uv(),c_||s_||document.hidden){Jh.invalidate(),w_.reset(),ob=requestAnimationFrame(cb);return}if(g_){Jh.invalidate(),ob=requestAnimationFrame(cb);return}!$.isBlocked()&&!$.isPhotoAdjusting()&&Z.uViewOffset.value.copy(mv.update(t,Zy)),Zh.updateMatrixWorld(!0),og.updateMatrixWorld(!0),Uv(),Og.sync(Dg.isReady&&Eg.isWood&&(Qg===`final`||Qg===`noglass`&&cg.uUsePhotoAlpha?.value)&&Vg!==ng),Z.uPetWorldToLocal.value.copy(og.matrixWorld).invert(),Z.uContentViewProjection.value.multiplyMatrices(Zh.projectionMatrix,Zh.matrixWorldInverse),Z.uContentInverseViewProjection.value.copy(Z.uContentViewProjection.value).invert(),Z.uContentCameraPosition.value.copy(Zh.position),Z.uTime.value=e/1e3;let n=fv.update(Zh,og,cg.uDepthScale.value,cg.uDepthBias.value,Hh.clientWidth,Z.uSourceZ.value,X_);dv.textContent=n,dv.hidden=!n;let r=(p_===`a`||!!__)&&(Qg===`final`||Qg===`glass`)&&uy.value===`mosaic`&&_y.value===`0`&&Z.uRegionAvailable.value>.5&&Z.uRegionStrength.value>.001&&Z.uStrength.value>.001;if(!Jh.shouldRender(t,{signature:sb(),continuous:M_.isAnimating,temporal:r})){w_.reset(),__&&(k_.textContent=`정지 화면 · 추가 렌더링 대기 중`),ob=requestAnimationFrame(cb);return}if(__&&x_){X.info.reset();let n=performance.now();u_.render(t,__.targetA),w_.record(`a`,performance.now()-n,X.info.render);let r=X.info.render.calls,i=X.info.render.triangles;n=performance.now();try{if(f_.sync({width:Z.uPaneSize.value.x,height:Z.uPaneSize.value.y,grid:Z.uGridSize.value,curvature:Z.uCurvature.value},Z.uGlassZ.value,Z.uLightPosition.value,Yh.background),f_.syncReveal(vg.meshes,Xh),f_.syncCourtyard(Rg()?kg:null),f_.render(Zh,Xh,Qg===`final`,__.targetB),w_.record(`b`,performance.now()-n,{calls:X.info.render.calls-r,triangles:X.info.render.triangles-i}),__.composite(x_,Hh.clientHeight),w_.frame(e),e-C_>500){C_=e;let t=w_.snapshot();k_.textContent=`CPU 제출 A ${t.a.cpuMs.toFixed(2)}ms · B ${t.b.cpuMs.toFixed(2)}ms\n화면 간격 ${t.frameMs?.toFixed(1)??`—`}ms (A+B 동시)\nDraw A ${t.a.calls} · B ${t.b.calls} / Tri A ${t.a.triangles.toLocaleString()} · B ${t.b.triangles.toLocaleString()}`;let n=performance.memory?.usedJSHeapSize;A_.textContent=`GL 형상 ${X.info.memory.geometries} · 텍스처 ${X.info.memory.textures} / B CPU ${(f_.geometryBytes/1048576).toFixed(2)}MiB\n${Number.isFinite(n)?`JS heap 약 ${(n/1048576).toFixed(1)}MiB (페이지·비표준)`:`JS heap API 미지원`}${f_.reducedSampling?` · B 세분화 축소`:``}`}}catch{Ky()}}else qy(t);ob=requestAnimationFrame(cb)}ob=requestAnimationFrame(cb);function lb(){F_?.dispose(),Bg(),Fg?.dispose(),kg.dispose(),Ag.dispose(),M_.cancel(),h_+=1,y_+=1,v_=!1,__?.dispose(),__=null,l_=!0,r_+=1,i_+=1,q_.cancel(),Gh.disabled=!0,Y_(),Q.abort(),rb.dispose(),cancelAnimationFrame(ob),ib.disconnect(),ty.onchange=null,ny.onchange=null,uy.onchange=null,fy.oninput=null,Ry.onclick=null,Sv.onclick=null,uv.onclick=null,$v.dispose(),kv.dispose(),pv.dispose(),u_?.dispose(),f_.dispose(),Eg.dispose(),Dg.dispose(),Og.dispose(),yg.dispose(),vg.dispose(),_g.dispose(),fg.forEach(e=>e.dispose()),Vg!==ng&&Vg.dispose(),cg.uDepthMap.value!==ag&&cg.uDepthMap.value.dispose(),ag.dispose(),og.geometry.dispose(),sg.dispose(),Qh.dispose(),rg.dispose(),dg.dispose(),ng.dispose(),X.domElement.remove(),X.dispose(),qh.dataset.phase=`hidden`,uv.remove(),dv.remove()}import.meta.hot?.dispose(lb);export{Ke as a,Ne as c,Yc as d,ya as f,ar as h,To as i,Xa as l,We as m,K as n,q as o,ze as p,nt as r,Mi as s,ih as t,za as u}; \ No newline at end of file +`)}sampleBilinear(e,t){if(!this.values||this.width<1||this.height<1)return 0;let n=V.clamp(e,0,this.width-1),r=V.clamp(t,0,this.height-1),i=Math.floor(n),a=Math.floor(r),o=Math.min(i+1,this.width-1),s=Math.min(a+1,this.height-1),c=n-i,l=r-a,u=this.gray(i,a),d=this.gray(o,a),f=this.gray(i,s),p=this.gray(o,s);return V.lerp(V.lerp(u,d,c),V.lerp(f,p,c),l)}gray(e,t){return this.values[(t*this.width+e)*4]/255}},Ah=class{canvas=document.querySelector(`#depth-inspection-canvas`);summary=document.querySelector(`#depth-inspection-summary`);point=document.querySelector(`#depth-inspection-point`);xInput=document.querySelector(`#depth-inspection-x`);yInput=document.querySelector(`#depth-inspection-y`);image=null;data=null;normalized=null;overlay=document.createElement(`canvas`);max=0;gap=0;scale=0;constructor(e){this.canvas.addEventListener(`click`,e=>{let t=this.canvas.getBoundingClientRect();this.xInput.value=String(Math.min(this.canvas.width-1,Math.floor((e.clientX-t.left)/t.width*this.canvas.width))),this.yInput.value=String(Math.min(this.canvas.height-1,Math.floor((e.clientY-t.top)/t.height*this.canvas.height))),this.updatePoint()},{signal:e}),[this.xInput,this.yInput].forEach(t=>t.addEventListener(`input`,()=>this.updatePoint(),{signal:e}))}setDepth(e,t){let{data:n,width:r,height:i}=t.image;if(this.image=e instanceof HTMLImageElement?e:null,this.data=n&&r*i>1?n:null,this.normalized=t.userData.normalizedDepth??null,this.canvas.hidden=!this.image||!this.data,this.point.textContent=``,this.canvas.hidden||!this.data){this.summary.textContent=`사진과 깊이를 불러오세요.`;return}this.canvas.width=this.overlay.width=r,this.canvas.height=this.overlay.height=i,this.xInput.max=String(r-1),this.yInput.max=String(i-1);let a=this.overlay.getContext(`2d`),o=a.createImageData(r,i),s=0,c=0,l=0,u=0;this.max=0;for(let e=0;ethis.max&&(this.max=Number(this.data[e*4])/255,u=e);let d=-1/0;for(let e=0;ed&&(d=n,u=e),n===1&&(s+=1),t===1&&(c+=1),n>=Sh.nearThreshold&&(l+=1);let r=n===1?[255,55,180]:t===1?[0,240,255]:n>=Sh.nearThreshold?[255,210,40]:null;r&&o.data.set([...r,210],e*4)}a.putImageData(o,0,0);let f=e=>(100*e/(r*i)).toFixed(4);this.summary.textContent=`${r}×${i} · 최대 depth=${this.max.toFixed(5)}\n${this.normalized?`모델`:`입력`} 최대 1: ${s}px (${f(s)}%)\n8비트 depth=1: ${c}px (${f(c)}%)\ndepth≥${Sh.nearThreshold}: ${l}px (${f(l)}%)\n최대 위치: (${u%r}, ${Math.floor(u/r)})`,this.xInput.value=String(u%r),this.yInput.value=String(Math.floor(u/r)),this.updatePoint()}updateDistance(e,t){this.gap=e,this.scale=t,this.updatePoint()}updatePoint(){if(!this.data||!this.image)return;let e=Math.max(0,Math.min(this.canvas.width-1,Math.round(Number(this.xInput.value)))),t=Math.max(0,Math.min(this.canvas.height-1,Math.round(Number(this.yInput.value)))),n=t*this.canvas.width+e,r=Number(this.data[n*4])/255,i=this.gap+(this.max-r)*this.scale;this.point.textContent=`픽셀 (${e}, ${t})\n${this.normalized?`모델 상대 깊이: ${this.normalized[n].toFixed(6)}\n`:``}8비트 깊이: ${r.toFixed(6)}\n최대 표면 간격: ${this.gap.toFixed(4)}\n선택 지점 간격: ${i.toFixed(4)}\n뒤로 물러난 양: ${((this.max-r)*this.scale).toFixed(4)}`;let a=this.canvas.getContext(`2d`);a.drawImage(this.image,0,0,this.canvas.width,this.canvas.height),a.drawImage(this.overlay,0,0),a.strokeStyle=`#ffffff`,a.lineWidth=Math.max(1,this.canvas.width/250),a.beginPath(),a.arc(e+.5,t+.5,Math.max(3,this.canvas.width/50),0,Math.PI*2),a.stroke()}},jh=class{meshes;geometries;constructor(e){this.geometries=Array.from({length:4},(e,t)=>{let n=new Zi;return n.setAttribute(`position`,new Bi(new Float32Array(12),3)),n.setIndex([0,1,2,0,2,3]),n.setAttribute(`uv`,new Ui(t<2?[0,0,0,1,1,1,1,0]:[0,0,1,0,1,1,0,1],2)),n.computeVertexNormals(),n}),this.meshes=this.geometries.map(t=>new q(t,e))}update(e,t,n,r,i,a){let o=e*.5,s=t*.5,c=n*.5,l=r*.5,u=Math.min(e,t)*.002,d=i+u,f=Math.max(0,c-u),p=Math.max(0,l-u),m=[[[-o-u,-s-u,d],[-o-u,s+u,d],[-f,p,a],[-f,-p,a]],[[o+u,s+u,d],[o+u,-s-u,d],[f,-p,a],[f,p,a]],[[-o-u,s+u,d],[o+u,s+u,d],[f,p,a],[-f,p,a]],[[o+u,-s-u,d],[-o-u,-s-u,d],[-f,-p,a],[f,-p,a]]];for(let e=0;ee.dispose())}},Mh=class{group=new Lc;pocket=new Na(new W(1,0,0),1);material=new ud({color:10320214,roughness:.86,clippingPlanes:[this.pocket]});geometry=new da(1,1,1);vertical=new q(this.geometry,this.material);horizontal=new q(this.geometry,this.material);width=1;open=0;constructor(){this.group.name=`experimental-structural-door-grid`,this.group.add(this.vertical,this.horizontal),this.group.visible=!1}resize(e,t,n){this.width=e;let r=Math.min(e,t),i=.065*r;this.vertical.scale.set(i,t,.11*r),this.vertical.position.set(0,0,n+.038*r),this.horizontal.scale.set(e,i,.11*r),this.horizontal.position.set(0,.015*t,n+.038*r),this.pocket.constant=e/2+.05*r,this.setOpen(this.open)}setOpen(e){this.open=V.clamp(e,0,1),this.group.position.x=this.open===0?0:-this.width*this.open}dispose(){this.group.removeFromParent(),this.geometry.dispose(),this.material.dispose()}},Nh=.74;function Ph(e,t){let n=Om(e,Nh)*.82,r=Om(e,t)*.82,i=n*Nh*.8,a=n*.8,o=[r*t*.8,r*.8,.6];return{width:i,height:a,cameraBounds:o,clearanceScale:Math.min(i,a,...o.slice(0,2))}}function Fh(e,t,n,r,i,a,o){let s=e.height,c=e.width,l=Math.min(.48*s,.43*c/(Math.max(.01,n.width)*t/Math.max(.01,n.height)))*i,u=l/Math.max(.01,n.height),d=u*t,f=.24*c+a*.35*c,p=-.56*s+l+o*.35*s;return{x:f-(n.x+n.width/2-.5)*d,y:p-(.5-n.y)*u,z:r,width:d,height:u}}var Ih=`modulepreload`,Lh=function(e){return`/`+e},Rh={},zh=function(e){return e.pathname.endsWith(`.css`)},Bh=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e,i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)}r=o(t.map(t=>{t=Lh(t,n);let r=s(t);if(r.href in Rh)return;Rh[r.href]=!0;let i=zh(r);if(e===void 0){e={all:new Set,styles:new Set};let t=document.getElementsByTagName(`link`);for(let n=t.length-1;n>=0;n--){let r=t[n];e.all.add(r.href),r.rel===`stylesheet`&&e.styles.add(r.href)}}if((i?e.styles:e.all).has(r.href))return;let o=document.createElement(`link`);if(o.rel=i?`stylesheet`:Ih,i||(o.as=`script`),o.crossOrigin=``,o.href=r.href,a&&o.setAttribute(`nonce`,a),document.head.appendChild(o),i)return new Promise((e,t)=>{o.addEventListener(`load`,e),o.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${r}`)))})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};function Vh(e,t,n){let r=e.querySelector(`#internal-controls`),i=e.querySelector(`#settings-dialog`),a=new AbortController,o={signal:a.signal},s=(t,n,r=``)=>{let i=e.createElement(t);return i.id=n,i.textContent=r,i},c=(e,t)=>{let n=s(`button`,e,t);return n.type=`button`,n},l=s(`section`,`peeking-experiment`);l.className=`peeking-experiment`,l.setAttribute(`aria-labelledby`,`peeking-title`);let u=s(`h3`,`peeking-title`,`마당에서 빼꼼`),d=s(`p`,`peeking-limitations`,`가벼운 누끼 실험이라 털이 잘리거나 배경이 남을 수 있어요. 사진 속 자세를 새로 만들지 않으며, 옆에서 보면 납작해 보일 수 있어요.`),f=s(`p`,`peeking-route-note`,`할머니집 + B에서 보여요. A·포토부스·비교에서는 잠시 원본 사진을 보여줘요.`),p=c(`peeking-choose`,`마당에서 빼꼼 · 실험`);p.setAttribute(`aria-describedby`,`peeking-limitations peeking-route-note`);let m=s(`input`,`peeking-photo`);m.type=`file`,m.accept=`image/*`,m.hidden=!0,m.setAttribute(`aria-label`,`마당 실험에 사용할 사진 선택`);let h=c(`peeking-toggle`,`원본 사진으로 돌아가기`);l.append(u,d,f,p,m,h),r.append(l);let g=s(`dialog`,`peeking-preview-dialog`);g.className=`peeking-preview-dialog`,g.setAttribute(`aria-labelledby`,`peeking-preview-title`),g.setAttribute(`aria-describedby`,`peeking-preview-note`);let _=s(`h2`,`peeking-preview-title`,`누끼를 먼저 확인해 주세요`),v=s(`p`,`peeking-preview-note`,`털·귀·발과 남은 배경을 확인해 주세요. 괜찮을 때만 마당에 배치해요.`),y=s(`p`,`peeking-progress`);y.setAttribute(`role`,`status`),y.setAttribute(`aria-live`,`polite`),y.setAttribute(`aria-atomic`,`true`);let b=s(`p`,`peeking-error`);b.setAttribute(`role`,`alert`);let x=s(`div`,`peeking-comparison`);x.className=`peeking-comparison`;let S=s(`img`,`peeking-original`);S.alt=`배경을 포함한 원본 사진`;let C=s(`img`,`peeking-cutout`);C.alt=`배경 제거 결과, 체크무늬는 투명한 부분`;for(let[e,t,n]of[[S,`원본 사진`,`original`],[C,`누끼 · 체크무늬는 투명`,`cutout`]]){let r=s(`figure`,`peeking-figure-${n}`),i=s(`div`,`peeking-surface-${n}`);i.className=`peeking-preview-surface`,i.append(e),r.append(i,s(`figcaption`,`peeking-caption-${n}`,t)),x.append(r)}let w=s(`p`,`peeking-warning`),T=s(`div`,`peeking-actions`);T.className=`peeking-actions`;let E=c(`peeking-accept`,`이 누끼로 배치`),D=c(`peeking-retry`,`다시 시도하기`),O=c(`peeking-another`,`다른 사진 선택`),k=c(`peeking-cancel`,`취소`);T.append(E,D,O,k),g.append(_,v,y,b,x,w,T),e.body.append(g);let A={available:!1,enabled:!1,busy:!1},j=null,M=null,N=!1,P=()=>{p.disabled=A.busy||N,h.hidden=!A.available,h.disabled=!A.available||A.busy||N,h.textContent=A.enabled?`원본 사진으로 돌아가기`:`마당 실험 다시 보기`,h.setAttribute(`aria-pressed`,String(A.enabled)),E.disabled=!j?.result||A.busy||N},F=()=>{S.removeAttribute(`src`),C.removeAttribute(`src`),x.hidden=!0,w.hidden=!0,w.textContent=``,b.hidden=!0,b.textContent=``,D.hidden=!0,g.setAttribute(`aria-busy`,`false`),P()},I=()=>{g.open&&g.close(),!N&&i.open&&p.isConnected&&!p.disabled&&p.focus({preventScroll:!0})},ee=()=>{let e=j;j=null,M=null,e?.controller.abort(),e?.result?.dispose(),e?.preparation?.dispose(),F(),y.textContent=``,I()},te=async e=>{if(N||A.busy||!i.open)return;ee(),M=e;let t={controller:new AbortController,preparation:null,result:null};j=t;let n=()=>!N&&j===t&&!t.controller.signal.aborted&&i.open;y.textContent=`누끼 미리보기를 준비하는 중…`,g.setAttribute(`aria-busy`,`true`),g.showModal(),k.focus({preventScroll:!0}),P();try{let{CutoutPreparation:r}=await Bh(async()=>{let{CutoutPreparation:e}=await import(`./CutoutPreparation-DTym6CdH.js`);return{CutoutPreparation:e}},[]);if(!n())return;t.preparation=new r;let i=await t.preparation.prepare(e,e=>{n()&&(y.textContent=e)},t.controller.signal);if(!n()){i.dispose(),t.preparation.dispose();return}t.result=i,S.src=i.originalUrl,C.src=i.cutoutUrl,x.hidden=!1;let a=[];i.warnings.includes(`multiple-foreground`)&&a.push(`여러 대상이 남아 있을 수 있어요.`),i.warnings.includes(`tiny-foreground`)&&a.push(`남은 대상이 아주 작아요. 다른 사진이 더 나을 수 있어요.`),w.textContent=a.join(` `),w.hidden=a.length===0,y.textContent=`결과를 확인한 뒤 직접 배치해 주세요.`,g.setAttribute(`aria-busy`,`false`),P()}catch(e){if(!n())return;t.preparation?.dispose(),t.preparation=null,b.textContent=e instanceof Error?e.message:`누끼를 준비하지 못했어요. 다시 시도하거나 다른 사진을 골라 주세요.`,b.hidden=!1,D.hidden=!1,y.textContent=`사진은 아직 바뀌지 않았어요.`,g.setAttribute(`aria-busy`,`false`),P()}},ne=()=>{N||A.busy||!i.open||(ee(),m.value=``,m.click())};p.addEventListener(`click`,ne,o),O.addEventListener(`click`,ne,o),m.addEventListener(`change`,()=>{let e=m.files?.[0];m.value=``,e&&te(e)},o),D.addEventListener(`click`,()=>{M&&te(M)},o),k.addEventListener(`click`,ee,o),g.addEventListener(`cancel`,e=>{e.preventDefault(),e.stopPropagation(),ee()},o),g.addEventListener(`close`,()=>{!g.open&&j&&ee()},o),i.addEventListener(`close`,()=>{i.open||ee()},o),E.addEventListener(`click`,()=>{if(N||A.busy||!j?.result||!j.preparation)return;let{result:e,preparation:t}=j;j=null,M=null;let r=!1,i={...e,dispose(){r||(r=!0,e.dispose(),t.dispose())}};F(),I(),n.onAccept(i)},o),h.addEventListener(`click`,()=>{!N&&A.available&&!A.busy&&n.onToggle(!A.enabled)},o);let re=()=>{N||(N=!0,ee(),a.abort(),t.removeEventListener(`abort`,re),l.remove(),g.remove())};return t.addEventListener(`abort`,re,{once:!0}),F(),t.aborted&&re(),{cancel:ee,dispose:re,setState(e){N||(A={...e},P())}}}var Hh=document.querySelector(`#canvas-wrap`),Uh=document.querySelector(`#status`),Wh=document.querySelector(`#depth-provenance`),Gh=document.querySelector(`#ai-depth`),Kh=document.querySelector(`#empty`),qh=document.querySelector(`#hint`);qh.dataset.phase=`hidden`;var X=new Jc({antialias:!0}),Jh=new Xf;X.localClippingEnabled=!0,X.setPixelRatio(Math.min(devicePixelRatio,1.5)),Hh.append(X.domElement);var Yh=new Yc,Xh=new Yc;Yh.background=new K(16249061);var Zh=new wa(40,1,.1,100);Zh.position.z=3;var Qh=new za(1,1),$h=document.createElement(`canvas`);$h.width=$h.height=512;var eg=$h.getContext(`2d`);function tg(e){let t=Sp[e],n=eg.createLinearGradient(0,0,512,512);t.room.forEach((e,t)=>n.addColorStop(t/2,e)),eg.fillStyle=n,eg.fillRect(0,0,512,512),eg.fillStyle=t.light,eg.fillRect(75,50,115,340),eg.fillStyle=t.mullion,eg.fillRect(320,0,28,512)}tg(`wood`);var ng=new Gl($h);ng.colorSpace=Xt;var rg=new Mi({map:ng}),ig=new q(Qh,rg);Yh.add(ig);var ag=Ch.flatTexture(),og=new Dh(ng,ag,.25,0),sg=og.material,cg=sg.uniforms;Yh.add(og);var Z={uSceneZoom:{value:1},uSceneOffset:{value:new H},uSceneTexture:{value:ng},uSceneDepth:{value:ng},uProtectionDepthMap:cg.uDepthMap,uPetWorldToLocal:{value:new G},uContentViewProjection:{value:new G},uContentInverseViewProjection:{value:new G},uContentCameraPosition:{value:new W},uLightPosition:{value:new W(.6,.8,2.6)},uBackgroundColor:{value:Yh.background.clone()},uGlassZ:{value:.6},uSourceZ:{value:.56},uGridSize:{value:tp.grid},uMosaicStyle:{value:2},uStrength:{value:1},uGlossStrength:{value:.3},uCurvature:{value:1},uRegionStrength:{value:0},uRegionAvailable:{value:0},uRegionAtlasSize:{value:new H(104,104)},uRegionGridSize:{value:new H(13,13)},uRegionPaletteSize:{value:new H(65,13)},uRegionPalette:{value:ng},uRegionAtlas:{value:ng},uViewOffset:{value:new H},uPaneRect:{value:new rr(0,0,1,1)},uResolution:{value:new H},uTime:{value:0},uPetSize:{value:new H(1,1)},uPaneSize:{value:new H(1,1)}},lg={value:ng},ug={value:new H(1,1)};Object.assign(Z,{uRegionHistory:lg,uDepthEvidenceRange:ug,uEnvironmentStrength:{value:$f},uGobangSurface:{value:new rr(tp.heightPerCell,tp.flatHalfWidth,tp.refractiveIndex,tp.thickness)},uGobangBevelRound:{value:tp.bevelRound},uGobangEnvironmentStrength:{value:tp.environmentStrength},uDepthCorrection:{value:new H(bh.blend,bh.maxCellCorrection)}});var dg=new da(1,1,1),fg=[new Mi({color:11837637}),new Mi({color:12824531}),new Mi({color:10323632}),new Mi({color:14272486}),new Mi({color:11178429}),new Mi({color:12626386})],pg=new q(dg,fg),mg=new q(dg,fg),hg=new q(dg,fg),gg=new q(dg,fg);Xh.add(pg,mg,hg,gg);var _g=new Mi({color:fg[1].color,side:2}),vg=new jh(_g);Xh.add(...vg.meshes);var yg=new Zm(Xh,[pg,mg,hg,gg],vg,fg,_g),bg=document.querySelector(`#frame-notice`),xg=document.querySelector(`#frame-retry`),Sg=document.querySelector(`#house-retry`),Cg=!1,wg=!1;function Tg(){bg.hidden=!Cg&&!wg,xg.hidden=!Cg,Sg.hidden=!wg,bg.textContent=[Cg?`나무 창틀을 불러오지 못해 임시 창틀을 보여드려요.`:``,wg?`집 주변 공간을 불러오지 못해 창문만 보여드려요.`:``,Cg||wg?`설정에서 다시 불러올 수 있어요.`:``].filter(Boolean).join(` `)}var Eg=new Fm(Xh,(e,t)=>{yg.setAssetActive(e),Cg=t===`error`,Tg(),Jh.invalidate()}),Dg=new Jm(Xh,e=>{wg=e===`error`,Tg(),Jh.invalidate()}),Og=Ym(og);Xh.add(Og.mesh);var kg=new pp,Ag=new Mh;Xh.add(Ag.group);var jg=null,Mg=null,Ng=null,Pg=!1,Fg=null,Ig=null,Lg=null;function Rg(){return!!(jg&&Ng&&Pg&&Eg.isWood&&p_===`b`&&!v_)}function zg(){return Rg()?Ng:Vg}function Bg(){Fg?.cancel(),Mg?.dispose(),Mg=null,Ng?.dispose(),Ng=null,jg?.dispose(),jg=null,Pg=!1,Fg?.setState({available:!1,enabled:!1,busy:a_||s_||c_})}var Vg=ng,Hg=!1,Ug=1,Wg=1,Gg=1,Kg=1,qg=0,Jg=0,Yg=V.lerp(ep.minGap,ep.maxGap,ep.defaultPercent/100),Xg=!1,Zg=!1,Qg=`noglass`,$g=new Kf,e_=null,t_=null,n_=!1,r_=0,i_=0,a_=!1,o_=!1,s_=!1,c_=!1,l_=!1,u_=null,d_=null,f_=new vp(X,og),p_=`b`,m_=`b`,h_=0,g_=!1,__=null,v_=!1,y_=0,b_=1,x_=null,S_=null,C_=0,w_=new Yf,T_=document.querySelector(`#comparison-toggle`),E_=document.querySelector(`#comparison-exit`),D_=document.querySelector(`#comparison-overlay`),O_=document.querySelector(`#comparison-state`),k_=document.querySelector(`#comparison-timing`),A_=document.querySelector(`#comparison-memory`),Q=new AbortController;xg.addEventListener(`click`,()=>{Eg.load()},{signal:Q.signal}),Sg.addEventListener(`click`,()=>{Dg.load()},{signal:Q.signal});var j_=!1,M_=new uh,N_=document.defaultView?.matchMedia?.(`(prefers-reduced-motion: reduce)`),P_=Af(()=>document.defaultView?.localStorage),F_=zf({visitorId:Pf({getStorage:()=>document.defaultView?.localStorage,randomUUID:()=>globalThis.crypto.randomUUID()}),makeDogId:(e,t)=>Ff(e,t,(e,t)=>globalThis.crypto.subtle.digest(e,t)),transport:Rf(),onCount:e=>Vf([...document.querySelectorAll(`[data-arrival-count]`)],e)}),I_=null,L_=null,R_=null;function z_(){F_?.invalidate(),R_=null}function B_(e){return!F_||!I_||e!==L_||c_||g_||l_?null:(R_===null&&(R_=F_.begin(I_.origin,I_.name)),R_)}Tf(document,Q.signal);var $=Cp(document,Q.signal,e=>{Yh.background.set(Sp[e].background),Z.uBackgroundColor.value.copy(Yh.background),M_.cancel(),yg.apply(e),Eg.apply(e),Dg.apply(e),tg(e),ng.needsUpdate=!0,u_?.invalidate(),j_&&ev()},()=>{nv(),Lg?.start()},e=>{nb(e)},P_,iv,e=>{Bv(),mv.hold(),kv.setPaused(e||$.isBlocked()),rv(),Jh.invalidate()});function V_(e,t=e){Uh.textContent=e,$.setDetail(t)}function H_(){return $.canAdjustPhoto()&&!l_&&!c_&&!g_&&!a_&&!s_&&!o_&&!Hg&&Vg!==ng&&p_===`b`&&Qg===`final`&&!v_&&!Rg()}function U_(){return $.canExportPhoto()&&!l_&&!c_&&!g_&&!a_&&!s_&&!o_&&!Hg&&Vg!==ng&&p_===`b`&&Qg===`final`&&!v_&&!Rg()}async function W_(e,t){if(!U_())throw Error(`사진 준비가 끝난 뒤 일반 화면에서 저장해 주세요.`);let n=r_,r=await Sf(X,document,e,t,t=>{f_.sync({width:Z.uPaneSize.value.x,height:Z.uPaneSize.value.y,grid:Z.uGridSize.value,curvature:Z.uCurvature.value},Z.uGlassZ.value,Z.uLightPosition.value,Yh.background),f_.syncReveal(vg.meshes,Xh),f_.syncCourtyard(null),f_.renderForExport(Zh,Xh,t,e===`photo`)});if(n!==r_||t.aborted||!U_())throw new DOMException(`Cancelled`,`AbortError`);return r}Ig=Cf(document,Q.signal,U_,W_,()=>$.refreshBlocking());var G_=new Ah(Q.signal);function K_(){Fg?.setState({available:!!jg,enabled:Pg,busy:a_||o_||s_||c_||l_}),ry.disabled=c_||Vg===ng||Hg||a_||o_||l_,Gh.disabled=c_||Vg===ng||Hg||a_||o_||s_||l_,Gh.textContent=s_?`사진 분석 중…`:`AI 입체감 만들기`}var q_=new wh(e=>{!l_&&s_&&V_(e)});function J_(){z_(),i_+=1,q_.cancel(),s_=!1,o_=!1,K_()}function Y_(){e_&&e_.dispose(),e_=null}var X_=0;function Z_(){return Z.uGlassZ.value-Yg-(X_-cg.uDepthBias.value)*cg.uDepthScale.value}function Q_(){Y_(),t_=null,Xg=!1,n_=!1}function $_(){Jh.invalidate(),cg.uUsePhotoAlpha.value=Rg(),cg.uTexture.value=zg(),Ag.group.visible=Rg(),kg.setEnabled(Rg()),Yh.background.copy(Rg()?kg.uniforms.uYardSkyColor.value:new K(Sp[Eg.isWood?`wood`:`booth`].background)),Z.uBackgroundColor.value.copy(Yh.background);let e=Z_(),t=(3-e)/3,n=Wg*(Kg-1)*.5*qg*t,r=Gg*(Kg-1)*.5*Jg*t;if(ig.scale.set(Wg*Kg*t,Gg*Kg*t,1),ig.position.set(n,r,e),og.scale.copy(ig.scale),og.position.copy(ig.position),Z.uSourceZ.value=e,vg.update(Z.uPaneSize.value.x,Z.uPaneSize.value.y,Wg*(3-e)/3,Gg*(3-e)/3,Z.uGlassZ.value,e),Rg()&&jg){let t=Ph(Zh.aspect,Ug),n=jg.bounds,r=Fh(t,Ug,{x:n.x0/jg.width,y:n.y0/jg.height,width:(n.x1-n.x0)/jg.width,height:(n.y1-n.y0)/jg.height},e,Kg,qg,Jg);og.position.set(r.x,r.y,r.z),og.scale.set(r.width,r.height,1);let i=r.y+(.5-n.y1/jg.height)*r.height,a=-t.height/2-.1*t.width;kg.setDogContact(r.x+(n.x0/jg.width+(n.x1-n.x0)/jg.width/2-.5)*r.width,e,.2*t.width*Kg,Math.max(0,1-Math.abs(i-a)/(.1*t.height))*.42),vg.update(t.width,t.height,t.width,t.height,Z.uGlassZ.value,Z.uGlassZ.value-.08*Math.min(t.width,t.height))}G_.updateDistance(Yg,cg.uDepthScale.value)}function ev(){Jh.invalidate(),Bv();let e=Hh.getBoundingClientRect();X.setSize(e.width,e.height,!1),x_=__?qf(e.width,e.height,b_).panes:null;let t=x_?x_[0]:e;x_&&(x_.forEach((t,n)=>{let r=document.querySelector(n===0?`#comparison-label-a`:`#comparison-label-b`);r.style.left=`${t.x+t.width/2}px`,r.style.top=`${t.y-32}px`,r.style.width=`${e.width<720?e.width-20:(e.width-36)/2}px`}),__.resize(Math.max(1,Math.floor(t.width*X.getPixelRatio())),Math.max(1,Math.floor(t.height*X.getPixelRatio())))),Zh.aspect=t.width/t.height,yv.updateProjection();let n=Rg()?.74:Ug,r=Om(t.width/t.height,n)*zm(Eg.isWood?`wood`:`booth`);Wg=r*n,Gg=r,$_(),Z.uPetSize.value.set(Wg,Gg),Z.uResolution.value.set(t.width,t.height);let i=4.8*Math.tan(V.degToRad(Zh.fov/2));Z.uPetSize.value.set(i*Zh.aspect,i),Z.uPaneSize.value.set(Wg*(3-Z.uGlassZ.value)/3,Gg*(3-Z.uGlassZ.value)/3),vg.update(Z.uPaneSize.value.x,Z.uPaneSize.value.y,Wg*(3-Z_())/3,Gg*(3-Z_())/3,Z.uGlassZ.value,Z_()),u_?.resize(Math.max(1,Math.floor(t.width*X.getPixelRatio())),Math.max(1,Math.floor(t.height*X.getPixelRatio())));let a=Z.uPaneSize.value.x,o=Z.uPaneSize.value.y,s=Math.min(a,o)*.052,c=s*1.5,l=Z.uGlassZ.value+c*.25;if(pg.position.set(-(a+s)*.5,0,l),mg.position.set((a+s)*.5,0,l),hg.position.set(0,(o+s)*.5,l),gg.position.set(0,-(o+s)*.5,l),pg.scale.set(s,o,c),mg.scale.set(s,o,c),hg.scale.set(a+s*2,s,c),gg.scale.set(a+s*2,s,c),yg.update(a,o,Z.uGlassZ.value,s,c),Eg.resize(a,o,Z.uGlassZ.value),Rg()){let e=Ph(Zh.aspect,Ug);Dg.resize(a,o,Z.uGlassZ.value,e.clearanceScale,{grid:Z.uGridSize.value,curvature:Z.uCurvature.value}),mv.setRoomBounds(a,o,Z.uGlassZ.value),kg.resize(a,o,Z.uGlassZ.value),Ag.resize(a,o,Z.uGlassZ.value),vg.update(a,o,a,o,Z.uGlassZ.value,Z.uGlassZ.value-.08*Math.min(a,o))}else Dg.resize(a,o,Z.uGlassZ.value,void 0,{grid:Z.uGridSize.value,curvature:Z.uCurvature.value}),mv.setRoomBounds(a,o,Z.uGlassZ.value,Eg.isWood);let u=6*Math.tan(V.degToRad(20)),d=u*Zh.aspect;Z.uPaneRect.value.set(Math.max(0,.5-Wg/(2*d)),Math.max(0,.5-Gg/(2*u)),Math.min(1,.5+Wg/(2*d)),Math.min(1,.5+Gg/(2*u)))}function tv(){rv()}function nv(){rv()}function rv(e){$g.interact(performance.now(),e),qh.dataset.phase=`hidden`}function iv(){r_+=1,pv.cancelPending(),J_(),I_=null,L_=null,Fg?.cancel(),Mg?.dispose(),Mg=null,Q_(),a_=!1,Bv(),kv.setPaused(!0),rv(),K_()}function av(e=`personal`,t=!0){z_(),I_=F_&&t?Object.freeze({origin:e,name:P_.name}):null,L_=null,I_&&(R_=F_.begin(I_.origin,I_.name)),$.setMediaOrigin(e),Bv(),$.setPhoto(``),$.setState(`loading`),V_(`사진을 읽고 있어요.`)}function ov(){$.stopPhotoAdjust(),Bv(),kv.disconnect(),mv.reset(),Z.uViewOffset.value.copy(mv.update(0,Zy)),Zh.updateMatrixWorld(!0),xv(1),Kg=1,qg=Jg=0,Vv(0),Jh.invalidate()}function sv(e,t,n){let r=Mg;Mg=null,Bg(),r&&!n?(jg=r,Ng=new nr(r.cutoutImage),Ng.colorSpace=Xt,Ng.needsUpdate=!0,Pg=!0,Kg=1,qg=Jg=0):r?.dispose(),Vg!==ng&&Vg.dispose(),Vg=e,Hg=!!n,a_=!1,Ug=t,L_=!n&&I_?e:null,n&&z_(),Xg=!1,n||ov(),$y(),e.colorSpace=Xt,cg.uTexture.value=zg(),rg.map=e,rg.needsUpdate=!0,$.setPhoto(e.image instanceof HTMLImageElement?e.image.src:``),Kh.style.display=`none`,ev(),K_()}function cv(e){Jh.invalidate(),cg.uDepthMap.value!==ag&&cg.uDepthMap.value.dispose(),cg.uDepthMap.value=e,e.colorSpace=``,ug.value.fromArray(Ch.evidenceRange(e));let t=e.image?.data;if(X_=0,t&&t.length>=4)for(let e=0;e{let r=Xg&&e_!==null,i=n_,a=!n&&!r;sv(e,t,n),og.setVideo(!!n),cv(e_??Ch.flatTexture()),e_=null,r&&t_?fv.setSample(t_):fv.clear(),t_=null,Zg=i,n_=!1,Wh.hidden=!(r||Zg),r?Wh.textContent=`수작업 테스트 Depth · AI 추정 아님`:Zg&&(Wh.textContent=`Depth 없음 · 평면 사진 테스트`),lv(`final`),a||($.setState(`ready`),nv()),iy&&(iy.textContent=`이 사진으로 해보기`),a&&eb(!0)},e=>{let t=a_&&!!e;a_=!1,K_(),(e||!s_)&&V_(e);let n=!!e&&!t&&Hg;uv.hidden=!n,e?(z_(),Mg?.dispose(),Mg=null,$.setState(`error`,!1,n),Q_(),iy&&(iy.textContent=`이 사진으로 해보기`)):Hg&&$.setState(`ready`)});uv.onclick=()=>pv.retry();var mv=new ph(Zh),hv;try{hv=window.localStorage}catch{}var gv=Uf(hv);mv.setCompositionMode(gv),Dg.setCompositionMode(gv);var _v=document.querySelector(`#camera-composition`),vv=document.querySelector(`#camera-composition-note`);_v.value=gv,_v.addEventListener(`change`,()=>{gv=_v.value===`legacy`?`legacy`:`wall`,mv.setCompositionMode(gv),Dg.setCompositionMode(gv);let e=Wf(hv,gv);vv.textContent=(gv===`legacy`?`기존의 넓은 방 구도로 돌아왔어요. `:`벽 옆에서 보는 실험 구도예요. `)+(e?`선택은 이 브라우저에 저장돼요.`:`선택을 저장하지 못했어요. 새로고침하면 이번 선택이 유지되지 않을 수 있어요.`),mv.update(0,Zy),Zh.updateMatrixWorld(!0),Jh.invalidate()},{signal:Q.signal});var yv=new fh(Zh),bv=document.querySelector(`#scene-zoom-reset`);function xv(e,t,n){yv.setZoom(e,t,n),Z.uSceneZoom.value=yv.value,Z.uSceneOffset.value.copy(yv.offset),bv.hidden=yv.value===1}bv.addEventListener(`click`,()=>{xv(1),rv()},{signal:Q.signal});var Sv=document.querySelector(`#gyro`),Cv=document.querySelector(`#gyro-label`),wv=document.querySelector(`#scene-motion`),Tv=wf(globalThis.navigator);Lg=Oe(document,Q.signal,Tv,()=>$.canShowFirstGuide(),()=>{$.refreshBlocking(),ey(performance.now()),Uv(),!Q.signal.aborted&&!$.isBlocked()&&Hh.focus({preventScroll:!0})});var Ev=document.querySelector(`#gyro-recenter`),Dv=document.querySelector(`#gyro-status`),Ov=document.querySelector(`#gyro-notice`),kv=new vh((e,t)=>mv.setView(e,t),(e,t)=>{let n=e===`active`||e===`paused`||e===`waiting`;Cv.textContent=e===`permission`?`권한 요청 취소`:e===`waiting`?`기울기 연결 중`:n?`기울기 켜짐`:`기울기 연결`,Sv.setAttribute(`aria-label`,n?`${Cv.textContent}, 끄기`:Cv.textContent),Sv.setAttribute(`aria-pressed`,String(n)),Sv.setAttribute(`aria-busy`,String(e===`permission`||e===`waiting`)),Ev.hidden=!Tv||e!==`active`&&e!==`paused`||$.isBlocked()&&!$.isGuideOpen()||$.isPhotoAdjusting(),Dv.textContent=t,Ov.textContent=e===`unavailable`?t:``,Ov.hidden=e!==`unavailable`||!Tv||$.isBlocked(),e===`unavailable`&&rv()},()=>({x:mv.target.x,y:mv.target.y}),()=>rv(`tilt`)),Av=null,jv=document.querySelector(`#door-handle`),Mv=document.querySelector(`#door-controls`),Nv=document.querySelector(`#door-toggle`),Pv=document.querySelector(`#door-notice`),Fv=new W,Iv=new vf,Lv=new Na(new W(0,0,1));function Rv(){return p_===`b`&&!v_&&Qg===`final`&&Eg.isWood&&Eg.isReady}function zv(){return Rv()&&Vg!==ng&&!$.isBlocked()&&!$.isPhotoAdjusting()&&!c_&&!g_&&!document.hidden}function Bv(){$v.cancelGesture(),M_.cancel()}function Vv(e){M_.set(e),Uv()}function Hv(e){M_.moveTo(e,performance.now(),!!N_?.matches),Uv()}function Uv(){let e=Rv(),t=zv(),n=M_.value,r=e?n:0;Ag.setOpen(r),Eg.setOpen(r),f_.setSlide(-Z.uPaneSize.value.x*r);let i=$.isGuideOpen()&&e&&Vg!==ng&&!c_&&!g_&&!document.hidden;Mv.hidden=!t&&!i,Nv.disabled=!t&&!i;let a=M_.target>.001;Nv.textContent=a?`문 닫기`:`문 열기`,Nv.setAttribute(`aria-label`,`문 ${Math.round(n*100)}% 열림. ${a?`닫기`:`열기`}. 방향키로 조금씩, Home으로 닫기, End로 열기`),Pv.textContent=v_?`A·B 비교는 닫힌 문으로 표시해요. 비교를 끝내면 열림 위치가 돌아와요.`:p_===`a`?`A 진단은 닫힌 문으로 표시해요. B로 돌아가면 열림 위치가 돌아와요.`:Qg===`final`?Eg.isWood?Eg.isReady?`손잡이만 드래그하면 문, 나머지 영역은 시점 이동이에요. 두 손가락은 항상 확대·축소해요.`:`나무 창틀을 불러온 뒤 손잡이를 밀어 열 수 있어요.`:`미닫이는 할머니집 창가 테마에서 사용할 수 있어요.`:`미닫이는 Final에서 사용할 수 있어요. 진단 화면은 닫힌 상태이며 열림 위치는 보존해요.`;let o=t?Eg.handlePosition(Fv):null;if(jv.hidden=!o,o){let e=X.domElement.getBoundingClientRect();o.project(Zh),jv.hidden=o.z<-1||o.z>1||Math.abs(o.x)>1||Math.abs(o.y)>1,jv.style.left=`${(o.x+1)*e.width/2}px`,jv.style.top=`${(1-o.y)*e.height/2}px`}}function Wv(e){let t=X.domElement.getBoundingClientRect();return!t.width||!t.height?null:(Iv.setFromCamera(new H((e.x-t.left)/t.width*2-1,1-(e.y-t.top)/t.height*2),Zh),Lv.constant=-Z.uGlassZ.value,Iv.ray.intersectPlane(Lv,Fv)?.x??null)}Nv.addEventListener(`click`,()=>{zv()&&($v.cancelGesture(),rv(M_.target>.001?`door-close`:`door-open`),Hv(M_.target>.001?0:1))},{signal:Q.signal}),Nv.addEventListener(`keydown`,e=>{if(!zv())return;let t=e.key===`Home`?0:e.key===`End`?1:e.key===`ArrowLeft`?M_.target+.1:e.key===`ArrowRight`?M_.target-.1:null;if(t===null)return;e.preventDefault(),$v.cancelGesture();let n=Math.max(0,Math.min(1,t));rv(n===M_.target?void 0:n1e-8?V.clamp(l/s,-1,1):0,Jg=c>1e-8?V.clamp(u/c,-1,1):0,$_(),$y()}function Zv(e,t,n=t){let r=Jv(t),i=Jv(n);r&&i&&Xv(e,r,i)}function Qv(e,t){Zv(Kg,{x:0,y:0},{x:e*2,y:t*2})}var $v=new lh(X.domElement,(e,t)=>{$.isBlocked()||($.isPhotoAdjusting()?Qv(e,t):(mv.add(e,t),kv.syncManualView()),rv(`drag`))},rv,{getZoom:()=>$.isPhotoAdjusting()?Kg:yv.value,setZoom:(e,t,n)=>{$.isPhotoAdjusting()?Zv(e,t,n):xv(e,t,n)},isEnabled:()=>!$.isBlocked(),getBounds:e=>{if(!x_)return X.domElement.getBoundingClientRect();let t=X.domElement.getBoundingClientRect(),n=S_??Jf(x_,e.x-t.left,e.y-t.top);return n?{left:t.left+n.x,top:t.top+n.y,width:n.width,height:n.height}:null},subjectDrag:{begin:e=>{if($.isPhotoAdjusting())return qv=Yv(e),!!qv;if(!zv())return!1;let t=Eg.handlePosition(Fv);if(!t)return!1;let n=X.domElement.getBoundingClientRect();t.project(Zh);let r=n.left+(t.x+1)*n.width/2,i=n.top+(1-t.y)*n.height/2;if(t.z<-1||t.z>1||Math.abs(e.x-r)>22||Math.abs(e.y-i)>22)return!1;mv.hold();let a=Wv(e);return a!==null&&(M_.cancel(),Av={startX:a,open:M_.value,screenX:e.x,screenY:e.y,moved:!1},!0)},move:e=>{if($.isPhotoAdjusting()){let t=Yv(e);t&&qv&&Xv(Kg,qv,t),qv=t;return}if(!Av||!zv())return;let t=Wv(e);if(t===null)return;Av.moved||=Math.hypot(e.x-Av.screenX,e.y-Av.screenY)>5;let n=M_.value;Vv(Av.open-(t-Av.startX)/Z.uPaneSize.value.x),Av.moved&&M_.value!==n&&rv(M_.value>n?`door-open`:`door-close`)},end:e=>{if(qv=null,$.isPhotoAdjusting()){Av=null;return}!e&&Av&&!Av.moved&&zv()&&(rv(Av.open>.001?`door-close`:`door-open`),Hv(Av.open>.001?0:1)),Av=null}},onGestureChange:(e,t)=>{e||(S_=null),t&&(mv.hold(),M_.cancel()),kv.setPaused(e||$.isBlocked()||$.isPhotoAdjusting())}});X.domElement.addEventListener(`pointerdown`,e=>{if(x_&&!S_){let t=X.domElement.getBoundingClientRect();S_=Jf(x_,e.clientX-t.left,e.clientY-t.top)}},{capture:!0,signal:Q.signal}),document.addEventListener(`visibilitychange`,()=>{Jh.invalidate(),document.hidden&&Bv()},{signal:Q.signal}),document.querySelector(`#settings-open`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),document.querySelector(`#scene-menu-open`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),document.querySelector(`#sample-home`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),document.querySelector(`#entry-samples`).addEventListener(`click`,()=>{Bv(),kv.setPaused(!0)},{signal:Q.signal}),wv.addEventListener(`click`,()=>rv(),{signal:Q.signal});function ey(e){Ig?.setAvailable(U_());let t=$.isPhotoAdjusting(),n=H_();t&&!n&&$.stopPhotoAdjust(),document.querySelector(`#photo-adjust-open`).hidden=!n||t||$.isBlocked();let r=$.isBlocked()||$.isPhotoAdjusting()||c_||g_||document.hidden,i=$.isGuideOpen()&&!c_&&!g_&&!document.hidden;Ev.hidden=r&&!i||!Tv||kv.state!==`active`&&kv.state!==`paused`;let a=r&&!i||!Tv;wv.hidden!==a&&(wv.hidden=a),!r&&kv.state===`active`&&Lg?.recenter();let o=r||!Tv||kv.state!==`unavailable`;Ov.hidden!==o&&(Ov.hidden=o);let s=$g.update(e,{enabled:!r&&!$v.isInteracting&&!v_&&!M_.isAnimating,tiltActive:kv.state===`active`,sliding:zv(),doorOpen:M_.value,reducedMotion:!!N_?.matches}),c=s?.phase??`hidden`;s&&qh.textContent!==s.text&&(qh.textContent=s.text),qh.dataset.phase!==c&&(qh.dataset.phase=c)}var ty=document.querySelector(`#image`),ny=document.querySelector(`#video`),ry=document.querySelector(`#depth-image`),iy=document.querySelector(`#sample`),ay=document.querySelector(`#test-photo`),oy=document.querySelector(`#reference-strip`),sy=document.querySelector(`#reference-status`),cy=[document.querySelector(`#reference-image-1`),document.querySelector(`#reference-image-2`)];oy.hidden=!1;var ly=()=>{sy.hidden=!1};cy.forEach(e=>e.addEventListener(`error`,ly,{signal:Q.signal})),Promise.all([Bh(()=>import(`./reference1-BphJMCNh.js`),[]),Bh(()=>import(`./reference2-DHNjbprc.js`),[])]).then(([e,t])=>{l_||(cy[0].src=e.default,cy[1].src=t.default)}).catch(()=>{l_||ly()});var uy=document.querySelector(`#effect`),dy=document.querySelector(`#view-mode`),fy=document.querySelector(`#sensitivity`),py=document.querySelector(`#depth-scale`),my=document.querySelector(`#camera-offset`),hy=document.querySelector(`#grid-size`),gy=document.querySelector(`#gridOut`),_y=document.querySelector(`#mosaic-style`),vy=_y.closest(`label`),yy=document.querySelector(`#curvature-controls`),by=document.querySelector(`#region-fixed-note`),xy=document.querySelector(`#curvature`),Sy=document.querySelector(`#light-x`),Cy=document.querySelector(`#light-y`),wy=document.querySelector(`#lightXOut`),Ty=document.querySelector(`#lightYOut`),Ey=document.querySelector(`#cameraOut`),Dy=document.querySelector(`#photo-glass-distance`),Oy=document.querySelector(`#photoGlassDistanceOut`),ky=document.querySelector(`#sensitivityOut`),Ay=document.querySelector(`#depthOut`),jy=document.querySelector(`#photo-zoom`),My=document.querySelector(`#photoZoomOut`),Ny=document.querySelector(`#photo-pan-x`),Py=document.querySelector(`#photoPanXOut`),Fy=document.querySelector(`#photo-pan-y`),Iy=document.querySelector(`#photoPanYOut`),Ly=document.querySelector(`#photo-reset`),Ry=document.querySelector(`#reset`),zy=document.querySelector(`#glass-renderer`),By=document.querySelector(`#renderer-notice`),Vy=document.querySelector(`#mesh-render-error`);async function Hy(){return u_||(d_||=Bh(async()=>{let{createOriginalGlassRenderer:e}=await import(`./OriginalGlassRenderer-BAqBMSXc.js`);return{createOriginalGlassRenderer:e}},[]).then(({createOriginalGlassRenderer:e})=>{if(l_)throw Error(`Scene disposed`);return u_=e({renderer:X,scene:Yh,frameScene:Xh,camera:Zh,petDepth:og,uniforms:Z,depthUniforms:cg,emptyTex:ng,regionHistoryUniform:lg,state:()=>({mode:Qg,active:Vg,activeIsVideo:Hg,effect:uy.value,style:_y.value})}),u_.setEffect(uy.value),ev(),u_}).finally(()=>{d_=null}),d_)}function Uy(){p_===`b`&&m_===`b`&&!v_&&(u_?.dispose(),u_=null)}function Wy(){let e=p_===`a`;zy.value=p_,document.querySelector(`#pattern-cards`).hidden=uy.value!==`mosaic`,uy.disabled=!e,document.querySelectorAll(`[data-pattern]`).forEach(t=>{t.hidden=!e&&t.dataset.pattern!==`2`}),By.textContent=e?`A 진단 모드 · 기존 무늬와 화면 기반 굴절`:`기본 B · 실제 고방 메시 + 맞춤 굴절`+(f_.environmentOnly?` · 환경광만`:``),Qy()}async function Gy(e){Bv();let t=++h_;m_=e;try{if(e===`a`&&await Hy(),l_||c_||t!==h_){Uy();return}Bv(),p_=e,v_&&Yy(),e===`b`&&(uy.value=`mosaic`,_y.value=`2`,Z.uMosaicStyle.value=2,Z.uRegionStrength.value=0,Z.uStrength.value=1,u_?.setEffect(`mosaic`),document.querySelectorAll(`[data-pattern]`).forEach(e=>e.setAttribute(`aria-pressed`,String(e.dataset.pattern===`2`)))),Uy(),Wy(),ev(),g_&&(g_=!1,Vy.close(),$.setRenderLost(!1))}catch{t===h_&&(m_=p_),Uy(),zy.value=p_,By.textContent=`A 진단 렌더러를 불러오지 못했어요. 현재 화면을 유지해요.`}}function Ky(){c_||l_||g_||(z_(),g_=!0,Bv(),kv.setPaused(!0),$.setRenderLost(!0),v_&&Yy(`B 렌더링이 멈췄어요. 복구 방법을 선택해주세요.`),Vy.showModal())}Vy.addEventListener(`cancel`,e=>e.preventDefault(),{signal:Q.signal}),document.querySelector(`#mesh-retry`).addEventListener(`click`,()=>{c_||l_||(f_.dispose(),f_=new vp(X,og),Jh.invalidate(),g_=!1,Vy.close(),$.setRenderLost(!1),Wy())},{signal:Q.signal}),document.querySelector(`#mesh-use-a`).addEventListener(`click`,()=>{Gy(`a`)},{signal:Q.signal}),zy.addEventListener(`change`,()=>{Gy(zy.value===`a`?`a`:`b`)},{signal:Q.signal});function qy(e){if(p_===`a`){u_.render(e);return}if(Qg===`rgb`||Qg===`depth`){X.setRenderTarget(null),X.render(Yh,Zh);return}try{f_.sync({width:Z.uPaneSize.value.x,height:Z.uPaneSize.value.y,grid:Z.uGridSize.value,curvature:Z.uCurvature.value},Z.uGlassZ.value,Z.uLightPosition.value,Yh.background),f_.syncReveal(vg.meshes,Xh),f_.syncCourtyard(Rg()?kg:null),f_.render(Zh,Xh,Qg===`final`||Qg===`glass`,null,Qg!==`glass`)}catch{Ky()}}function Jy(){return uy.value===`mosaic`&&_y.value===`2`&&(Qg===`final`||Qg===`noglass`)}function Yy(e=`비교를 끝냈어요. 선택한 단독 렌더러로 돌아왔어요.`){y_+=1,v_=!1,Bv(),S_=null,__?.dispose(),__=null,x_=null,Uy(),X.info.autoReset=!0,D_.hidden=!0,E_.hidden=!0,T_.textContent=`비교 켜기 · 추가 렌더 비용`,T_.setAttribute(`aria-pressed`,`false`),O_.textContent=e,document.querySelector(`#experience`).removeAttribute(`data-comparison`),w_.reset(),c_||ev()}async function Xy(){if(v_){Yy();return}if(Vg===ng||s_||o_||a_){O_.textContent=`사진 준비가 끝난 뒤 비교를 켜주세요.`;return}if(c_||l_||!Jy()){O_.textContent=`고방유리와 Final 또는 No Glass를 선택한 뒤 비교를 켜주세요.`;return}Bv(),v_=!0;let e=++y_;T_.textContent=`비교 준비 취소`,O_.textContent=`굴절 보정 B를 준비하고 있어요.`;try{let{PhysicalGlassComparison:t}=await Bh(async()=>{let{PhysicalGlassComparison:e}=await import(`./PhysicalGlassComparison-HEVBf_iN.js`);return{PhysicalGlassComparison:e}},[]);if(await Hy(),l_||c_||e!==y_||!v_){Uy();return}if(!Jy()){Yy(`고방유리 Final / No Glass에서 비교할 수 있어요.`);return}b_=Zh.aspect,__=new t(X,Yh.background),Bv(),rv(),X.info.autoReset=!1,w_.reset(),k_.textContent=`첫 프레임을 준비하는 중…`,A_.textContent=``,C_=0,D_.hidden=!1,E_.hidden=!1,T_.textContent=`비교 끝내기`,T_.setAttribute(`aria-pressed`,`true`),O_.textContent=`A 기존 코드 / 굴절 보정 B · 실제 메시 + 맞춤 굴절. 두 화면의 드래그·확대·거리·깊이를 공유해요.`,document.querySelector(`#comparison-label-b`).textContent=f_.environmentOnly?`굴절 보정 B · 맞춤 굴절 (환경광만)`:`굴절 보정 B · 맞춤 굴절`,document.querySelector(`#experience`).setAttribute(`data-comparison`,`true`),ev(),document.querySelector(`#settings-dialog`).close(),Hh.focus({preventScroll:!0})}catch{Yy(`비교 렌더러를 준비하지 못했어요. 단독 화면을 유지해요.`)}}T_.addEventListener(`click`,()=>{Xy()},{signal:Q.signal}),E_.addEventListener(`click`,()=>{Yy(),Hh.focus({preventScroll:!0})},{signal:Q.signal});for(let e of[uy,_y,dy])e?.addEventListener(`change`,()=>{queueMicrotask(()=>{v_&&!Jy()&&Yy(`다른 무늬·진단 화면을 선택해 비교를 끝냈어요.`)})},{signal:Q.signal});var Zy=1;function Qy(){let e=uy.value===`mosaic`;vy&&(vy.style.display=e?`grid`:`none`),_y.disabled=!e,yy&&(yy.hidden=!e,yy.style.display=e?`grid`:`none`),by&&(by.hidden=!e,by.textContent=_y.value===`2`?`고방유리 · 표면 요철에 따른 굴절 · 색면 처리 없음`:_y.value===`0`?`Ref1 옵션 2 · 색면 단순화 1 · 굴절 1 (고정)`:`기존 촘촘 유리 · 굴절 1 (고정)`),[Sy,Cy,xy].forEach(t=>{t&&(t.disabled=!e)})}function $y(){jy&&(jy.value=Kg.toFixed(2)),My&&(My.value=Kg.toFixed(2)),document.querySelector(`#photo-adjust-zoom`).value=Kg.toFixed(2),document.querySelector(`#photo-adjust-value`).value=Kg.toFixed(2),document.querySelector(`#photo-adjust-help`).textContent=Kg<=1.001?`사진을 확대한 뒤 드래그해서 위치를 맞춰주세요`:`드래그·방향키로 이동 · 두 손가락·휠로 확대`,Ny&&(Ny.value=qg.toFixed(2)),Py&&(Py.value=qg.toFixed(2)),Fy&&(Fy.value=Jg.toFixed(2)),Iy&&(Iy.value=Jg.toFixed(2))}async function eb(e=!1){if(Gh.disabled||!(Vg.image instanceof HTMLImageElement))return;let t=Vg,n=B_(t),r=Vg.image,i=++i_;s_=!0,Bv(),$.startJourney(),V_(`출발 준비 중이에요. 처음에는 조금 더 걸릴 수 있어요.`),K_();try{let a=await q_.getDepthMap(r);if(l_||i!==i_||Vg!==t||Hg){a.dispose();return}cv(a),fv.clear(),Zg=!1,Wh.hidden=!1,Wh.textContent=`AI 추정 · Depth Anything V2 ${xh.modelName} · 입력 ${xh.inputSize} (상대 깊이, 0=뒤 · 1=앞)`,lv(`final`),!c_&&!g_&&n!==null&&n===R_&&F_?.arrived(n),$.setState(`ready`),V_(e?`입체감 준비 완료! 사진을 살짝 움직여보세요.`:`새 입체감을 적용했어요. 사진을 움직여 확인해보세요.`),nv()}catch(e){!l_&&i===i_&&(z_(),$.setState(`error`,!0),V_(`사진 분석 실패: ${e instanceof Error?e.message:`알 수 없는 오류`}. 다시 시도하거나 평면 사진으로 볼 수 있어요.`,`사진을 준비하지 못했어요. 다시 시도하거나 다른 사진을 골라 주세요. 평면 사진으로 볼 수도 있어요.`))}finally{i===i_&&(s_=!1,K_())}}Gh.addEventListener(`click`,()=>{eb()},{signal:Q.signal}),Fg=Vh(document,Q.signal,{onAccept(e){if(c_||l_){e.dispose();return}tv(),r_+=1,J_(),pv.cancelPending(),Q_(),Mg?.dispose(),Mg=e,a_=!0,av(),K_(),pv.load(new File([e.originalBlob],`peeking-original.png`,{type:`image/png`}))},onToggle(e){!jg||a_||s_||c_||(Bv(),Pg=e,Kg=1,qg=Jg=0,$y(),ev(),lv(Qg),u_?.invalidate(),Fg?.setState({available:!0,enabled:e,busy:!1}))}});function tb(e){return c_||l_||!e.type.startsWith(`image/`)?!1:(Fg?.cancel(),Mg?.dispose(),Mg=null,tv(),r_+=1,J_(),av(),a_=!0,K_(),Q_(),pv.load(e),!0)}ty.onchange=e=>{let t=e.target,n=t.files?.[0];n&&tb(n),t.value=``},Ef(document,Q.signal,()=>!l_&&!c_&&!g_&&$.canAcceptPhotoPaste(),tb),ny.onchange=e=>{let t=e.target,n=t.files?.[0];n&&!c_&&(Fg?.cancel(),Mg?.dispose(),Mg=null,tv(),r_+=1,J_(),av(`personal`,!1),a_=!0,K_(),Q_(),pv.load(n)),t.value=``},document.querySelector(`#photo-adjust-open`).addEventListener(`click`,()=>{H_()&&!$.isBlocked()&&($.startPhotoAdjust(),$y())},{signal:Q.signal}),document.querySelector(`#photo-adjust-zoom`).addEventListener(`input`,e=>{$.isPhotoAdjusting()&&H_()&&(Kg=V.clamp(Number(e.target.value)||1,1,3),$_(),$y())},{signal:Q.signal}),document.querySelector(`#photo-adjust-reset`).addEventListener(`click`,()=>{$.isPhotoAdjusting()&&H_()&&(Kg=1,qg=Jg=0,$_(),$y())},{signal:Q.signal}),jy?.addEventListener(`input`,e=>{Kg=Number(e.target.value),$_(),$y()},{signal:Q.signal}),Ny?.addEventListener(`input`,e=>{qg=Number(e.target.value),$_(),$y()},{signal:Q.signal}),Fy?.addEventListener(`input`,e=>{Jg=Number(e.target.value),$_(),$y()},{signal:Q.signal}),Ly?.addEventListener(`click`,()=>{Kg=1,qg=0,Jg=0,$_(),$y()},{signal:Q.signal});async function nb(e){if(c_||l_||![`dog1`,`dog2`,`dog3`,`dog4`,`dog5`].includes(e))return;tv(),ay.value=e,$.setSampleName?.({dog1:`호두`,dog2:`두부`,dog3:`보리`,dog4:`콩이`,dog5:`누렁이`}[e]),Fg?.cancel(),Mg?.dispose(),Mg=null;let t=++r_,n=`/assets/samples/${e}.jpg`;J_(),a_=!0,av(`sample`),K_(),pv.cancelPending(),Q_(),iy&&(iy.textContent=`사진을 불러오는 중…`),V_(``);try{let e=await fetch(n);if(!e.ok)throw Error(`image`);let r=await e.blob();if(l_||t!==r_)return;n_=!0,pv.load(new File([r],n.split(`/`).pop()??`test-photo`,{type:e.headers.get(`content-type`)??`image/jpeg`}))}catch{!l_&&t===r_&&(z_(),a_=!1,K_(),$.setState(`error`),Q_(),V_(`샘플 사진을 읽지 못했습니다. 다른 사진을 고르거나 다시 시도해 주세요.`),iy&&(iy.textContent=`이 사진으로 해보기`))}}iy?.addEventListener(`click`,()=>{nb(ay.value)},{signal:Q.signal}),uy.addEventListener(`change`,e=>{u_?.setEffect(e.target.value),Qy()},{signal:Q.signal}),dy?.addEventListener(`change`,e=>lv(e.target.value),{signal:Q.signal}),fy.oninput=e=>{let t=Number(e.target.value);Zy=t,ky.value=t.toFixed(2)},py?.addEventListener(`input`,e=>{let t=Math.min(Number(e.target.value),.4);cg.uDepthScale.value=t,$_(),u_?.invalidate(),Ay&&(Ay.value=t.toFixed(2))},{signal:Q.signal}),my.addEventListener(`input`,e=>{let t=Number(e.target.value);mv.setMaxOffset(t),Ey.value=t.toFixed(2)},{signal:Q.signal}),Dy.addEventListener(`input`,e=>{let t=Number(e.target.value);Yg=V.lerp(ep.minGap,ep.maxGap,t/100),$_(),Oy.value=`${t.toFixed(0)}%`},{signal:Q.signal}),hy.addEventListener(`input`,e=>{let t=Number(e.target.value);Z.uGridSize.value=t,gy.value=t.toFixed(0),ev()},{signal:Q.signal}),_y.addEventListener(`change`,e=>{if(uy.value!==`mosaic`)return;let t=Number(e.target.value);Z.uMosaicStyle.value=t,Z.uGridSize.value=t===0?13:t===2?tp.grid:24,Z.uRegionStrength.value=+(t===0),Z.uStrength.value=1,hy.value=String(Z.uGridSize.value),gy.value=String(Z.uGridSize.value),ev(),Qy()},{signal:Q.signal}),xy?.addEventListener(`change`,e=>{Z.uCurvature.value=e.target.value===`-1`?-1:1},{signal:Q.signal}),Sy?.addEventListener(`input`,e=>{let t=Number(e.target.value);Z.uLightPosition.value.x=t,wy&&(wy.value=t.toFixed(2))},{signal:Q.signal}),Cy?.addEventListener(`input`,e=>{let t=Number(e.target.value);Z.uLightPosition.value.y=t,Ty&&(Ty.value=t.toFixed(2))},{signal:Q.signal}),ry?.addEventListener(`change`,async()=>{if(c_){ry.value=``;return}let e=ry.files?.[0];if(!e||Vg===ng||Hg||a_)return;J_();let t=i_;o_=!0,Bv(),$.setState(`loading`),V_(`깊이 이미지를 읽고 있어요.`),K_(),fv.clear();let n=URL.createObjectURL(e),r=null;try{let e=new Image;if(e.src=n,await e.decode(),l_||t!==i_)return;if(Ug>0&&Math.abs(e.width/e.height-Ug)>.02)throw Error(`aspect`);if(r=Ch.toTexture(e),l_||t!==i_){r.dispose(),r=null;return}cv(r),r=null,Wh.hidden=!1,Wh.textContent=`직접 올린 깊이 이미지 · AI 추정 아님 (0=뒤, 1=앞)`,V_(`직접 올린 깊이 이미지를 적용했어요.`),$.setState(`ready`),nv()}catch{!l_&&t===i_&&(V_(`깊이 이미지를 읽지 못했거나 사진과 종횡비가 다릅니다.`),$.setState(`error`,Vg!==ng&&!Hg))}finally{r?.dispose(),URL.revokeObjectURL(n),t===i_&&(ry.value=``,o_=!1,K_())}},{signal:Q.signal}),Ry.onclick=()=>{mv.reset(),kv.reset(),xv(1)},Sv.onclick=()=>{Tv&&!$.isBlocked()&&!$.isPhotoAdjusting()&&kv.toggle()},Ev.addEventListener(`click`,()=>{$.isBlocked()||$.isPhotoAdjusting()||(mv.reset(),kv.reset())},{signal:Q.signal}),document.querySelector(`#scene-guide-replay`).addEventListener(`click`,()=>Lg?.start(!0),{signal:Q.signal}),document.querySelector(`#guide-replay`).addEventListener(`click`,()=>{let e=document.querySelector(`#settings-dialog`);e.open&&(e.addEventListener(`close`,()=>Lg?.start(!0),{once:!0,signal:Q.signal}),e.close())},{signal:Q.signal}),Hh.addEventListener(`keydown`,e=>{if($.isBlocked())return;let t=e.key===`ArrowLeft`?[-.06,0]:e.key===`ArrowRight`?[.06,0]:e.key===`ArrowUp`?[0,.06]:e.key===`ArrowDown`?[0,-.06]:null;t&&(e.preventDefault(),$.isPhotoAdjusting()?Qv(t[0],t[1]):(mv.add(t[0],t[1]),kv.syncManualView()),rv(`drag`))},{signal:Q.signal}),document.querySelectorAll(`[data-pick-photo]`).forEach(e=>e.addEventListener(`click`,()=>ty.click(),{signal:Q.signal})),document.querySelector(`#flow-retry`).addEventListener(`click`,()=>{Hg?pv.retry():eb()},{signal:Q.signal}),document.querySelector(`#flow-flat`).addEventListener(`click`,()=>{Vg!==ng&&(z_(),cv(Ch.flatTexture()),lv(`final`),Wh.hidden=!1,Wh.textContent=`입체감 없는 평면 사진 · AI 추정 아님`,$.setState(`ready`),nv())},{signal:Q.signal}),bp(document,Q.signal);var rb=new wp(X.domElement,document.querySelector(`#render-recovery`),document.querySelector(`#render-reload`),()=>{c_=!0,h_+=1,m_=p_,Vy.open&&Vy.close(),v_&&Yy(`그래픽 연결이 끊겨 비교를 종료했어요. 복구 후 선택한 단독 렌더러로 돌아가요.`);let e=s_||o_||a_;$.setRenderLost(!0),Bv(),kv.setPaused(!0),rv(),Fg?.cancel(),Mg?.dispose(),Mg=null,r_+=1,pv.cancelPending(!0),a_=!1,ry.value=``,J_(),Q_(),e&&($.setState(`error`,Vg!==ng&&!Hg),V_(`그래픽 연결이 끊겨 사진 준비를 멈췄어요. 화면이 복구되면 다시 시도하거나 평면 사진으로 볼 수 있어요.`))},()=>{u_?.invalidate(),f_.restore(),ev(),c_=!1,g_=!1,$.setRenderLost(!1),K_()},()=>window.location.reload()),ib=new ResizeObserver(ev);ib.observe(Hh),ev(),lv(`final`),Qy(),K_(),Wy(),Eg.load(),j_=!0,Dg.load(),F_?.start();var ab=performance.now(),ob=0;function sb(){let e=new Set([`uTime`,`uSceneTexture`,`uSceneDepth`,`uRegionPalette`,`uRegionAtlas`,`uRegionHistory`]),t=Object.entries({...Z,...cg}).filter(([t])=>!e.has(t)).map(([e,t])=>{let n=t.value;if(n instanceof nr){let t=n===Vg&&Hg?n.image:null,r=t&&typeof t.requestVideoFrameCallback!=`function`?t.currentTime:n.version;return`${e}:${n.uuid}:${r}`}return n&&typeof n.toArray==`function`?`${e}:${n.toArray().join(`,`)}`:`${e}:${n}`});return[p_,Qg,__?`comparison`:`single`,uy.value,_y.value,X.domElement.width,X.domElement.height,Eg.isReady,Dg.isReady,Eg.isWood,...Zh.matrixWorld.elements,...Zh.projectionMatrix.elements,...og.matrixWorld.elements,M_.value,...t].join(`|`)}function cb(e){let t=Math.min((e-ab)/1e3,.1);if(ab=e,kv.setPaused($.isBlocked()||$.isPhotoAdjusting()||$v.isInteracting),ey(e),M_.update(e,zv(),!!N_?.matches),Uv(),c_||s_||document.hidden){Jh.invalidate(),w_.reset(),ob=requestAnimationFrame(cb);return}if(g_){Jh.invalidate(),ob=requestAnimationFrame(cb);return}!$.isBlocked()&&!$.isPhotoAdjusting()&&Z.uViewOffset.value.copy(mv.update(t,Zy)),Zh.updateMatrixWorld(!0),og.updateMatrixWorld(!0),Uv(),Og.sync(Dg.isReady&&Eg.isWood&&(Qg===`final`||Qg===`noglass`&&cg.uUsePhotoAlpha?.value)&&Vg!==ng),Z.uPetWorldToLocal.value.copy(og.matrixWorld).invert(),Z.uContentViewProjection.value.multiplyMatrices(Zh.projectionMatrix,Zh.matrixWorldInverse),Z.uContentInverseViewProjection.value.copy(Z.uContentViewProjection.value).invert(),Z.uContentCameraPosition.value.copy(Zh.position),Z.uTime.value=e/1e3;let n=fv.update(Zh,og,cg.uDepthScale.value,cg.uDepthBias.value,Hh.clientWidth,Z.uSourceZ.value,X_);dv.textContent=n,dv.hidden=!n;let r=(p_===`a`||!!__)&&(Qg===`final`||Qg===`glass`)&&uy.value===`mosaic`&&_y.value===`0`&&Z.uRegionAvailable.value>.5&&Z.uRegionStrength.value>.001&&Z.uStrength.value>.001;if(!Jh.shouldRender(t,{signature:sb(),continuous:M_.isAnimating,temporal:r})){w_.reset(),__&&(k_.textContent=`정지 화면 · 추가 렌더링 대기 중`),ob=requestAnimationFrame(cb);return}if(__&&x_){X.info.reset();let n=performance.now();u_.render(t,__.targetA),w_.record(`a`,performance.now()-n,X.info.render);let r=X.info.render.calls,i=X.info.render.triangles;n=performance.now();try{if(f_.sync({width:Z.uPaneSize.value.x,height:Z.uPaneSize.value.y,grid:Z.uGridSize.value,curvature:Z.uCurvature.value},Z.uGlassZ.value,Z.uLightPosition.value,Yh.background),f_.syncReveal(vg.meshes,Xh),f_.syncCourtyard(Rg()?kg:null),f_.render(Zh,Xh,Qg===`final`,__.targetB),w_.record(`b`,performance.now()-n,{calls:X.info.render.calls-r,triangles:X.info.render.triangles-i}),__.composite(x_,Hh.clientHeight),w_.frame(e),e-C_>500){C_=e;let t=w_.snapshot();k_.textContent=`CPU 제출 A ${t.a.cpuMs.toFixed(2)}ms · B ${t.b.cpuMs.toFixed(2)}ms\n화면 간격 ${t.frameMs?.toFixed(1)??`—`}ms (A+B 동시)\nDraw A ${t.a.calls} · B ${t.b.calls} / Tri A ${t.a.triangles.toLocaleString()} · B ${t.b.triangles.toLocaleString()}`;let n=performance.memory?.usedJSHeapSize;A_.textContent=`GL 형상 ${X.info.memory.geometries} · 텍스처 ${X.info.memory.textures} / B CPU ${(f_.geometryBytes/1048576).toFixed(2)}MiB\n${Number.isFinite(n)?`JS heap 약 ${(n/1048576).toFixed(1)}MiB (페이지·비표준)`:`JS heap API 미지원`}${f_.reducedSampling?` · B 세분화 축소`:``}`}}catch{Ky()}}else qy(t);ob=requestAnimationFrame(cb)}ob=requestAnimationFrame(cb);function lb(){F_?.dispose(),Bg(),Fg?.dispose(),kg.dispose(),Ag.dispose(),M_.cancel(),h_+=1,y_+=1,v_=!1,__?.dispose(),__=null,l_=!0,r_+=1,i_+=1,q_.cancel(),Gh.disabled=!0,Y_(),Q.abort(),rb.dispose(),cancelAnimationFrame(ob),ib.disconnect(),ty.onchange=null,ny.onchange=null,uy.onchange=null,fy.oninput=null,Ry.onclick=null,Sv.onclick=null,uv.onclick=null,$v.dispose(),kv.dispose(),pv.dispose(),u_?.dispose(),f_.dispose(),Eg.dispose(),Dg.dispose(),Og.dispose(),yg.dispose(),vg.dispose(),_g.dispose(),fg.forEach(e=>e.dispose()),Vg!==ng&&Vg.dispose(),cg.uDepthMap.value!==ag&&cg.uDepthMap.value.dispose(),ag.dispose(),og.geometry.dispose(),sg.dispose(),Qh.dispose(),rg.dispose(),dg.dispose(),ng.dispose(),X.domElement.remove(),X.dispose(),qh.dataset.phase=`hidden`,uv.remove(),dv.remove()}import.meta.hot?.dispose(lb);export{Ke as a,Ne as c,Yc as d,ya as f,ar as h,To as i,Xa as l,We as m,K as n,q as o,ze as p,nt as r,Mi as s,ih as t,za as u}; \ No newline at end of file diff --git a/dist/index.html b/dist/index.html index d13b1f7..b8d292b 100644 --- a/dist/index.html +++ b/dist/index.html @@ -7,8 +7,18 @@ Behind Glass · 할머니집 창가 - - + + +
@@ -46,7 +56,7 @@

기울기는 꺼져 있어요. 드래그로 둘러볼 수 있어요.

-
+

behind glass

할머니 집에
멍멍이가 왔어요

@@ -76,7 +86,6 @@ -
diff --git a/index.html b/index.html index 430e545..6af2c2a 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,17 @@ Behind Glass · 할머니집 창가 + +
@@ -44,7 +55,7 @@

기울기는 꺼져 있어요. 드래그로 둘러볼 수 있어요.

-
+

behind glass

할머니 집에
멍멍이가 왔어요

@@ -74,7 +85,6 @@ -
diff --git a/scripts/test-arrival-integration.mjs b/scripts/test-arrival-integration.mjs index 8216316..1fc4bed 100644 --- a/scripts/test-arrival-integration.mjs +++ b/scripts/test-arrival-integration.mjs @@ -45,11 +45,14 @@ test('photo snapshot comes from the name store and survives retry without reread assert.match(fn('showMeshFailure'), /cancelArrivalJourney\(\)/); assert.doesNotMatch(fn('generateAIDepth'), /beginMediaLoad|petNameForms/); }); -test('two initially hidden counts sit below entry controls and the settings heading', () => { +test('two initially hidden counts sit in the loading footer and below the settings heading', () => { const nodes = [...html.matchAll(/]*data-arrival-count[^>]*>/g)]; assert.equal(nodes.length, 2); for (const [node] of nodes) { assert.match(node, /\bhidden\b/); assert.doesNotMatch(node, /aria-live|role=/); } - assert.match(html, /id="notice-status"[^>]*><\/span>\s*<\/div>\s*]*data-arrival-count/); + const welcome = html.match(/
/)[0]; + const loading = html.match(/
/)[0]; + assert.doesNotMatch(welcome, /data-arrival-count/); + assert.match(loading, /]*data-arrival-count[^>]*><\/p>\s*<\/section>/); assert.match(html, /id="settings-title"[\s\S]*?<\/div>\s*]*data-arrival-count/); assert.match(css, /\.arrival-count\s*\{[^}]*(?:font-size|line-height)/); }); diff --git a/src/main.ts b/src/main.ts index 12f75c3..b3fd156 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,7 +12,6 @@ import { createArrivalTracker } from './analytics/ArrivalTracker'; import { renderArrivalCount } from './ui/ArrivalCount'; import * as THREE from 'three'; import {readCameraComposition,saveCameraComposition} from './input/CameraComposition'; -import './style.css'; import { SceneHints, type HintKind } from './ui/SceneHints'; import './ui/peeking-experiment.css'; import { comparisonLayout, paneAt, type PaneRect } from './rendering/ComparisonLayout'; diff --git a/src/style.css b/src/style.css index d7da3b2..bb7f095 100644 --- a/src/style.css +++ b/src/style.css @@ -31,6 +31,7 @@ body { font-size:16px; line-height:1.65; } +html[data-font-loading] #app { visibility:hidden; opacity:0; } button,input,select { font:inherit; color:inherit; @@ -1243,6 +1244,8 @@ body { overflow:hidden; } /* Confirmed totals stay secondary to the photo experience. */ .arrival-count { margin:8px 0 0; color:var(--muted); font-size:12px; line-height:1.6; } +.flow-overlay { padding-bottom:max(64px,calc(env(safe-area-inset-bottom) + 44px)); } +.flow-overlay > .arrival-count { position:absolute; left:24px; right:24px; bottom:max(18px,env(safe-area-inset-bottom)); margin:0; } #settings-dialog .arrival-count { margin:0 0 18px; } /* Two short entry steps stay scrollable on small screens and at text zoom. */