diff --git a/Eternal_AI_PRD_v1.docx b/Eternal_AI_PRD_v1.docx
new file mode 100644
index 0000000..5baf9e5
Binary files /dev/null and b/Eternal_AI_PRD_v1.docx differ
diff --git a/app.js b/app.js
index e4a2ea2..8d67d91 100644
--- a/app.js
+++ b/app.js
@@ -3,28 +3,27 @@
const landing = document.getElementById('landing');
const creator = document.getElementById('creator');
+ const auth = document.getElementById('auth');
+ const distill = document.getElementById('distill');
const form = document.getElementById('character-form');
const resultPanel = document.getElementById('result-panel');
const previewCode = document.querySelector('#preview-code code');
const systemPromptInput = document.getElementById('system-prompt');
+ const views = { landing, creator, auth, distill };
const steps = Array.from(document.querySelectorAll('.form-step'));
const dots = Array.from(document.querySelectorAll('.stepper__dot'));
let currentStep = 0;
let generatedSoul = '';
let generatedConfig = '';
let activePreview = 'soul';
+ let activeAuthTab = 'login';
function showView(name) {
- if (name === 'landing') {
- landing.classList.add('active');
- creator.classList.remove('active');
- window.scrollTo({ top: 0, behavior: 'smooth' });
- } else {
- landing.classList.remove('active');
- creator.classList.add('active');
- window.scrollTo({ top: 0, behavior: 'smooth' });
- }
+ Object.entries(views).forEach(([key, el]) => {
+ if (el) el.classList.toggle('active', key === name);
+ });
+ window.scrollTo({ top: 0, behavior: 'smooth' });
}
function updateStep(index) {
@@ -256,6 +255,29 @@ ${data.secrets || '无'}
});
}
+ function switchAuthTab(tab) {
+ activeAuthTab = tab;
+ document.querySelectorAll('.auth-tab').forEach((t) => {
+ t.classList.toggle('active', t.dataset.tab === tab);
+ });
+ document.querySelectorAll('.auth-form').forEach((f) => {
+ f.classList.toggle('active', f.dataset.form === tab);
+ });
+ }
+
+ function validatePasswordMatch(formEl) {
+ const pwd = formEl.querySelector('[name="password"]');
+ const confirm = formEl.querySelector('[name="confirmPassword"]');
+ if (!pwd || !confirm) return true;
+ if (pwd.value !== confirm.value) {
+ confirm.setCustomValidity('两次输入的密码不一致');
+ confirm.reportValidity();
+ return false;
+ }
+ confirm.setCustomValidity('');
+ return true;
+ }
+
// Event delegation
document.addEventListener('click', (e) => {
const target = e.target.closest('[data-action], [data-tab], [data-download]');
@@ -270,6 +292,19 @@ ${data.secrets || '无'}
return;
}
+ if (action === 'open-auth') {
+ e.preventDefault();
+ switchAuthTab('login');
+ showView('auth');
+ return;
+ }
+
+ if (action === 'open-distill') {
+ e.preventDefault();
+ showView('distill');
+ return;
+ }
+
if (action === 'back') {
e.preventDefault();
showView('landing');
@@ -306,9 +341,13 @@ ${data.secrets || '无'}
if (target.dataset.tab) {
e.preventDefault();
- activePreview = target.dataset.tab;
- updateTabs();
- renderPreview();
+ if (target.closest('.auth-tabs')) {
+ switchAuthTab(target.dataset.tab);
+ } else {
+ activePreview = target.dataset.tab;
+ updateTabs();
+ renderPreview();
+ }
return;
}
@@ -323,6 +362,19 @@ ${data.secrets || '无'}
}
});
+ // Auth form submissions
+ document.querySelectorAll('.auth-form').forEach((authForm) => {
+ authForm.addEventListener('submit', (e) => {
+ e.preventDefault();
+ if (!validatePasswordMatch(authForm)) return;
+ const formData = new FormData(authForm);
+ const data = Object.fromEntries(formData.entries());
+ const action = authForm.dataset.form === 'login' ? '登录' : '注册';
+ alert(`${action}成功:${data.account}`);
+ showView('landing');
+ });
+ });
+
// Update auto-generated system prompt as user types
form.addEventListener('input', () => {
updateSystemPromptPreview();
diff --git a/index.html b/index.html
index be78056..b5456b1 100644
--- a/index.html
+++ b/index.html
@@ -7,14 +7,14 @@
-
+
-
+
我的 [XXX ]
@@ -23,7 +23,7 @@
-
+
蒸馏前任
@@ -223,6 +223,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
没耐心?直接加微信定制沟通 →
+
+
+
什么是蒸馏前任?
+
把你们曾经的聊天记录、语音习惯、相处细节交给我们,技术团队会将其蒸馏成一个可对话的 AI 前任。ta 会记得你们的暗号、说话节奏,甚至那些只有你们懂的小情绪。
+
+
+
+
适合谁?
+
+ - 想好好告别,却还没说完话的人
+ - 希望把一段关系以安全方式封存的人
+ - 想借 AI 完成自我疗愈、练习表达的人
+
+
+
+
+
服务流程
+
+ - ① 下单付款
+ - ② 客服指导导出聊天记录
+ - ③ 上传至指定云盘
+ - ④ 技术人员处理蒸馏
+ - ⑤ 完成后获得专属二维码和头像
+
+
+
+
+ 标准版
+ ¥ 199
+ / 次
+
+
+
+
+
+
+
+
付款后请添加客服微信,我们将一对一指导你完成聊天记录导出与上传。
+
+
+
+
创作者可推广蒸馏前任服务获得分润,具体比例请在创作者管理中心配置。
+
+
+
diff --git a/styles.css b/styles.css
index e9a082a..4e17b40 100644
--- a/styles.css
+++ b/styles.css
@@ -258,6 +258,10 @@ body {
font-size: 13px;
}
+.btn--block {
+ width: 100%;
+}
+
.btn__arrow {
transition: transform var(--transition);
}
@@ -596,6 +600,175 @@ textarea.field__input--tall {
font-family: inherit;
}
+/* Auth view */
+.view--auth {
+ padding-top: 40vh;
+}
+
+.auth-tabs {
+ display: flex;
+ gap: 8px;
+ margin-bottom: 22px;
+ padding: 5px;
+ border-radius: var(--radius);
+ background: rgba(8, 9, 22, 0.55);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+}
+
+.auth-tab {
+ flex: 1;
+ padding: 10px;
+ border-radius: var(--radius-sm);
+ border: none;
+ background: transparent;
+ color: var(--text-muted);
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: color var(--transition), background var(--transition);
+}
+
+.auth-tab.active {
+ background: rgba(255, 255, 255, 0.1);
+ color: var(--text);
+}
+
+.auth-form {
+ display: none;
+ flex-direction: column;
+ flex: 1;
+ animation: fadeIn 0.35s ease;
+}
+
+.auth-form.active {
+ display: flex;
+}
+
+.auth-hint {
+ margin-top: 14px;
+ font-size: 12px;
+ color: var(--text-muted);
+ text-align: center;
+ line-height: 1.6;
+}
+
+/* Distill ex service page */
+.view--distill-page {
+ padding-top: 40vh;
+}
+
+.distill-page {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+}
+
+.distill-quick {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 12px 16px;
+ border-radius: var(--radius-sm);
+ background: linear-gradient(135deg, rgba(255, 160, 205, 0.22), rgba(160, 140, 255, 0.22));
+ border: 1px solid rgba(255, 160, 205, 0.35);
+ color: #ffe4f0;
+ font-size: 14px;
+ text-decoration: none;
+ text-align: center;
+ transition: transform var(--transition), box-shadow var(--transition);
+}
+
+.distill-quick:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 24px rgba(255, 130, 180, 0.2);
+}
+
+.distill-section {
+ padding: 18px;
+ border-radius: var(--radius);
+ background: rgba(8, 9, 22, 0.55);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ backdrop-filter: blur(14px);
+ -webkit-backdrop-filter: blur(14px);
+}
+
+.distill-section__title {
+ font-family: "Noto Serif SC", serif;
+ font-size: 17px;
+ font-weight: 600;
+ margin-bottom: 10px;
+ color: #fff;
+}
+
+.distill-section__text,
+.distill-list,
+.distill-steps {
+ font-size: 13px;
+ line-height: 1.75;
+ color: rgba(220, 225, 255, 0.85);
+}
+
+.distill-list,
+.distill-steps {
+ padding-left: 18px;
+ margin: 0;
+}
+
+.distill-list li {
+ margin-bottom: 6px;
+}
+
+.distill-steps li {
+ margin-bottom: 8px;
+}
+
+.distill-steps span {
+ color: var(--accent);
+ font-weight: 600;
+ margin-right: 4px;
+}
+
+.distill-price {
+ display: flex;
+ align-items: baseline;
+ justify-content: center;
+ gap: 8px;
+ padding: 18px;
+ border-radius: var(--radius);
+ background: rgba(8, 9, 22, 0.55);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+}
+
+.distill-price__label {
+ font-size: 14px;
+ color: var(--text-muted);
+}
+
+.distill-price__value {
+ font-size: 32px;
+ font-weight: 700;
+ color: #fff;
+}
+
+.distill-price__unit {
+ font-size: 13px;
+ color: var(--text-muted);
+}
+
+.distill-note,
+.distill-revenue {
+ font-size: 12px;
+ line-height: 1.7;
+ color: var(--text-muted);
+ text-align: center;
+}
+
+.distill-revenue {
+ padding: 12px;
+ border-radius: var(--radius-sm);
+ background: rgba(255, 255, 255, 0.04);
+}
+
/* Utility */
[hidden] {
display: none !important;