1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| {% raw %}
<div id="links-root"></div>
<style>
#links-root{--gap:16px;--radius:14px;--card-bg:rgba(255,255,255,0.7);--card-border:rgba(0,0,0,0.06);--card-hover-bg:rgba(0,0,0,0.04);--shadow:0 6px 18px rgba(0,0,0,0.06);margin:0 auto;max-width:1100px}
#links-root .links-category{margin:28px 0 22px}
#links-root .links-category h2{margin:0 0 12px;font-size:1.25rem;font-weight:700;line-height:1.2}
#links-root .links-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--gap)}
@media (max-width:768px){#links-root .links-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
#links-root .friend-card{display:block;text-decoration:none;color:inherit;border-radius:var(--radius);border:1px solid var(--card-border);background:var(--card-bg);padding:10px;transition:transform .15s ease,box-shadow .15s ease,background .2s}
#links-root .friend-card:hover{background:var(--card-hover-bg);transform:translateY(-2px);box-shadow:var(--shadow)}
#links-root .avatar-wrap{position:relative;border-radius:12px;overflow:hidden;aspect-ratio:1/1}
#links-root .avatar-wrap img{width:100%;height:100%;object-fit:cover;display:block}
#links-root .avatar-wrap .desc{position:absolute;left:0;right:0;bottom:0;transform:translateY(100%);padding:10px 12px;background:rgba(0,0,0,.72);color:#fff;font-size:.875rem;line-height:1.35;transition:transform .2s ease;pointer-events:none}
#links-root .avatar-wrap.reveal .desc{transform:translateY(0)}
#links-root .meta{padding-top:8px}
#links-root .name{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.post-title{display:none!important}
</style>
<script>
const LINKS_DATA=[{links_category:"Team",list:[{name:"su-team",link:"https://su-team.cn/",description:"不止是CTF!",avatar:"https://baozongwi.xyz/images/su_logo/SU4.jpg"}]},{links_category:"friends🤩",list:[{name:"fushuling",link:"https://fushuling.com/",description:"带我进SU的好哥哥",avatar:"https://fushuling-1309926051.cos.ap-shanghai.myqcloud.com/2022/08/QQ%E5%9B%BE%E7%89%8720220812001845.jpg"},{name:"Y4tacker",link:"https://y4tacker.github.io/",description:"Y4师傅诶~",avatar:"https://y4tacker.github.io/images/me.jpeg"}]}];
const escapeHTML=(s)=>String(s).replace(/[&<>"']/g,(m)=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m]));
function shuffle(arr){for(let i=arr.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[arr[i],arr[j]]=[arr[j],arr[i]]}return arr}
function createCard(item){
const a=document.createElement('a');
a.className='friend-card';
a.href=item.link;
a.target='_blank';
a.rel='noopener noreferrer';
a.setAttribute('aria-label',`${item.name} - ${item.description||''}`);
a.innerHTML=`
<div class="avatar-wrap">
<img src="${escapeHTML(item.avatar)}" alt="${escapeHTML(item.name)} avatar" loading="lazy" referrerpolicy="no-referrer">
<div class="desc" aria-hidden="true">${escapeHTML(item.description||'')}</div>
</div>
<div class="meta">
<div class="name" title="${escapeHTML(item.name)}">${escapeHTML(item.name)}</div>
</div>
`;
const wrap=a.querySelector('.avatar-wrap');
let shownOnce=false;
wrap.addEventListener('mouseenter',()=>{if(!shownOnce){wrap.classList.add('reveal');shownOnce=true}});
wrap.addEventListener('mouseleave',()=>{wrap.classList.remove('reveal');shownOnce=false});
wrap.addEventListener('touchstart',(e)=>{e.preventDefault();const willShow=!wrap.classList.contains('reveal');wrap.classList.toggle('reveal',willShow);shownOnce=willShow},{passive:false});
a.querySelector('img').addEventListener('error',(ev)=>{ev.target.src='data:image/svg+xml;utf8,'+encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400"><rect width="100%" height="100%" fill="#ddd"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#555" font-size="22">${escapeHTML(item.name)}</text></svg>`)});return a}
(function(){
const root=document.getElementById('links-root');if(!root)return;
LINKS_DATA.forEach(cat=>{
const section=document.createElement('section');
section.className='links-category';
section.innerHTML=`<h2>${escapeHTML(cat.links_category)}</h2><div class="links-grid"></div>`;
const grid=section.querySelector('.links-grid');
shuffle(cat.list.slice()).forEach(item=>grid.appendChild(createCard(item)));
root.appendChild(section);
});
})();
</script>
{% endraw %}
|