크리켓에 오신 것을 환영합니다
Welcome to Cricket Seoul
🦗 귀뚜라미 소리와 함께 들어가세요
모두가 들을 수 있는 귀뚜라미의 울음은 사회적 지위에 상관없이 자연에서 들리는 아름다운 소리 중 하나입니다. 우리는 귀뚜라미의 소리처럼 많은 사람들에게 한국적인 술과 음식을 들려주려 합니다.
Cocktail
클래식을 한국 전통주로 비틀다
모든 칵테일 ₩25,000 · 탭 시스템으로 알콜/무알콜 선택 가능
Food
사계절과 도시, 시골이 담긴 안주

크리켓의 요리는 한국의 익숙한 안주에 영감받은 요리들입니다. 주점에서 흔히 만나는 메뉴들을 크리켓만의 독창적인 해석으로 재탄생시켜, 특별한 경험을 선사합니다.

가격 단위 1,000원
Flight Set
한국의 술을 다양하게 즐기는 꾸러미
3 Glass Flight
29,000
Takju · Yakju or Sparkling · Jeontongju
5 Glass Flight
49,000
Takju · Yakju · Sparkling · Jeontongju · Spirit
Takju
쌀과 누룩으로 빚어 거르지 않은 탁한 술. 은은한 탄산과 새콤달콤함.
Yakju
탁주를 맑게 거른 청주 계열. 약재나 꽃을 더하기도 한다.
Jeontongju
발효주를 증류한 전통 소주와 리큐르.
Sparkling
국산 과일이나 쌀로 빚은 스파클링.
Spirit
한국의 증류주.
* 구성은 매달 바뀝니다 · Selections vary each month
전통주 도감
크리켓 서울이 담은 한국의 술

전통주(傳統酒)란 우리 쌀과 누룩으로, 우리 땅의 방식으로 빚어온 술을 말합니다. 거르지 않은 탁주(막걸리), 맑게 거른 약주·청주, 이를 증류한 소주, 과일로 빚은 과실주까지. 크리켓 서울은 전국 각지의 양조장에서 온 술을 소개하고, 그 술이 태어난 자리를 지도로 보여줍니다.

가격 = 잔 / 병 (단위 1,000원)
전통주 지도
지역에 손을 올리면 그곳의 술이 보입니다
🖐️ 지역을 누르면 확대되고, 그 안의 점(양조지)을 누르면 술이 아래에 나옵니다
지역을 선택하세요
시·도에 손을 올리거나 누르면 그 지역이 커지고, 전통주가 생산된 자리에 점이 찍힙니다.
술자리 게임
한 잔 걸고 하는 놀이
전통주란?
쌀 한 톨이 술이 되기까지
쌀
그림을 누르면 크게 볼 수 있습니다
누룩
그림을 누르면 크게 볼 수 있습니다
발효
그림을 누르면 크게 볼 수 있습니다
거르기
그림을 누르면 크게 볼 수 있습니다
증류
그림을 누르면 크게 볼 수 있습니다
※ 크리켓의 전통주는 모두 이 길을 지나 이 자리에 왔습니다.
About
크리켓 서울이 일하는 방식
One Menu, Every Korea

크리켓 서울의 메뉴는 한국의 모든 면에서 영감을 얻습니다. 음식 문화, 도시와 시골의 대비, 뚜렷한 사계절, 그리고 한국만의 감성. 이 요소들을 크리켓의 시선으로 풀어 동시대의 칵테일로 옮깁니다.

Tap System

한국식 칵테일을 탭 시스템으로 제공해 가볍고 편하게 즐기도록 했습니다. 손님은 무알콜과 알콜 중에서 고를 수 있습니다.

Onggi & Bamboo Aging

옹기와 대나무에 숙성한 칵테일은 오크와 달리 더 부드럽고, 은은한 산미를 더합니다. 나무통이 아닌 한국의 그릇으로 시간을 담습니다.

Locally Sourced

음식과 칵테일을 오직 한국 현지 재료로만 만듭니다. 지역 자원을 산업 안에서 실제로 지속 가능하게 쓰는 방식을 믿습니다.

Sharing Project

크리켓 서울은 지역의 양조장과 장인, 예술가와 손잡고 그들의 술과 작업을 칵테일로 풀어냅니다. 크리켓에서 시작한 지역 막걸리 양조장과의 협업처럼, 재료와 장인정신과 현대의 바 문화를 잇는 새로운 방식을 이어갑니다. 목표는 하나입니다. 한국의 아름다움을 더 많은 사람과 나누는 것.

`).join(""); } /* ===== 전통주 도감 렌더 ===== */ let soolFilter="all"; const soolChips=document.getElementById("soolChips"); function renderSoolChips(){ soolChips.innerHTML=``+CATS.map(c=>``).join(""); soolChips.querySelectorAll(".chip").forEach(ch=>{ch.classList.toggle("on",ch.dataset.k===soolFilter);ch.onclick=()=>{soolFilter=ch.dataset.k;soolChips.querySelectorAll(".chip").forEach(x=>x.classList.toggle("on",x===ch));renderSool();};}); } function siteLink(id){ const u=SITES[id]; if(!u) return ""; return `${esc(t('site.official'))} ↗`; } /* 양조장 공식 사이트. 검색으로 찾은 뒤 실제로 열어 회사명·주소·제품을 확인한 것만 넣는다. 확인 못 한 곳은 비워둔다 (틀린 링크는 없느니만 못함) */ const SITES={ boksundoga:"https://boksoon.com/", sucre:"https://jubangjangbrewery.com/", fogmag:"https://dalseong.co/", "ellyeop-takju":"http://www.ellyeoppyunjoo.com/", "ellyeop-cheongju":"http://www.ellyeoppyunjoo.com/", ihwaju:"http://sool.ksdb.co.kr/product/product_010100.asp", "inner-nectar":"http://www.bewaterbrew.com/", "inner-flow":"http://www.bewaterbrew.com/", "inner-calm":"http://www.bewaterbrew.com/", pungjeong:"https://hwayang.co/", hwajeonilchwi:"https://hwajeonilchwi.com/", "gyeongseong-gwahaju":"https://soolawon.co.kr/", "daetong-daeip":"http://chusungju.co.kr/", "sahwa-yuja":"https://sahwa.co.kr/", "omirose-premier":"https://omynara.com/", "omirose-yeon":"https://omynara.com/", "omirose-gyeol":"https://omynara.com/", "gowoon-oak":"https://omynara.com/", "gowoon-baekja":"https://omynara.com/", "kiwi-sool":"https://sooldogajeju.com/", moonbaesool:"https://www.moonbaesool.co.kr/", ryu24:"https://ryu-distillery.com/", damsol:"https://www.solsongju.com/", "hwayo-xp":"https://hwayo.com/", soorok:"https://danongbio.co.kr/", "kione-eagle":"https://threesocieties.co.kr/", "kione-tiger":"https://threesocieties.co.kr/", "kione-unicorn":"https://threesocieties.co.kr/", "kione-signature":"https://threesocieties.co.kr/", "kione-batch8":"https://threesocieties.co.kr/", "kione-edward":"https://threesocieties.co.kr/", "ggeek-pale":"https://www.ggeekbeer.com/", "ggeek-porter":"https://www.ggeekbeer.com/", chusa40:"https://xn--vf4b19u.com/", chusa50:"https://xn--vf4b19u.com/", mongro:"https://xn--vf4b19u.com/" }; function bBody(b){ const r=rzOf(b.id); if(!r) return `
${esc(b.desc)}${siteLink(b.id)}
`; let h=`
`; if(r.oneLine) h+=`
“${esc(r.oneLine)}”
`; if(r.taste) h+=`
${esc(lbl('taste'))}${esc(r.taste)}
`; if(r.feature) h+=`
${esc(lbl('feature'))}${esc(r.feature)}
`; if(r.history) h+=`
${esc(lbl('history'))}${esc(r.history)}
`; h+=siteLink(b.id); return h+`
`; } function renderSool(){ const host=document.getElementById("soolList"); const cats=CATS.filter(c=>soolFilter==="all"||c.k===soolFilter); host.innerHTML=cats.map(c=>{ const list=BOTTLES.filter(b=>b.cat===c.k); return `
${esc(t('cat.'+c.k+'.label'))} ${list.length}
${esc(t('cat.'+c.k+'.desc'))}
${list.map(b=>{const rk=(RES.ko||{})[b.id];return `
${esc(b.kr)}
${esc(b.name)}
${b.abv}%${priceStr(b)}
${b.region?`${esc(regName(b.region))}`:`${esc(fl('unknown'))}`}${b.flag?`${esc(fl('verify'))}`:''}${rk&&rk.conf==='low'?`${esc(fl('low'))}`:''}
${bBody(b)}
`;}).join("")}
`; }).join(""); } renderSool(); /* ===== 도별 인터랙티브 지도 ===== */ const SVGNS="http://www.w3.org/2000/svg"; // 도시(region) → 시도 코드 const PROV_OF={seoul:'11',incheon:'23',yangpyeong:'31',hwaseong:'31',yongin:'31',yeoju:'31',gimpo:'31',guri:'31',namyangju:'31',hoengseong:'32',chuncheon:'32',cheongju:'33',chungju:'33',yeongdong:'33',gongju:'34',yesan:'34',daejeon:'25',daegu:'22',andong:'37',sangju:'37',mungyeong:'37',gimhae:'38',hamyang:'38',changwon:'38',sacheon:'38',ulsan:'26',jeonju:'35',sunchang:'35',gochang:'35',damyang:'36',naju:'36',jeju:'39',goyang:'31'}; function cityXY(la,lo){const p=MAPDATA.proj;return [(lo*p.cosLat-p.minX)*p.S+p.pad,(-la-p.minY)*p.S+p.pad];} let activeProv=null, zoomed=false, vbAnim=null; let VB={x:0,y:0,w:0,h:0}; const BACKTXT={ko:"← 전체 지도",en:"← Whole map",zh:"← 全国地图",ja:"← 全体マップ"}; function el(tag,attrs){const e=document.createElementNS(SVGNS,tag);for(const k in attrs)e.setAttribute(k,attrs[k]);return e;} function setVB(x,y,w,h){VB={x,y,w,h};document.getElementById("mapsvg").setAttribute("viewBox",x.toFixed(1)+" "+y.toFixed(1)+" "+w.toFixed(1)+" "+h.toFixed(1));} function animVB(tx,ty,tw,th,dur,done){ const s={...VB},t0=performance.now(); if(vbAnim)cancelAnimationFrame(vbAnim); const ease=k=>k<.5?4*k*k*k:1-Math.pow(-2*k+2,3)/2; (function step(now){ const k=Math.min(1,(now-t0)/dur),e=ease(k); setVB(s.x+(tx-s.x)*e,s.y+(ty-s.y)*e,s.w+(tw-s.w)*e,s.h+(th-s.h)*e); scaleOverlay(); if(k<1)vbAnim=requestAnimationFrame(step);else{vbAnim=null;if(done)done();} })(performance.now()); } // 줌 배율에 맞춰 글자·점·선 크기를 화면상 일정하게 유지 function scaleOverlay(){ const s=VB.w/MAPDATA.vbW; document.querySelectorAll("#mapMuni .muni").forEach(p=>{p.setAttribute("stroke-dasharray",(3.2*s).toFixed(2)+" "+(2.4*s).toFixed(2));}); document.querySelectorAll("#mapDyn .mdot").forEach(d=>d.setAttribute("r",(4.6*s).toFixed(2))); document.querySelectorAll("#mapDyn .mhit").forEach(d=>d.setAttribute("r",(30*s).toFixed(2))); document.querySelectorAll("#mapDyn .mdot-label").forEach(t=>t.setAttribute("font-size",(9*s).toFixed(2))); document.querySelectorAll("#mapDyn .prov-label").forEach(t=>t.setAttribute("font-size",(16*s).toFixed(2))); } function buildMap(){ const svg=document.getElementById("mapsvg"); svg.setAttribute("preserveAspectRatio","xMidYMid meet"); setVB(0,0,MAPDATA.vbW,MAPDATA.vbH); const provCount={};BOTTLES.forEach(b=>{if(b.region&&PROV_OF[b.region])provCount[PROV_OF[b.region]]=(provCount[PROV_OF[b.region]]||0)+1;}); svg.innerHTML=""; // 작은 광역시는 도에 가려지지 않게 나중에 그린다 const METRO=["11","21","22","23","24","25","26","29"]; const ordered=[...MAPDATA.provinces].sort((a,b)=>(METRO.indexOf(a.code)>=0?1:0)-(METRO.indexOf(b.code)>=0?1:0)); ordered.forEach(p=>{ const path=el("path",{class:"prov"+(provCount[p.code]?" has":"")+(METRO.indexOf(p.code)>=0?" metro":""),id:"prov-"+p.code,d:p.d}); path.addEventListener("click",e=>{e.stopPropagation();activateProv(p.code);}); svg.appendChild(path); }); svg.appendChild(el("g",{id:"mapMuni"})); // 시군구 점선 svg.appendChild(el("g",{id:"mapDyn"})); // 라벨+양조지 점 } function activateProv(code){ activeProv=code;zoomed=true; const svg=document.getElementById("mapsvg"); [...svg.querySelectorAll(".prov")].forEach(pp=>{pp.classList.toggle("active",pp.id==="prov-"+code);pp.classList.toggle("dim",pp.id!=="prov-"+code);}); const activeEl=document.getElementById("prov-"+code); const muni=document.getElementById("mapMuni"),dyn=document.getElementById("mapDyn"); svg.insertBefore(activeEl,muni); // 시군구 경계(점선) muni.innerHTML=""; ((window.MAPMUNI||{})[code]||[]).forEach(m=>muni.appendChild(el("path",{class:"muni",d:m.d}))); // 실제 화면 확대: viewBox를 그 도의 영역으로 const bb=activeEl.getBBox(); const aspect=MAPDATA.vbW/MAPDATA.vbH; let w=bb.width,h=bb.height; if(w/hp.code===code); dyn.innerHTML=""; const label=el("text",{class:"prov-label",x:cx,y:bb.y-bb.height*0.04,"text-anchor":"middle"}); label.textContent=provName(prov.code,prov.kr);dyn.appendChild(label); const cities=Object.keys(PROV_OF).filter(k=>PROV_OF[k]===code); cities.forEach((k,i)=>{ const cnt=BOTTLES.filter(b=>b.region===k).length; if(!cnt) return; const[x,y]=cityXY(REG[k].la,REG[k].lo); const pick=e=>{e.stopPropagation();selectCity(k);}; // 실제로 눌리는 영역 (투명, 점보다 훨씬 크게) const hit=el("circle",{class:"mhit",cx:x,cy:y-3,r:30,fill:"rgba(0,0,0,0)"}); hit.dataset.k=k; hit.addEventListener("click",pick); const dot=el("circle",{class:"mdot",cx:x,cy:y,r:4.6,style:"animation-delay:"+(i*50)+"ms"}); dot.dataset.k=k; dot.addEventListener("click",pick); const tx=el("text",{class:"mdot-label",x:x,y:y-7,"text-anchor":"middle",style:"animation-delay:"+(i*50)+"ms"}); tx.textContent=cityName(k)+" ·"+cnt; tx.dataset.k=k; tx.addEventListener("click",pick); dyn.appendChild(hit);dyn.appendChild(dot);dyn.appendChild(tx); }); scaleOverlay(); const bk=document.getElementById("mapBack"); bk.textContent=BACKTXT[LANG]||BACKTXT.ko;bk.classList.add("show"); } function zoomOutMap(){ zoomed=false;activeProv=null; const svg=document.getElementById("mapsvg"); [...svg.querySelectorAll(".prov")].forEach(pp=>pp.classList.remove("active","dim")); document.getElementById("mapMuni").innerHTML=""; document.getElementById("mapDyn").innerHTML=""; document.getElementById("mapBack").classList.remove("show"); animVB(0,0,MAPDATA.vbW,MAPDATA.vbH,700); const panel=document.getElementById("mapPanel"); panel.innerHTML=`
${esc(t('map.panel0.t'))}
${esc(t('map.panel0.b'))}
`; } function selectCity(k){ const list=BOTTLES.filter(b=>b.region===k); const panel=document.getElementById("mapPanel"); panel.innerHTML=`
${esc(regName(k))} · ${list.length}${esc(t('map.count'))} ${esc(t('map.here'))}
`; document.querySelectorAll(".mdot").forEach(d=>d.classList.toggle("sel", d.dataset.k===k)); // 아래 목록으로 부드럽게 이동 const y=panel.getBoundingClientRect().top+window.scrollY-navH()-12; window.scrollTo({top:Math.max(0,y),behavior:"smooth"}); } /* 공정 단계 버튼 → 그림 펼치기 (한 번에 하나) */ document.querySelectorAll(".stepb").forEach(b=>b.addEventListener("click",()=>{ const st=b.closest(".step"), was=st.classList.contains("open"); document.querySelectorAll(".step.open").forEach(o=>{if(o!==st)o.classList.remove("open");}); st.classList.toggle("open",!was); if(!was){ const im=st.querySelector("img"); if(im&&!im.src&&im.dataset.src)im.src=im.dataset.src; setTimeout(()=>{const r=st.getBoundingClientRect(); if(r.topim.addEventListener("click",()=>{ lbImg.src=im.src||im.dataset.src; lb.classList.add("on");})); lb.addEventListener("click",closeLb); document.addEventListener("keydown",e=>{if(e.key==="Escape")closeLb();}); } buildMap(); document.getElementById("mapBack").addEventListener("click",e=>{e.stopPropagation();zoomOutMap();}); function selectRegion(k){ // 도감/칵테일에서 지도로 올 때: 해당 도 활성 + 도시 선택 const code=PROV_OF[k]; if(code) activateProv(code); selectCity(k); document.getElementById("mapPanel").scrollIntoView({behavior:"smooth",block:"nearest"}); } /* ===== 한 페이지 스크롤 + 카테고리 바로가기 ===== */ const secs=[...document.querySelectorAll("section[data-p]")]; const navb=[...document.querySelectorAll(".nav-b")]; function navH(){const n=document.querySelector("nav");return n?n.offsetHeight:0;} function jumpTo(p){ const s=document.querySelector('section[data-p="'+p+'"]');if(!s)return; const y=s.getBoundingClientRect().top+window.scrollY-navH()-6; window.scrollTo({top:Math.max(0,y),behavior:"smooth"}); } function show(p){jumpTo(p);} // 기존 호출 호환 navb.forEach(b=>b.onclick=()=>jumpTo(b.dataset.t)); const navin=document.getElementById("nav"), navwrap=document.getElementById("navwrap"); function navFade(){ if(!navin||!navwrap)return; const over=navin.scrollWidth-navin.clientWidth; navwrap.classList.toggle("more", over>2 && navin.scrollLeftnr.right-14) navin.scrollLeft+=(br.right-nr.right+14); } let curNav=null; function spyNav(){ const line=navH()+70;let cur=secs[0]; for(const s of secs){if(s.getBoundingClientRect().top<=line)cur=s;} navb.forEach(b=>b.classList.toggle("on",b.dataset.t===cur.dataset.p)); if(curNav!==cur.dataset.p){curNav=cur.dataset.p;navReveal(navb.find(b=>b.dataset.t===curNav));} navFade(); } window.addEventListener("scroll",spyNav,{passive:true}); window.addEventListener("resize",()=>{navFade();},{passive:true}); if(navin)navin.addEventListener("scroll",navFade,{passive:true}); function gotoMap(region){jumpTo("map");setTimeout(()=>selectRegion(region),450);} function gotoBottle(id){ if(!byId[id])return; if(soolFilter!=="all"){soolFilter="all";renderSoolChips();renderSool();applyReveal();} setTimeout(()=>{const e=document.getElementById("b-"+id);if(!e)return; e.classList.add("in","open"); const y=e.getBoundingClientRect().top+window.scrollY-navH()-40; window.scrollTo({top:Math.max(0,y),behavior:"smooth"}); e.animate([{background:"rgba(164,133,79,.28)"},{background:"transparent"}],{duration:1500});},60); } function gotoCat(k){soolFilter=k;renderSoolChips();renderSool();applyReveal();jumpTo("sool");} /* ===== 귀뚜라미 사운드 (랜덤 크로스페이드 루프) ===== */ const CRICKET=["cricket1.mp3","cricket2.mp3","cricket3.mp3","cricket4.mp3"]; const VOL=0.3; let audioOn=false, muted=false, lastIdx=-1; const vA=new Audio(), vB=new Audio(); [vA,vB].forEach(a=>{a.preload="auto";a.volume=0;}); let cur=vA, nxt=vB; function pickSrc(){let i;do{i=Math.floor(Math.random()*CRICKET.length);}while(i===lastIdx&&CRICKET.length>1);lastIdx=i;return CRICKET[i];} function fadeTo(a,target,ms,done){const start=a.volume,t0=performance.now(); function step(t){const k=Math.min(1,(t-t0)/ms);a.volume=Math.max(0,Math.min(1,start+(target-start)*k));if(k<1)requestAnimationFrame(step);else if(done)done();} requestAnimationFrame(step);} let swapping=false; function crossfade(){if(swapping||!audioOn)return;swapping=true; nxt.src=pickSrc();nxt.volume=0;nxt.currentTime=0;nxt.play().catch(()=>{}); fadeTo(nxt,muted?0:VOL,650); fadeTo(cur,0,650,()=>{try{cur.pause();}catch(_){}}); cur.ontimeupdate=null; const tmp=cur;cur=nxt;nxt=tmp; cur.ontimeupdate=onTU; setTimeout(()=>{swapping=false;},680);} function onTU(e){const a=e.target;if(a!==cur||swapping)return; const ov=Math.min(0.45,(a.duration||1.2)*0.4); if(a.duration && a.currentTime>=a.duration-ov) crossfade();} function startCricket(){if(audioOn)return;audioOn=true; cur.src=pickSrc();cur.volume=0;cur.ontimeupdate=onTU; cur.play().then(()=>fadeTo(cur,muted?0:VOL,900)).catch(()=>{}); soundToggle.classList.add("show");} // 안전장치: 혹시 둘 다 멈추면 즉시 재시작 (연속 재생 보장) setInterval(()=>{if(audioOn&&!muted&&cur.paused&&nxt.paused){swapping=false;cur.src=pickSrc();cur.volume=0;cur.ontimeupdate=onTU;cur.play().then(()=>fadeTo(cur,VOL,400)).catch(()=>{});}},2500); [vA,vB].forEach(a=>a.addEventListener("ended",()=>{if(audioOn&&!swapping&&a===cur)crossfade();})); const soundToggle=document.getElementById("soundToggle"); soundToggle.onclick=()=>{muted=!muted;soundToggle.textContent=muted?"🔇":"🔊"; if(muted){[vA,vB].forEach(a=>fadeTo(a,0,300));}else{if(!audioOn)startCricket();else fadeTo(cur,VOL,300);}}; /* ===== 웰컴 스플래시 입장 ===== */ const splash=document.getElementById("splash"); function enter(){splash.classList.add("gone");startCricket();document.getElementById("langToggle").classList.add("show");setTimeout(()=>{try{splash.remove();}catch(_){}} ,1000);} document.getElementById("enterBtn").addEventListener("click",e=>{e.stopPropagation();enter();}); splash.addEventListener("click",enter); /* ===== 스크롤 리빌 애니메이션 ===== */ const REVEAL_SEL=[".cover .philo",".sec-h",".step",".hownote",".unit",".item-c",".b-c",".catblock",".catlabel",".flight",".gcard",".about-block",".mapwrap",".maphint",".mappanel",".primer",".chips"]; const io=new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting){e.target.classList.add("in");io.unobserve(e.target);}}),{threshold:0.05,rootMargin:"0px 0px -30px 0px"}); function applyReveal(){ if(!("IntersectionObserver" in window)){document.querySelectorAll(".reveal").forEach(e=>e.classList.add("in"));return;} REVEAL_SEL.forEach(sel=>document.querySelectorAll(sel).forEach(e=>{ if(e.classList.contains("in")||e.dataset.rv)return; // 이미 보였거나 이미 등록됨 e.dataset.rv="1"; e.classList.add("reveal"); const r=e.getBoundingClientRect(); if(r.top0)e.classList.add("in");else io.observe(e); })); } applyReveal(); /* ===== 스크롤 낮 → 밤 ===== */ // 배경: 낮 → 파스텔 살구 → 노을 주황 → 짙은 갈색 → 어둠 (스크롤 내내 서서히) const BG_STOPS=[ {p:0.00,c:{paper:"#e9e2d3",paper2:"#f0e9db",sage:"#d5ddc4",sage2:"#c7d1b3",line:"#38291a29"}}, {p:0.22,c:{paper:"#f3e0c6",paper2:"#f9ecd9",sage:"#dcdcba",sage2:"#cdcda8",line:"#42301c2b"}}, {p:0.42,c:{paper:"#f5cfa4",paper2:"#fbdcb8",sage:"#ddcda3",sage2:"#ccbb92",line:"#4a2f1a33"}}, {p:0.60,c:{paper:"#e8a874",paper2:"#f0b986",sage:"#d3b98d",sage2:"#c2a77c",line:"#4a2a1238"}}, {p:0.70,c:{paper:"#a45d2c",paper2:"#b56d36",sage:"#98784c",sage2:"#886940",line:"#ffe9d033"}}, {p:0.82,c:{paper:"#3f2413",paper2:"#4e2e19",sage:"#4a3a22",sage2:"#5b482d",line:"#ffe9d02e"}}, {p:1.00,c:{paper:"#080709",paper2:"#141118",sage:"#1e2a20",sage2:"#2c3a2e",line:"#e9e1d124"}} ]; // 밤하늘 별: 0.78 부터 서서히 나타남 const STAR_IN=0.72; // 글자: 밝은 배경용 / 어두운 배경용 두 벌만 두고 한 지점에서 0.55초로 부드럽게 반전 const TEXT_DAY ={ink:"#2b1a0a",ink2:"#4a3319",mut:"#5e401f",gold:"#7d4a15"}; const TEXT_NIGHT={ink:"#f6ecdc",ink2:"#dfd0b4",mut:"#bda684",gold:"#e8be74"}; /* 글자 반전 지점은 스크롤 위치가 아니라 "그 순간 배경의 밝기"로 자동 결정한다. 섹션을 옮기거나 새 섹션을 넣어도 항상 배경 반대색 글자가 나온다. */ function srgbL(v){v/=255;return v<=0.03928?v/12.92:Math.pow((v+0.055)/1.055,2.4);} function lumOf(css){const m=(css||"").match(/[\d.]+/g);if(!m||m.length<3)return 1; return 0.2126*srgbL(+m[0])+0.7152*srgbL(+m[1])+0.0722*srgbL(+m[2]);} const L_DARK=0.155, L_LIGHT=0.24; function hx(h){h=h.replace("#","");if(h.length===6)h+="ff"; return [parseInt(h.slice(0,2),16),parseInt(h.slice(2,4),16),parseInt(h.slice(4,6),16),parseInt(h.slice(6,8),16)/255];} function mixc(a,b,k){const A=hx(a),B=hx(b); return "rgba("+Math.round(A[0]+(B[0]-A[0])*k)+","+Math.round(A[1]+(B[1]-A[1])*k)+","+Math.round(A[2]+(B[2]-A[2])*k)+","+(A[3]+(B[3]-A[3])*k).toFixed(3)+")";} let nightK=-9, isNight=null, curPaper="#e9e2d3"; function updateDayNight(){ const max=Math.max(1,document.documentElement.scrollHeight-window.innerHeight); const p=Math.min(1,Math.max(0,window.scrollY/max)); const s=document.documentElement.style; // 배경: 구간별 보간으로 계속 서서히 변함 if(Math.abs(p-nightK)>=0.002){ nightK=p; let i=0; while(iBG_STOPS[i+1].p) i++; const a=BG_STOPS[i], b=BG_STOPS[i+1]; const k=Math.min(1,Math.max(0,(p-a.p)/(b.p-a.p))); for(const key in a.c) s.setProperty("--"+key, mixc(a.c[key], b.c[key], k)); curPaper=mixc(a.c.paper, b.c.paper, k); const stars=document.getElementById("stars"); if(stars){const o=Math.min(1,Math.max(0,(p-STAR_IN)/(1-STAR_IN))); stars.style.opacity=o.toFixed(3); stars.style.visibility=o>0.01?"visible":"hidden";} // 해는 위에서 천천히 지고, 달은 아래에서 떠오른다 const sun=document.getElementById("sun"), moon=document.getElementById("moon"); const sm=(v,a,b)=>Math.min(1,Math.max(0,(v-a)/(b-a))); if(sun){ sun.style.top=(6+p*118).toFixed(1)+"vh"; sun.style.opacity=(1-sm(p,0.26,0.52)).toFixed(3); } if(moon){ moon.style.top=(128-sm(p,0.46,1)*111).toFixed(1)+"vh"; moon.style.opacity=sm(p,0.50,0.74).toFixed(3); } } // 글자: 배경 밝기를 재서 자동 반전 (히스테리시스로 경계에서 깜빡이지 않게) const L=lumOf(curPaper); const want = isNight ? (L{e.innerHTML=t(e.dataset.i18n);}); navb.forEach(b=>{b.textContent=t("nav."+b.dataset.t);}); setTimeout(navFade,0); renderCocktails();renderFoods();renderSoolChips();renderSool(); if(activeProv){const a=activeProv;activeProv=null;activateProv(a);} else{const panel=document.getElementById("mapPanel"); panel.innerHTML=`
${esc(t('map.panel0.t'))}
${esc(t('map.panel0.b'))}
`;} document.querySelectorAll(".langbtn").forEach(x=>x.classList.toggle("on",x.dataset.l===LANG)); const bk=document.getElementById("mapBack"); if(bk)bk.textContent=BACKTXT[LANG]||BACKTXT.ko; applyReveal(); nightK=-1; updateDayNight(); } function setLang(l){LANG=l;applyLang();} document.querySelectorAll(".langbtn").forEach(b=>b.addEventListener("click",e=>{e.stopPropagation();setLang(b.dataset.l);document.getElementById("langPop").classList.remove("show");})); const langPop=document.getElementById("langPop"); document.getElementById("langToggle").onclick=e=>{e.stopPropagation();langPop.classList.toggle("show");}; document.addEventListener("click",()=>langPop.classList.remove("show")); applyLang();