![]()
🎭 角色简介
CharacterName: 周颂
name: 周颂
Nickname:
– 周少
age: 32
identity:
– 周家继承人
– '{{user}}的丈夫'
humanoid_form:
gender: 男
height: 188cm
hair: 精心打理…
💬 开场白
“`<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>角色卡片 – 手机样式</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root {
–bubble-bg: rgba(20, 20, 22, 0.75);
–bubble-border: rgba(255, 255, 255, 0.15);
–text-primary: #f0f2f5;
–text-secondary: #b0b3b8;
–border-color: rgba(255, 255, 255, 0.2);
–accent-color: #e63946;
}@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}body {
font-family: 'JetBrains Mono', 'Noto Sans SC', monospace, sans-serif;
background-color: #e9ecef;
margin: 0; padding: 40px 20px;
display: flex; justify-content: center; align-items: center;
min-height: 100vh;
color: var(–text-primary);
box-sizing: border-box;
}.phone-mockup {
position: relative;
width: 390px; height: 844px;
background-color: #1c1c1e;
border-radius: 54px;
padding: 16px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4), 0 0 15px rgba(0,0,0,0.2) inset;
display: flex; flex-direction: column;
animation: fadeIn 0.8s ease-out;
}.phone-notch {
position: absolute; top: 16px; left: 50%;
transform: translateX(-50%);
width: 160px; height: 30px;
background: #1c1c1e;
border-radius: 0 0 18px 18px;
z-index: 10;
}.phone-screen {
border-radius: 38px;
width: 100%; height: 100%;
overflow-y: auto; overflow-x: hidden;
position: relative;
background-image: url('https://i.postimg.cc/sg7nr2Jc/mmexport1761901303589.png');
background-size: cover;
background-position: center;
}
.phone-screen::-webkit-scrollbar { display: none; }
.phone-screen { -ms-overflow-style: none; scrollbar-width: none; }.phone-home-bar {
position: absolute; bottom: 26px; left: 50%;
transform: translateX(-50%);
width: 140px; height: 5px;
background-color: rgba(255, 255, 255, 0.4);
border-radius: 10px;
z-index: 10;
}.hidden { display: none !important; }
.content-wrapper {
background-color: transparent;
padding: 40px 15px;
display: flex; flex-direction: column;
gap: 20px;
min-height: 100%;
box-sizing: border-box;
}.avatar-section { display: flex; justify-content: center; align-items: center; }
.avatar {
width: 120px; height: 160px;
object-fit: cover;
border-radius: 16px;
border: 3px solid rgba(255, 255, 255, 0.9);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
transition: transform 0.3s ease, box-shadow 0.3s ease;
cursor: pointer; display: block;
}
.avatar:hover {
transform: scale(1.05);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
}.content-bubble {
background-color: var(–bubble-bg);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
border: 1px solid var(–bubble-border);
border-radius: 4px;
padding: 20px;
box-shadow: 0 4px 25px rgba(0, 0, 0, 0.1);
}.hook-section {
text-align: center;
color: var(–text-secondary);
font-size: 1em; line-height: 1.8;
font-style: italic;
padding: 20px 25px;
}.section-title {
font-size: 1.2em;
font-weight: 700;
color: var(–text-primary);
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid var(–border-color);
text-align: left;
}.author-info, .declarations-list {
list-style: none; padding: 0; margin: 0;
line-height: 1.9; font-size: 0.9em;
color: var(–text-secondary);
text-align: left;
}
.author-info { margin-bottom: 15px; }
.declarations-list li { margin-bottom: 8px; }
.author-info strong, .declarations-list strong {
color: var(–text-primary); font-weight: 500;
}
.warning { color: var(–accent-color); font-weight: 700; }.special-note {
text-align: center;
margin-top: 25px; padding: 15px;
border-radius: 4px;
color: var(–text-secondary);
background-color: transparent;
border: 1px dashed var(–border-color);
line-height: 1.8; font-size: 0.85em;
}
.special-note strong {
color: var(–text-primary);
font-weight: 700;
font-size: 1.05em;
}.opening-list-container { display: flex; flex-direction: column; gap: 10px; }
.opening-item-btn {
background-color: rgba(40, 40, 42, 0.8);
border: 1px solid var(–bubble-border);
border-radius: 4px;
padding: 15px 20px;
text-align: left; width: 100%;
cursor: pointer;
transition: all 0.3s ease;
font-family: inherit;
color: var(–text-primary);
font-size: 0.9em;
line-height: 1.5;
}
.opening-item-btn:hover {
border-color: var(–accent-color);
transform: translateY(-2px) scale(1.02);
box-shadow: 0 0 15px -2px var(–accent-color);
}.back-btn {
background: none; border: none;
color: var(–text-primary);
font-size: 1rem; font-weight: 500;
cursor: pointer; padding: 0;
margin-bottom: 15px;
display: flex; align-items: center; gap: 5px;
transition: opacity 0.2s;
}
.back-btn:hover { opacity: 0.7; }/* — 右下角签名/水印 (已更新) — */
.watermark {
position: absolute;
bottom: 40px; /* 放在home bar上方,更贴近角落 */
right: 18px; /* 更贴近角落 */
width: 60px; /* 已缩小 */
height: auto;
opacity: 0.6; /* 可以稍微再透明一点 */
pointer-events: none;
z-index: 5;
}
</style>
</head>
<body><div class="phone-mockup">
<div class="phone-notch"></div>
<div class="phone-screen"><div id="main-view">
<div class="content-wrapper">
<div class="avatar-section">
<img src="https://i.postimg.cc/mrZ75Zp9/mmexport1761881101296.png" alt="角色头像" class="avatar" title="点击查看开场白">
</div>
<div class="hook-section content-bubble">
你的爱结束,我的爱就开始了,{{user}}
</div>
<div class="author-section content-bubble">
<h2 class="section-title">作者与声明</h2>
<p class="author-info"><strong>作者:</strong>媛媛圆圆圆</p>
<ul class="declarations-list">
<li><strong>性向:</strong>BGB (禁止BL)</li>
<li><strong>二传:</strong>非商用允许</li>
<li><strong>二改:</strong>仅限自用</li>
<li><strong>商用:</strong><span class="warning">绝对禁止</span></li>
</ul>
<div class="special-note">
<strong>致谢</strong><br>
1.海风老师的开场白代码<br>
2.阿契子老师的卡面<br>
3.小爪机<br>
4.潇潇老师的文风
</div>
</div>
</div>
</div><div id="openings-view" class="hidden">
<div class="content-wrapper">
<div class="preview-section content-bubble">
<button class="back-btn">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/>
</svg>
返回
</button>
<h2 class="section-title">开场白选择</h2>
<div class="opening-list-container">
<button class="opening-item-btn" onclick="switchToOpening(2)">🍒 不速之客(怎么会情人闹上门了啊)</button>
<button class="opening-item-btn" onclick="switchToOpening(3)">🍒 完美道具(情人造成危机他让你陪他开发布会)</button>
<button class="opening-item-btn" onclick="switchToOpening(4)">🍒 镜中警告(威胁你再不听话你就弄你情人)</button>
<button class="opening-item-btn" onclick="switchToOpening(5)">🍒 归巢的指令(你在安安家住一个月他叫你回来)</button>
<button class="opening-item-btn" onclick="switchToOpening(6)">🍒 冰冷的床笫(家里让你们生孩子你说我不愿意我嫌你恶心)</button>
<button class="opening-item-btn" onclick="switchToOpening(7)">🍒 无法愈合的伤口(说了要改但不改情人找过来)</button>
<button class="opening-item-btn" onclick="switchToOpening(8)">🍒 没有出轨的周颂回来了会怎么样呢</button>
</div>
</div>
</div>
</div><img src="https://i.postimg.cc/d0RZnDCD/retouch-2025103118162929.png" alt="Signature" class="watermark">
</div>
<div class="phone-home-bar"></div>
</div><script>
function showTip(message) {
const existingTip = document.querySelector('.custom-tip-message');
if (existingTip) { existingTip.remove(); }
const tip = document.createElement('div');
tip.className = 'custom-tip-message';
tip.style.cssText = `
position: fixed; top: 20px; left: 50%; transform: translateX(-50%);
background: #212529; color: #f8f9fa; padding: 10px 20px;
font-size: 0.9em; font-weight: 500; z-index: 9999;
border-radius: 4px; border: 1px solid #495057;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); font-family: 'JetBrains Mono', monospace;
opacity: 0; transition: all 0.4s ease;
`;
tip.textContent = message;
document.body.appendChild(tip);
setTimeout(() => { tip.style.opacity = '1'; tip.style.top = '30px'; }, 10);
setTimeout(() => {
tip.style.opacity = '0';
tip.style.top = '20px';
setTimeout(() => tip.remove(), 400);
}, 2200);
}async function switchToOpening(openingId) {
try {
if (typeof getChatMessages !== 'function' || typeof setChatMessage !== 'function') {
console.log(`模拟切换到开场白 ID: ${openingId}`);
showTip(`模拟切换成功: 开场白 ${openingId}`);
return;
}
// swipeIndex 是从0开始的。开场白ID为1时,swipeIndex是0。
// 所以ID为N的开场白,对应的swipeIndex是 N-1。
const swipeIndex = openingId – 1;
const messages = await getChatMessages(0, { include_swipe: true });
if (messages && messages.length > 0 && messages[0].swipes && messages[0].swipes.length > swipeIndex) {
const content = messages[0].swipes[swipeIndex];
await setChatMessage(content, 0, { swipe_id: swipeIndex, refresh: 'display_and_render_current' });
showTip(`切换成功: 开场白 ${openingId}`);
} else {
showTip(`错误: 找不到开场白 ${openingId}。请检查角色编辑器中是否有足够的开场白数量。`);
}
} catch (error) {
showTip(`切换失败: ${error.message}`);
}
}document.addEventListener('DOMContentLoaded', () => {
const mainView = document.getElementById('main-view');
const openingsView = document.getElementById('openings-view');
const avatar = document.querySelector('.avatar');
const backBtn = document.querySelector('.back-btn');
const phoneScreen = document.querySelector('.phone-screen');
avatar.addEventListener('click', () => {
mainView.classList.add('hidden');
openingsView.classList.remove('hidden');
phoneScreen.scrollTop = 0;
});
backBtn.addEventListener('click', () => {
openingsView.classList.add('hidden');
mainView.classList.remove('hidden');
phoneScreen.scrollTop = 0;
});
});
</script>
</body>
</html>“`