152 lines
7.4 KiB
HTML
152 lines
7.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
<title>背景 · 宇森 Yusen</title>
|
|
<link rel="stylesheet" href="assets/fonts/yusen-fonts.css" />
|
|
<link rel="icon" type="image/png" sizes="48x48" href="assets/ui/logo_planet_48.png?v=20260723">
|
|
<link rel="stylesheet" href="assets/common.css" />
|
|
<style>
|
|
.bg-stack{max-width:1080px;width:100%;margin:0 auto;padding:36px 0;}
|
|
.bg-page{padding:36px 0;border-top:1px solid rgba(139,92,246,.16);}
|
|
.bg-page:first-child{border-top:none;padding-top:6px;}
|
|
.bg-page-head{text-align:center;margin-bottom:24px;}
|
|
.bg-page-title{position:relative;display:inline-block;font-family:"Noto Serif SC",serif;font-weight:800;font-size:40px;letter-spacing:7px;line-height:1.2;margin:0;padding-bottom:15px;
|
|
background:linear-gradient(120deg,#ffffff 0%,#f0d49a 46%,#c79bff 100%);
|
|
-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;}
|
|
.bg-page-title::after{content:'';position:absolute;left:50%;bottom:0;transform:translateX(-50%);width:70px;height:3px;border-radius:3px;
|
|
background:linear-gradient(90deg,transparent,var(--gold),var(--violet),transparent);}
|
|
|
|
.bg-frame{position:relative;min-height:160px;padding:32px 36px;border-radius:18px;overflow:hidden;
|
|
background:linear-gradient(160deg,rgba(139,92,246,.08),rgba(76,201,240,.04));
|
|
border:1px solid var(--card-bd);display:flex;align-items:center;justify-content:center;transition:.26s;}
|
|
.bg-frame::before{content:'';position:absolute;inset:0;border-radius:18px;padding:1px;
|
|
background:linear-gradient(135deg,rgba(139,92,246,.4),rgba(76,201,240,.18),transparent 60%);
|
|
-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none;}
|
|
.bg-frame:hover{border-color:rgba(139,92,246,.5);box-shadow:0 0 34px rgba(139,92,246,.18);}
|
|
.bg-frame-in{width:100%;font-size:16px;line-height:2;color:#e2e8f6;}
|
|
.bg-frame-in p{margin:0 0 16px;}
|
|
.bg-frame-in .bg-ci{display:flex;gap:12px;padding:10px 0;border-top:1px solid var(--card-bd);}
|
|
.bg-frame-in .bg-ci:first-child{border-top:none;}
|
|
.bg-frame-in .bg-ci b{color:#fff;flex:0 0 120px;}
|
|
.bg-frame-in .bg-ci span{color:var(--text-dim);}
|
|
.bg-frame-ph{font-family:"Noto Sans SC",sans-serif;font-size:14px;letter-spacing:4px;color:var(--text-dim);opacity:.65;}
|
|
|
|
/* 特色卡片网格 */
|
|
.sec-title{font-family:"ZCOOL QingKe HuangYou",sans-serif;font-size:28px;color:#fff;text-shadow:0 0 16px rgba(139,92,246,.5);margin-bottom:20px;text-align:center;}
|
|
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;width:min(1060px,100%);margin:0 auto 36px;}
|
|
.card{background:var(--card);border:1px solid var(--card-bd);border-radius:14px;padding:18px 20px;transition:.26s;min-height:132px;}
|
|
.card:hover{transform:translateY(-4px);border-color:var(--violet);box-shadow:var(--glow);background:rgba(139,92,246,.12);}
|
|
.card .ic{font-size:28px;margin-bottom:8px;filter:drop-shadow(0 0 6px rgba(199,125,255,.6));}
|
|
.card h3{font-size:17px;color:#fff;margin-bottom:7px;letter-spacing:1px;}
|
|
.card p{font-size:13px;color:var(--text-dim);line-height:1.6;}
|
|
|
|
/* 致玩家 */
|
|
.letter-wrap{max-width:680px;width:100%;overflow-y:auto;padding:10px 20px;margin:0 auto;}
|
|
.letter-wrap h2{font-family:"ZCOOL QingKe HuangYou",sans-serif;font-size:30px;letter-spacing:4px;color:#fff;text-shadow:0 0 18px rgba(139,92,246,.5);margin-bottom:6px;text-align:center;}
|
|
.letter-wrap .lt-body{font-size:15px;color:var(--text-dim);line-height:2.1;}
|
|
.letter-wrap .lt-body p{margin-bottom:16px;}
|
|
.letter-wrap .lt-body p:first-child{font-size:17px;color:#fff;font-weight:500;}
|
|
.letter-wrap .lt-body .hl{color:var(--gold);font-weight:500;}
|
|
.letter-wrap .lt-sign{text-align:right;margin-top:28px;font-size:14px;color:var(--magenta);font-style:italic;}
|
|
|
|
@media (max-width:900px){ .grid{grid-template-columns:repeat(2,1fr);} }
|
|
@media (max-width:768px){
|
|
.grid{grid-template-columns:repeat(2,1fr);gap:12px;}
|
|
.card{min-height:120px;padding:15px 16px;}
|
|
.bg-page-title{font-size:30px;letter-spacing:4px;}
|
|
.bg-frame{padding:24px 20px;min-height:130px;}
|
|
.bg-frame-in{font-size:14.5px;line-height:1.85;}
|
|
}
|
|
@media (max-width:480px){ .grid{grid-template-columns:1fr;} }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="app">
|
|
<header class="topbar">
|
|
<a href="index.html" class="logo"><span class="cn">宇森</span></a>
|
|
<nav class="nav">
|
|
<a href="announce.html">公告</a>
|
|
<a href="background.html">背景</a>
|
|
<a href="rules.html">规则</a>
|
|
<a href="codex.html">图鉴</a>
|
|
<a href="story.html">剧情</a>
|
|
<a href="forum.html" class="auth-only">论坛</a>
|
|
<a href="worlddata.html" class="auth-only">世界数据</a>
|
|
</nav>
|
|
<div class="spacer"></div>
|
|
<div class="user-box" id="userBox"></div>
|
|
</header>
|
|
|
|
<main class="page-content hide-scroll">
|
|
<div class="bg-stack" id="bgBody">
|
|
<!-- 由 JS 从后台 API.pages() 渲染 -->
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<script src="assets/game-api.js"></script>
|
|
<script src="assets/common.js"></script>
|
|
<script>
|
|
const BG_PANELS = [
|
|
{key:'features', title:'特色', en:'FEATURES'},
|
|
{key:'intro', title:'介绍', en:'INTRODUCTION'},
|
|
{key:'background', title:'背景', en:'WORLD LORE'},
|
|
{key:'instructions', title:'说明', en:'HOW TO PLAY'},
|
|
{key:'letter', title:'致玩家', en:'A LETTER TO PLAYERS'},
|
|
];
|
|
|
|
async function renderBackground(){
|
|
const box = document.getElementById('bgBody');
|
|
if(!box) return;
|
|
const pagesMap = {};
|
|
try{
|
|
const d = await API.pages();
|
|
(d && d.items || []).forEach(p=>{ if(p.key) pagesMap[p.key] = p; });
|
|
}catch(e){}
|
|
|
|
function featuresHTML(p){
|
|
const items = (p.items || []).map(it =>
|
|
`<div class="card"><div class="ic">${it.icon || ''}</div><h3>${it.title || ''}</h3><p>${it.desc || ''}</p></div>`
|
|
).join('');
|
|
return `<div class="sec-title">${p.title || '游戏特色'}</div><div class="grid">${items}</div>`;
|
|
}
|
|
|
|
function backgroundHTML(p){
|
|
const layers = (p.items || []).map((it, idx) =>
|
|
`<div class="layer l${idx + 1}"><div class="lt">${it.title || ''}</div><div class="ld">${it.desc || ''}</div><span class="star">${it.icon || '✦'}</span></div>`
|
|
).join('');
|
|
return `<div class="layers">${layers}</div><div class="bg-text"><h2>${p.title || '世界起源'}</h2>${p.body_html || ''}</div>`;
|
|
}
|
|
|
|
function letterHTML(p){
|
|
return `<div class="letter-wrap"><h2>${p.title || ''}</h2><div class="lt-body">${p.body_html || ''}</div><div class="lt-sign">—— 宇森开发组</div></div>`;
|
|
}
|
|
|
|
const frameInner = (pg)=>{
|
|
if(pg.key === 'features') return featuresHTML(pg);
|
|
if(pg.key === 'letter') return letterHTML(pg);
|
|
if(pg.body_html) return `<div class="bg-frame-in">${pg.body_html}</div>`;
|
|
if(pg.items && pg.items.length)
|
|
return `<div class="bg-frame-in">${pg.items.map(it=>`<div class="bg-ci"><b>${it.title||''}</b><span>${it.desc||''}</span></div>`).join('')}</div>`;
|
|
return `<div class="bg-frame-ph">内容筹备中 · 即将上线</div>`;
|
|
};
|
|
|
|
box.innerHTML = BG_PANELS.map(p=>{
|
|
const pg = pagesMap[p.key] || {};
|
|
const title = pg.title || p.title;
|
|
return `
|
|
<section class="bg-page">
|
|
<div class="bg-page-head">
|
|
<h2 class="bg-page-title">${title}</h2>
|
|
</div>
|
|
<div class="bg-frame">${frameInner(pg)}</div>
|
|
</section>`;
|
|
}).join('');
|
|
}
|
|
renderBackground();
|
|
</script>
|
|
</body>
|
|
</html>
|