HTML
&lt;!DOCTYPE html&gt;



    <div class="container">
        <div class="header">
            <span class="glow-icon">🦋</span>
            <h1>· 魔物娘幻想 ·</h1>
            <div class="sub">角色引导配置</div>
        </div>
        <div class="intro-card">
            <div class="icon-badge">🌙</div>
            <p>欢迎来到 <strong>魔物娘世界</strong> · 在这片被古老魔法与神秘血脉笼罩的大陆上，你将化身为独一无二的魔物娘。编织你的身世与天赋，开启宿命交织的冒险。</p>
        </div>
        <div class="section-title"><span>✧</span> 角色档案</div>
        <div class="config-panel">
            <div class="form-grid">
                <div class="form-group">
                    <label>姓名</label>
                    <input type="text" id="char-name" placeholder="如：露娜·焰尾" value="">
                </div>
                <div class="form-group">
                    <label>性别</label>
                    <div class="radio-group">
                        <label><input type="radio" name="gender" value="女" checked> 女</label>
                        <label><input type="radio" name="gender" value="男"> 男</label>
                        <label><input type="radio" name="gender" value="其他"> 其他</label>
                    </div>
                </div>
                <div class="form-group">
                    <label>年龄</label>
                    <input type="text" id="char-age" placeholder="如：19 岁 (相当于人类)" value="">
                </div>
                <div class="form-group">
                    <label>种族 / 身份</label>
                    <input type="text" id="char-identity" placeholder="如：猫妖、龙裔、花灵" value="">
                </div>
                <div class="form-group full">
                    <label>外观描述</label>
                    <textarea id="char-appearance" placeholder="如：琥珀色竖瞳，蓬松的银灰色尾巴，发间生有淡紫色花朵，耳尖有绒毛……"></textarea>
                </div>
                <div class="form-group full">
                    <label>身世背景</label>
                    <textarea id="char-background" placeholder="如：诞生于月下楼兰的花海，体内流淌着古老的魅魔之血，曾独自穿越幽暗森林，只为寻回失落的记忆碎片……"></textarea>
                </div>
            </div>
            <div class="talent-section">
                <div class="talent-header">
                    <div class="label"><span>✦</span> 天赋词条 · 抽取你的宿命之力</div>
                    <button class="roll-btn" id="roll-talent-btn">
                        <svg viewBox="0 0 24 24"><path d="M12 3v12M9 12l3 3 3-3"/><path d="M5 12h14"/><circle cx="12" cy="18" r="2"/></svg>
                        抽取天赋
                    </button>
                </div>
                <div class="talent-grid" id="talent-grid">
                    <span class="talent-empty">点击「抽取天赋」获得随机词条，点击词条可选中保留</span>
                </div>
            </div>
            <div style="margin-top:1.4rem;">
                <div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:0.6rem;margin-bottom:0.3rem;">
                    <span style="font-size:0.8rem;color:#b090c8;letter-spacing:0.5px;opacity:0.6;">⋮ 实时预览 · 含已选天赋</span>
                </div>
                <div class="preview-box" id="preview-box"><span class="placeholder">填写上方信息并抽取天赋，角色卡将在此处生成...</span></div>
                <div class="copy-section">
                    <button class="copy-btn" id="copy-button">
                        <svg viewBox="0 0 24 24"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
                        复制角色卡
                    </button>
                </div>
            </div>
        </div>
    </div>
    <footer><a href="https://aitrader.wiki/zh/explore/installed/813e225e-2a1a-45bd-b441-f4741dff5418" target="_blank">本页面采用AI风月-创作大师生成</a></footer>
    <div class="toast" id="toast">
        <span class="toast-icon">✓</span>
        <div>信息已成功复制！</div>
        <button class="toast-close" id="toast-close">确定</button>
    </div>
    <script>
        (function() {
            const nameInput = document.getElementById('char-name');
            const genderRadios = document.querySelectorAll('input[name="gender"]');
            const ageInput = document.getElementById('char-age');
            const identityInput = document.getElementById('char-identity');
            const appearanceInput = document.getElementById('char-appearance');
            const backgroundInput = document.getElementById('char-background');
            const previewBox = document.getElementById('preview-box');
            const copyBtn = document.getElementById('copy-button');
            const toast = document.getElementById('toast');
            const toastClose = document.getElementById('toast-close');
            const talentGrid = document.getElementById('talent-grid');
            const rollBtn = document.getElementById('roll-talent-btn');

            let selectedTalents = [];

            const talentPool = [
                { text: '魅惑之瞳', quality: 'legendary' },
                { text: '龙鳞之躯', quality: 'legendary' },
                { text: '月影潜行', quality: 'legendary' },
                { text: '元素亲和', quality: 'epic' },
                { text: '治愈之触', quality: 'epic' },
                { text: '风之翼', quality: 'epic' },
                { text: '先祖低语', quality: 'epic' },
                { text: '火焰之尾', quality: 'rare' },
                { text: '冰晶之肤', quality: 'rare' },
                { text: '暗夜视觉', quality: 'rare' },
                { text: '毒棘之吻', quality: 'rare' },
                { text: '兽灵感应', quality: 'rare' },
                { text: '荆棘缠绕', quality: 'common' },
                { text: '水之呼吸', quality: 'common' },
                { text: '碎石之力', quality: 'common' },
                { text: '花香诱惑', quality: 'common' },
                { text: '绒毛软尾', quality: 'common' },
                { text: '轻灵跃动', quality: 'common' },
                { text: '回声定位', quality: 'common' },
                { text: '虹彩鳞片', quality: 'epic' },
                { text: '梦魇侵扰', quality: 'legendary' },
                { text: '妖精祝福', quality: 'epic' },
                { text: '石化之眼', quality: 'legendary' },
                { text: '绝缘之毛', quality: 'rare' },
            ];

            function getQualityLabel(q) {
                const map = { common: '普通', rare: '稀有', epic: '史诗', legendary: '传说' };
                return map[q] || '普通';
            }

            function shuffleArray(arr) {
                for (let i = arr.length - 1; i &gt; 0; i--) {
                    const j = Math.floor(Math.random() * (i + 1));
                    [arr[i], arr[j]] = [arr[j], arr[i]];
                }
                return arr;
            }

            function rollTalents() {
                const shuffled = shuffleArray([...talentPool]);
                const count = Math.min(5, shuffled.length);
                const picked = shuffled.slice(0, count);
                renderTalents(picked);
            }

            function renderTalents(talents) {
                talentGrid.innerHTML = '';
                if (!talents || talents.length === 0) {
                    talentGrid.innerHTML = '<span class="talent-empty">点击「抽取天赋」获得随机词条，点击词条可选中保留</span>';
                    return;
                }
                talents.forEach(t =&gt; {
                    const tag = document.createElement('span');
                    tag.className = `talent-tag ${t.quality}`;
                    if (selectedTalents.includes(t.text)) {
                        tag.classList.add('selected');
                    }
                    const dot = document.createElement('span');
                    dot.className = 'quality-dot';
                    tag.appendChild(dot);
                    const label = document.createTextNode(` ${t.text} [${getQualityLabel(t.quality)}]`);
                    tag.appendChild(label);
                    tag.dataset.text = t.text;
                    tag.dataset.quality = t.quality;
                    tag.addEventListener('click', function(e) {
                        const text = this.dataset.text;
                        const idx = selectedTalents.indexOf(text);
                        if (idx &gt; -1) {
                            selectedTalents.splice(idx, 1);
                            this.classList.remove('selected');
                        } else {
                            selectedTalents.push(text);
                            this.classList.add('selected');
                        }
                        updatePreview();
                    });
                    talentGrid.appendChild(tag);
                });
            }

            function getGender() {
                for (let r of genderRadios) {
                    if (r.checked) return r.value;
                }
                return '未设置';
            }

            function updatePreview() {
                const name = nameInput.value.trim() || '未命名';
                const gender = getGender();
                const age = ageInput.value.trim() || '未知';
                const identity = identityInput.value.trim() || '未定义';
                const appearance = appearanceInput.value.trim() || '未描述';
                const background = backgroundInput.value.trim() || '未撰写';
                let talentLine = '无';
                if (selectedTalents.length &gt; 0) {
                    talentLine = selectedTalents.join(' · ');
                }
                const lines = [
                    '【角色档案】',
                    '姓名：' + name,
                    '性别：' + gender,
                    '年龄：' + age,
                    '种族·身份：' + identity,
                    '外观：' + appearance,
                    '背景：' + background,
                    '─ 天赋 ─',
                    '『 ' + talentLine + ' 』'
                ];
                previewBox.textContent = lines.join('\n');
                if (!nameInput.value.trim() && !ageInput.value.trim() && !identityInput.value.trim() && !appearanceInput.value.trim() && !backgroundInput.value.trim() && selectedTalents.length === 0) {
                    previewBox.innerHTML = '<span class="placeholder">填写上方信息并抽取天赋，角色卡将在此处生成...</span>';
                }
            }

            function showToast() {
                toast.classList.add('show');
            }

            function hideToast() {
                toast.classList.remove('show');
            }

            function copyPreview() {
                let text = previewBox.textContent;
                if (previewBox.querySelector('.placeholder')) {
                    text = '请先填写角色信息并抽取天赋。';
                }
                try {
                    var textarea = document.createElement('textarea');
                    textarea.value = text;
                    textarea.style.position = 'fixed';
                    textarea.style.left = '-9999px';
                    textarea.style.top = '-9999px';
                    textarea.style.opacity = '0';
                    document.body.appendChild(textarea);
                    textarea.focus();
                    textarea.select();
                    var success = document.execCommand('copy');
                    document.body.removeChild(textarea);
                    if (success) {
                        showToast();
                    } else {
                        alert('复制失败，请手动复制。');
                    }
                } catch (e) {
                    alert('复制失败，请手动复制。');
                }
            }

            nameInput.addEventListener('input', updatePreview);
            ageInput.addEventListener('input', updatePreview);
            identityInput.addEventListener('input', updatePreview);
            appearanceInput.addEventListener('input', updatePreview);
            backgroundInput.addEventListener('input', updatePreview);
            for (let r of genderRadios) {
                r.addEventListener('change', updatePreview);
            }
            copyBtn.addEventListener('click', copyPreview);
            toastClose.addEventListener('click', hideToast);
            toast.addEventListener('click', function(e) {
                if (e.target === toast) hideToast();
            });

            rollBtn.addEventListener('click', function() {
                rollTalents();
                updatePreview();
            });

            updatePreview();
            rollTalents();
        })();
    </script>