chore: import MING theme source

This commit is contained in:
2026-09-23 09:29:09 +08:00
parent 63b5a4beba
commit d9946a3da4
53 changed files with 4476 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
/* MING 明命 — 自托管字体(v1.5.6 起替代 Google Fonts 外链)
来源:google/fonts(OFL 授权),经子集化(Big5 常用字 + 全形标点)与字重实例化 */
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/CormorantGaramond-400.woff2') format('woff2');
}
@font-face {
font-family: 'Cormorant Garamond';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/CormorantGaramond-500.woff2') format('woff2');
}
@font-face {
font-family: 'Noto Serif TC';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/NotoSerifTC-400.woff2') format('woff2');
}
@font-face {
font-family: 'Noto Serif TC';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('../fonts/NotoSerifTC-600.woff2') format('woff2');
}
@font-face {
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('../fonts/NotoSansTC-300.woff2') format('woff2');
}
@font-face {
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/NotoSansTC-400.woff2') format('woff2');
}
@font-face {
font-family: 'Noto Sans TC';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('../fonts/NotoSansTC-500.woff2') format('woff2');
}
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

+224
View File
@@ -0,0 +1,224 @@
/* ---------- 頂欄搜尋條 ---------- */
(function(){
var btn=document.querySelector('.hsearch');
var bar=document.getElementById('ming-searchbar');
if(!btn||!bar)return;
var input=bar.querySelector('input[type="search"]');
function openBar(){
document.body.classList.add('search-open');
btn.setAttribute('aria-expanded','true');
bar.setAttribute('aria-hidden','false');
if(input)setTimeout(function(){input.focus();},120);
}
function closeBar(){
document.body.classList.remove('search-open');
btn.setAttribute('aria-expanded','false');
bar.setAttribute('aria-hidden','true');
}
btn.addEventListener('click',function(){
document.body.classList.contains('search-open')?closeBar():openBar();
});
document.addEventListener('keydown',function(ev){
if(ev.key==='Escape'&&document.body.classList.contains('search-open'))closeBar();
});
document.addEventListener('click',function(ev){
if(!document.body.classList.contains('search-open'))return;
if(!ev.target.closest('.searchbar')&&!ev.target.closest('.hsearch'))closeBar();
});
})();
/* ---------- 行動版選單 ---------- */(function(){
var burger=document.querySelector('.hamburger');
var mnav=document.getElementById('ming-mnav');
if(!burger||!mnav)return;
function openMnav(){
document.body.classList.add('mnav-open');
burger.setAttribute('aria-expanded','true');
mnav.setAttribute('aria-hidden','false');
}
function closeMnav(){
document.body.classList.remove('mnav-open');
burger.setAttribute('aria-expanded','false');
mnav.setAttribute('aria-hidden','true');
}
burger.addEventListener('click',openMnav);
var closeBtn=mnav.querySelector('.mnav-close');
if(closeBtn)closeBtn.addEventListener('click',closeMnav);
mnav.querySelectorAll('.mnav-list a,.mnav-account').forEach(function(a){
a.addEventListener('click',closeMnav);
});
document.addEventListener('keydown',function(ev){
if(ev.key==='Escape'&&document.body.classList.contains('mnav-open'))closeMnav();
});
})();
/* ---------- 進場動畫 ---------- */
var io=new IntersectionObserver(function(entries){
entries.forEach(function(en){
if(en.isIntersecting){en.target.classList.add('in');io.unobserve(en.target);}
});
},{threshold:.15});
document.querySelectorAll('.reveal').forEach(function(el){io.observe(el)});
/* ---------- 新品許願池投票 ---------- */
(function(){
if(typeof MING_VOTE==='undefined')return;
document.addEventListener('click',function(ev){
var btn=ev.target.closest('.vote-btn');
if(!btn||btn.disabled)return;
var card=btn.closest('.vcard');
if(!card)return;
var goal=parseInt(card.getAttribute('data-goal'),10)||MING_VOTE.goal||100;
btn.disabled=true;btn.textContent='提交中…';
var fd=new FormData();
fd.append('action','ming_vote');
fd.append('nonce',MING_VOTE.nonce);
fd.append('campaign_id',card.getAttribute('data-cid'));
fd.append('product_id',card.getAttribute('data-id'));
fd.append('variation_id',card.getAttribute('data-vid')||'0');
fetch(MING_VOTE.ajaxurl,{method:'POST',credentials:'same-origin',body:fd})
.then(function(r){return r.json()})
.then(function(res){
if(res.success){
var n=res.data.count;
var vc=card.querySelector('.vcount b');if(vc)vc.textContent=n;
var bar=card.querySelector('.vote-bar i');
if(bar)bar.style.width=Math.min(100,Math.round(n/goal*100))+'%';
btn.textContent='已支持 ✓';btn.classList.add('voted');
var on=card.querySelector('.cdot.is-on');
if(on&&res.data.sku_count){var w=on.closest('.cdot-wrap');if(w){var em=w.querySelector('.cdot-n');if(em)em.textContent=res.data.sku_count;}}
}else if(res.data&&res.data.need_login){
window.location.href=res.data.login_url;
}else if(res.data&&res.data.already){
btn.textContent='已支持 ✓';btn.classList.add('voted');
var vc=card.querySelector('.vcount b');if(vc&&res.data.count)vc.textContent=res.data.count;
}else if(res.data&&res.data.message==='closed'){
btn.textContent='已截止';btn.classList.add('voted');
}else{
btn.disabled=false;btn.textContent='我想要這款';
}
})
.catch(function(){btn.disabled=false;btn.textContent='我想要這款';});
});
})();
/* ---------- 社群分享(複製連結 / 原生分享) ---------- */
(function(){
document.querySelectorAll('.ming-share').forEach(function(bar){
var title=bar.getAttribute('data-title')||document.title;
var text=bar.getAttribute('data-text')||title;
var url=bar.getAttribute('data-url')||location.href;
var copyBtn=bar.querySelector('.ming-share-btn.copy');
var nativeBtn=bar.querySelector('.ming-share-btn.native');
/* 原生分享需 HTTPS 安全環境 + 瀏覽器支援,否則不顯示(HTTP 下點了也沒反應) */
var canShare = window.isSecureContext && typeof navigator.share === 'function';
if(nativeBtn){
if(canShare){nativeBtn.hidden=false;}
nativeBtn.addEventListener('click',function(){
if(!canShare){return;}
navigator.share({title:title,text:text,url:url}).catch(function(err){
if(err&&err.name==='AbortError'){return;}
if(copyBtn){copyBtn.click();} /* 分享失敗退化為複製連結 */
});
});
}
if(copyBtn){
copyBtn.addEventListener('click',function(){
var done=function(){
var old=copyBtn.lastChild;
copyBtn.classList.add('copied');
var label=copyBtn.querySelector('.copy-label');
if(!label){
label=document.createElement('span');
label.className='copy-label';
copyBtn.appendChild(label);
}
label.textContent='已複製 ✓';
setTimeout(function(){copyBtn.classList.remove('copied');if(label)label.textContent='';},2000);
};
if(navigator.clipboard&&navigator.clipboard.writeText){
navigator.clipboard.writeText(url).then(done).catch(function(){fallback();});
}else{fallback();}
function fallback(){
var ta=document.createElement('textarea');
ta.value=url;ta.style.position='fixed';ta.style.opacity='0';
document.body.appendChild(ta);ta.select();
try{document.execCommand('copy');done();}catch(e){}
document.body.removeChild(ta);
}
});
}
});
})();
/* ---------- 商品頁色卡變體按鈕 ---------- */
(function(){
document.querySelectorAll('.ming-swatches').forEach(function(sw){
var attr=sw.getAttribute('data-attribute');
if(!attr)return;
var form=sw.closest('form.variations_form');
if(!form)return;
var select=form.querySelector('select[name="attribute_'+attr+'"]');
if(!select)return;
function sync(){
var opts=select.options;
sw.querySelectorAll('.ming-swatch').forEach(function(b){
var v=b.getAttribute('data-value');
var opt=null;
for(var i=0;i<opts.length;i++){if(opts[i].value===v){opt=opts[i];break;}}
b.classList.toggle('is-active',select.value===v);
b.classList.toggle('is-disabled',!opt||opt.disabled);
});
}
sw.addEventListener('click',function(ev){
var btn=ev.target.closest('.ming-swatch');
if(!btn||btn.classList.contains('is-disabled'))return;
select.value=btn.getAttribute('data-value');
select.dispatchEvent(new Event('change',{bubbles:true}));
sync();
});
select.addEventListener('change',sync);
if(window.MutationObserver){
var mo=new MutationObserver(sync);
mo.observe(select,{attributes:true,childList:true,subtree:true});
}
sync();
});
})();
/* ---------- 色卡點點:切換卡片商品圖 + 連結預選顏色 ---------- */
(function(){
document.addEventListener('click',function(e){
var dot=e.target.closest('.cdot');
if(!dot){return;}
e.preventDefault();
var card=dot.closest('.pcard, .vcard, li.product');
if(!card){return;}
var img=dot.getAttribute('data-img');
var pic=card.querySelector('.ph img, .woocommerce-loop-product__link img');
if(img&&pic){
pic.removeAttribute('srcset');
pic.removeAttribute('sizes');
if(pic.src!==img){
pic.style.opacity='0';
pic.addEventListener('load',function(){pic.style.opacity='1';},{once:true});
pic.src=img;
}
}
var link=dot.getAttribute('data-link');
if(link){
card.querySelectorAll('a.ph, a.more, a.woocommerce-loop-product__link').forEach(function(a){a.href=link;});
}
var wrap=dot.closest('.colors');
if(wrap){wrap.querySelectorAll('.cdot').forEach(function(d){d.classList.remove('is-on');});}
dot.classList.add('is-on');
var vid=dot.getAttribute('data-vid');
if(vid){card.setAttribute('data-vid',vid);}
});
})();