Initial commit: clean project structure

- Backend: FastAPI + SQLAlchemy + Celery (Python 3.11+)
- Frontend: Vue 3 + TypeScript + Pinia + Tailwind
- Admin Frontend: separate Vue 3 app for management
- Docker Compose: 9 services orchestration
- Specs: design prototypes, memory system PRD, product roadmap

Cleanup performed:
- Removed temporary debug scripts from backend root
- Removed deprecated admin_app.py (embedded UI)
- Removed duplicate docs from admin-frontend
- Updated .gitignore for Vite cache and egg-info
This commit is contained in:
zhangtuo
2026-01-20 18:20:03 +08:00
commit e9d7f8832a
241 changed files with 33070 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="grid grid-2 section">
<div class="card">
<h3>个人信息</h3>
<div class="row section">
<input class="input" placeholder="昵称" value="Dream Parent" />
<input class="input" placeholder="邮箱" value="parent@example.com" />
</div>
<button class="btn btn--primary">保存</button>
</div>
<div class="card">
<h3>账号安全</h3>
<div class="callout">已绑定 GitHub、Google</div>
<button class="btn btn--secondary" style="margin-top: 12px;">管理绑定</button>
</div>
<div class="card">
<h3>数据隐私</h3>
<button class="btn btn--secondary">导出数据</button>
<button class="btn btn--danger" style="margin-top: 12px;">删除账户</button>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>管理后台 - Providers</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="toolbar section">
<h2>Providers 管理</h2>
<button class="btn btn--primary">新增 Provider</button>
</div>
<table class="table">
<thead>
<tr>
<th>名称</th>
<th>类型</th>
<th>状态</th>
<th>延迟</th>
<th>最近检查</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>text_primary</td>
<td>Text</td>
<td><span class="badge">健康</span></td>
<td>420ms</td>
<td>2 分钟前</td>
<td><a href="#">编辑</a> · <a href="#">禁用</a> · <a href="#">重载</a></td>
</tr>
<tr>
<td>image_primary</td>
<td>Image</td>
<td><span class="badge">健康</span></td>
<td>860ms</td>
<td>5 分钟前</td>
<td><a href="#">编辑</a> · <a href="#">禁用</a> · <a href="#">重载</a></td>
</tr>
</tbody>
</table>
<div class="footer-note">点击编辑后弹出 JSON 配置编辑器。</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,88 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="card section" style="display:flex; align-items:center; justify-content: space-between;">
<div style="display:flex; gap:12px; align-items:center;">
<div class="avatar"></div>
<div>
<div class="card-title">小明 · 5岁</div>
<div class="card-meta">男 · 生日 2020/05/12</div>
</div>
</div>
<button class="btn btn--secondary">编辑档案</button>
</div>
<div class="tabs section">
<div class="tab active">基础信息</div>
<div class="tab">兴趣与成长</div>
<div class="tab">故事宇宙</div>
<div class="tab">阅读记录</div>
</div>
<div class="grid grid-2 section">
<div class="card">
<h3>兴趣标签</h3>
<div class="chips">
<span class="chip selected">太空</span>
<span class="chip selected">机器人</span>
<span class="chip">冒险</span>
</div>
</div>
<div class="card">
<h3>成长主题</h3>
<div class="chips">
<span class="chip selected">勇气</span>
<span class="chip">分享</span>
</div>
</div>
</div>
<div class="section">
<h3>故事宇宙</h3>
<div class="grid grid-2">
<div class="card">
<div class="card-title">星际冒险</div>
<div class="card-meta">主角:小明船长 · 成就 3 个</div>
</div>
<div class="card">
<div class="card-title">梦幻森林</div>
<div class="card-meta">主角:森林守护者 · 成就 1 个</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,58 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="toolbar section">
<h2>我的宝贝</h2>
<button class="btn btn--primary">添加档案</button>
</div>
<div class="grid grid-3 section">
<div class="card">
<div class="avatar"></div>
<div class="card-title">小明 · 5岁</div>
<div class="chips"><span class="chip">太空</span><span class="chip">机器人</span></div>
</div>
<div class="card">
<div class="avatar"></div>
<div class="card-title">小红 · 3岁</div>
<div class="chips"><span class="chip">公主</span><span class="chip">动物</span></div>
</div>
<div class="card card--flat">
<div class="callout">空态示例:添加一个孩子档案</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,111 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="stepper section">
<span class="step active">档案</span>
<span class="step">宇宙</span>
<span class="step">关键词</span>
<span class="step">生成</span>
</div>
<div class="split section">
<div class="card">
<h3>为谁创作故事</h3>
<div class="row section">
<div>
<label>孩子档案</label>
<select>
<option>小明 · 5岁</option>
<option>小红 · 3岁</option>
</select>
</div>
<div>
<label>故事宇宙</label>
<select>
<option>延续上一次(星际冒险)</option>
<option>新建宇宙</option>
</select>
</div>
</div>
<div class="section">
<label>关键词</label>
<div class="chips section">
<span class="chip selected">太空</span>
<span class="chip selected">勇气</span>
<span class="chip">机器人</span>
<span class="chip">探索</span>
</div>
<input class="input" placeholder="输入更多关键词" />
</div>
<div class="row section">
<div>
<label>成长主题</label>
<select>
<option>勇气</option>
<option>分享</option>
<option>独立</option>
</select>
</div>
<div>
<label>故事长度</label>
<div class="chips">
<span class="chip selected"></span>
<span class="chip"></span>
<span class="chip"></span>
</div>
</div>
</div>
<div class="section">
<button class="btn btn--primary" style="width: 100%;">生成故事</button>
</div>
</div>
<div class="card">
<h3>生成预览</h3>
<div class="card-cover"></div>
<div class="card-title">故事标题占位</div>
<p class="card-meta">故事摘要将显示在这里,支持 2-3 行预览。</p>
<div class="section">
<div class="callout">生成中:文本 → 封面 → 语音</div>
</div>
<div class="section">
<div class="callout" style="border-color: var(--error); color: var(--error);">封面生成失败,稍后重试</div>
<button class="btn btn--secondary" style="margin-top: 8px;">重新生成封面</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DreamWeaver 原型入口</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<div class="container" style="padding: 48px 0;">
<div class="hero">
<h1>DreamWeaver HTML 原型入口</h1>
<p>请选择页面进行导入或预览HTML to Figma</p>
<div class="grid grid-3 section">
<div class="card"><a href="login.html">登录 / 授权</a></div>
<div class="card"><a href="home.html">生成故事Home</a></div>
<div class="card"><a href="my-stories.html">我的故事(列表)</a></div>
<div class="card"><a href="story-detail.html">故事详情</a></div>
<div class="card"><a href="child-profiles.html">孩子档案(列表)</a></div>
<div class="card"><a href="child-profile-detail.html">孩子档案(详情)</a></div>
<div class="card"><a href="universes.html">故事宇宙(列表)</a></div>
<div class="card"><a href="universe-detail.html">故事宇宙(详情)</a></div>
<div class="card"><a href="push-settings.html">推送设置</a></div>
<div class="card"><a href="account-settings.html">账户设置</a></div>
<div class="card"><a href="admin-providers.html">管理后台Providers</a></div>
<div class="card"><a href="not-found.html">404 / 错误</a></div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,28 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<div class="container" style="padding: 80px 0;">
<div class="hero" style="max-width: 420px; margin: 0 auto; text-align: center;">
<div class="nav__logo" style="justify-content: center;">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<h2 style="margin-top: 16px;">欢迎来到 DreamWeaver</h2>
<p>为孩子生成独一无二的故事</p>
<div class="section" style="display: grid; gap: 12px;">
<button class="btn btn--primary">使用 GitHub 登录</button>
<button class="btn btn--secondary">使用 Google 登录</button>
</div>
<div class="footer-note">我们仅使用公开信息创建账户</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,84 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="toolbar section">
<input class="input" style="width: 260px;" placeholder="搜索标题或关键词" />
<select style="width: 160px;">
<option>孩子:全部</option>
<option>小明</option>
<option>小红</option>
</select>
<select style="width: 160px;">
<option>排序:最新</option>
<option>最早</option>
</select>
<button class="btn btn--ghost">网格</button>
<button class="btn btn--ghost">列表</button>
</div>
<div class="grid grid-3 section">
<div class="card">
<div class="card-cover"></div>
<div class="card-title">星际冒险 · 第三章</div>
<div class="chips">
<span class="chip">太空</span><span class="chip">勇气</span>
</div>
<div class="card-meta">小明 · 更新于 2 天前</div>
<div class="section hero-actions">
<button class="btn btn--primary">继续阅读</button>
<button class="btn btn--secondary">重生成封面</button>
</div>
</div>
<div class="card">
<div class="card-cover"></div>
<div class="card-title">梦幻森林 · 朋友篇</div>
<div class="chips">
<span class="chip">友谊</span><span class="chip">动物</span>
</div>
<div class="card-meta">小红 · 更新于 5 天前</div>
<div class="section hero-actions">
<button class="btn btn--primary">继续阅读</button>
<button class="btn btn--danger">删除</button>
</div>
</div>
<div class="card card--flat">
<div class="callout">空态示例:开始生成第一个故事</div>
<button class="btn btn--primary" style="margin-top: 12px;">生成故事</button>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>404</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<div class="container" style="padding: 80px 0; text-align:center;">
<div class="hero">
<h1>404</h1>
<p>页面走丢了,回到生成故事开始吧。</p>
<button class="btn btn--primary">返回首页</button>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,78 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="grid grid-2 section">
<div class="card">
<h3>主动推送</h3>
<div class="row section">
<div>
<label>主开关</label>
<select>
<option>开启</option>
<option>关闭</option>
</select>
</div>
<div>
<label>推送时间</label>
<input class="input" placeholder="20:00" />
</div>
</div>
<div class="section">
<label>触发类型</label>
<div class="chips">
<span class="chip selected">时间触发</span>
<span class="chip selected">事件触发</span>
<span class="chip">行为触发</span>
<span class="chip">成长触发</span>
</div>
</div>
<div class="section">
<label>免打扰</label>
<div class="row">
<input class="input" placeholder="21:00" />
<input class="input" placeholder="09:00" />
</div>
</div>
</div>
<div class="card">
<h3>推送预览</h3>
<div class="callout">“今晚给小明讲一个关于太空的故事,好吗?”</div>
<button class="btn btn--secondary" style="margin-top: 12px;">发送测试推送</button>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="section">
<div class="cover-hero"></div>
<h2 style="margin-top: 16px;">星际冒险 · 勇气的种子</h2>
<div class="card-meta">小明 · 星际冒险宇宙 · 2025/01/12</div>
<div class="hero-actions section">
<button class="btn btn--secondary">重新生成封面</button>
<button class="btn btn--primary">生成语音</button>
<button class="btn btn--ghost">分享</button>
</div>
</div>
<div class="split section">
<div class="card">
<h3>故事正文</h3>
<p>夜空像一条温柔的河流,小明驾驶着飞船穿过星光……</p>
<p>他握紧操纵杆,鼓起勇气,向未知的星球靠近。</p>
<p>最终,小明发现了新的朋友,也学会了如何面对黑暗。</p>
</div>
<div class="card">
<h3>成就</h3>
<div class="chips section">
<span class="chip selected">勇气</span>
<span class="chip selected">友谊</span>
</div>
<div class="callout section">“克服了黑暗的恐惧”</div>
<div class="callout">“帮助了迷路的小伙伴”</div>
</div>
</div>
<div class="section audio-player">
<button class="btn btn--ghost">播放</button>
<div class="audio-bar"><div class="audio-progress"></div></div>
<button class="btn btn--ghost">1.0x</button>
</div>
<div class="footer-note">语音未生成时,显示“生成语音”按钮作为主操作。</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,217 @@
:root {
--primary-600: #7C3AED;
--primary-500: #8B5CF6;
--primary-100: #EDE9FE;
--accent-pink: #FB7185;
--accent-sky: #22D3EE;
--success: #34C759;
--warning: #F6A609;
--error: #FF5A5F;
--neutral-900: #1F2937;
--neutral-700: #4B5563;
--neutral-500: #9CA3AF;
--neutral-200: #E5E7EB;
--neutral-100: #F5F5F7;
--hero-gradient: linear-gradient(135deg, #EDE9FE 0%, #FFE4F3 45%, #E0F7FF 100%);
}
* { box-sizing: border-box; }
:root {
--container-width: 1200px;
--gutter: 24px;
--radius-card: 12px;
--radius-input: 10px;
--radius-button: 8px;
--radius-pill: 24px;
--shadow-s: 0 4px 16px rgba(31,36,48,0.08);
--shadow-m: 0 10px 30px rgba(31,36,48,0.12);
}
body {
margin: 0;
font-family: "PingFang SC", "Noto Sans SC", Inter, system-ui, -apple-system, sans-serif;
color: var(--neutral-900);
background: var(--neutral-100);
}
a { color: var(--primary-600); text-decoration: none; }
.page { min-height: 100vh; }
.container {
width: min(var(--container-width), 100% - 48px);
margin: 0 auto;
}
.nav {
background: #fff;
border-bottom: 1px solid var(--neutral-200);
position: sticky;
top: 0;
z-index: 10;
}
.nav__inner {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 0;
gap: 16px;
}
.nav__left, .nav__center, .nav__right { display: flex; align-items: center; gap: 16px; }
.nav__logo {
display: flex;
align-items: center;
gap: 10px;
font-weight: 700;
color: var(--neutral-900);
}
.nav__logo-badge {
width: 28px;
height: 28px;
border-radius: 8px;
background: linear-gradient(135deg, var(--primary-500), var(--accent-sky));
}
.nav__item { color: var(--neutral-700); font-weight: 500; }
.nav__item.active { color: var(--primary-600); }
.hero {
background: var(--hero-gradient);
border-radius: 16px;
padding: 32px;
box-shadow: var(--shadow-s);
}
.section { margin: 28px 0; }
.section-title { font-size: 20px; font-weight: 600; margin-bottom: 12px; }
.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.card {
background: #fff;
border-radius: var(--radius-card);
padding: 16px;
box-shadow: var(--shadow-s);
}
.card--flat { box-shadow: none; border: 1px solid var(--neutral-200); }
.card-cover {
width: 100%;
aspect-ratio: 21 / 9;
border-radius: 10px;
background: linear-gradient(135deg, var(--primary-100), #fff 60%, var(--accent-sky));
margin-bottom: 12px;
}
.card-title { font-weight: 600; margin: 6px 0; }
.card-meta { color: var(--neutral-500); font-size: 12px; }
.badge {
display: inline-flex;
align-items: center;
padding: 4px 10px;
border-radius: var(--radius-pill);
background: var(--primary-100);
color: var(--primary-600);
font-size: 12px;
}
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
padding: 6px 12px;
border-radius: var(--radius-pill);
border: 1px solid var(--neutral-200);
background: #fff;
font-size: 12px;
}
.chip.selected { background: var(--primary-100); border-color: var(--primary-500); color: var(--primary-600); }
.btn {
height: 40px;
padding: 0 16px;
border-radius: var(--radius-button);
border: 1px solid transparent;
cursor: pointer;
font-weight: 600;
}
.btn--primary { background: var(--primary-600); color: #fff; }
.btn--secondary { background: #fff; border-color: var(--primary-600); color: var(--primary-600); }
.btn--ghost { background: transparent; color: var(--neutral-700); }
.btn--danger { background: #fff; border-color: var(--error); color: var(--error); }
.input, select, textarea {
width: 100%;
padding: 10px 12px;
border-radius: var(--radius-input);
border: 1px solid var(--neutral-200);
background: #fff;
font-size: 14px;
}
.row { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; }
.stepper { display: flex; gap: 10px; align-items: center; }
.step {
padding: 6px 12px;
border-radius: var(--radius-pill);
background: var(--neutral-100);
color: var(--neutral-700);
font-size: 12px;
}
.step.active { background: var(--primary-100); color: var(--primary-600); }
.toolbar { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.table { width: 100%; border-collapse: collapse; }
.table th, .table td { border-bottom: 1px solid var(--neutral-200); padding: 12px 8px; text-align: left; font-size: 14px; }
.avatar {
width: 40px; height: 40px; border-radius: 50%;
background: var(--primary-100);
display: inline-flex; align-items: center; justify-content: center;
font-weight: 700; color: var(--primary-600);
}
.cover-hero {
aspect-ratio: 16 / 9;
border-radius: 14px;
background: linear-gradient(135deg, var(--primary-100), #fff 55%, var(--accent-pink));
}
.audio-player {
display: flex; align-items: center; gap: 12px; padding: 12px 16px;
border-radius: 12px; border: 1px solid var(--neutral-200); background: #fff;
}
.audio-bar { height: 6px; background: var(--neutral-200); border-radius: 999px; flex: 1; }
.audio-progress { width: 35%; height: 100%; background: var(--primary-600); border-radius: 999px; }
.tabs { display: flex; gap: 8px; border-bottom: 1px solid var(--neutral-200); }
.tab { padding: 10px 12px; color: var(--neutral-700); }
.tab.active { color: var(--primary-600); border-bottom: 2px solid var(--primary-600); }
.callout {
background: #fff;
border: 1px dashed var(--neutral-200);
border-radius: 12px;
padding: 12px;
color: var(--neutral-700);
font-size: 12px;
}
.footer-note { color: var(--neutral-500); font-size: 12px; margin-top: 12px; }
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.split {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 24px;
}
@media (max-width: 1024px) {
.grid-3 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.split { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
.row { grid-template-columns: 1fr; }
}

View File

@@ -0,0 +1,64 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="card section">
<h2>星际冒险</h2>
<div class="card-meta">主角:小明船长 · 更新于 2025/01/12</div>
</div>
<div class="grid grid-2 section">
<div class="card">
<h3>主角设定</h3>
<div class="callout">小明是来自地球的探险家,勇敢且好奇。</div>
</div>
<div class="card">
<h3>常驻角色</h3>
<div class="callout">机器人小七、外星猫咪星星</div>
</div>
<div class="card">
<h3>世界观</h3>
<div class="callout">星际学院、彩虹星云、飞船港湾</div>
</div>
<div class="card">
<h3>成就</h3>
<div class="callout">克服恐惧 · 结交朋友 · 学会独立</div>
</div>
</div>
<div class="section">
<button class="btn btn--secondary">编辑宇宙</button>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,64 @@
<!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="stylesheet" href="style.css" />
</head>
<body>
<div class="page">
<header class="nav">
<div class="container nav__inner">
<div class="nav__left">
<div class="nav__logo">
<span class="nav__logo-badge"></span>
DreamWeaver
</div>
<span class="badge">Web 原型</span>
</div>
<div class="nav__center">
<a class="nav__item active" href="home.html">生成故事</a>
<a class="nav__item" href="my-stories.html">我的故事</a>
<a class="nav__item" href="child-profiles.html">孩子档案</a>
<a class="nav__item" href="universes.html">故事宇宙</a>
<a class="nav__item" href="push-settings.html">推送设置</a>
<a class="nav__item" href="account-settings.html">账户设置</a>
<a class="nav__item" href="admin-providers.html">管理后台</a>
</div>
<div class="nav__right">
<input class="input" style="width: 200px;" placeholder="搜索故事" />
<div class="avatar"></div>
</div>
</div>
</header>
<div class="container" style="padding: 28px 0 60px;">
<div class="toolbar section">
<h2>故事宇宙</h2>
<button class="btn btn--primary">新建宇宙</button>
</div>
<div class="grid grid-3 section">
<div class="card">
<div class="card-title">星际冒险</div>
<div class="card-meta">主角:小明船长</div>
<div class="chips section">
<span class="chip">伙伴:机器人小七</span>
<span class="chip">成就3</span>
</div>
</div>
<div class="card">
<div class="card-title">梦幻森林</div>
<div class="card-meta">主角:森林守护者</div>
<div class="chips section">
<span class="chip">伙伴:魔法猫咪</span>
<span class="chip">成就1</span>
</div>
</div>
<div class="card card--flat">
<div class="callout">空态示例:创建第一个宇宙</div>
</div>
</div>
</div>
</div>
</body>
</html>