初始化前端页面

This commit is contained in:
taiyi 2026-04-18 17:16:49 +08:00
commit 1c72434102
52 changed files with 996 additions and 0 deletions

View File

@ -0,0 +1 @@
Page({})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,50 @@
<view class="page">
<view class="topbar">
<view class="brand">
<view class="avatar-wrap"><image class="avatar" src="https://picsum.photos/260" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="icon-btn">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="heading">
<text class="title">成就墙</text>
<text class="subtitle">把你的每一次坚持都挂在墙上</text>
</view>
<view class="hero-card">
<view class="hero-glow"></view>
<view class="hero-row">
<view>
<text class="hero-num">14</text>
<text class="hero-label">已点亮勋章</text>
</view>
<view class="hero-badge">🏆</view>
</view>
</view>
<view class="grid">
<view class="item accent-tertiary">
<view class="item-icon">🎖</view>
<text class="item-title">坚持不懈</text>
<text class="item-sub">连续复习 7 天</text>
</view>
<view class="item accent-secondary">
<view class="item-icon">🔥</view>
<text class="item-title">连续打卡</text>
<text class="item-sub">持续 12 天</text>
</view>
<view class="item accent-primary">
<view class="item-icon">⚡</view>
<text class="item-title">速记达人</text>
<text class="item-sub">单次正确率 95%</text>
</view>
<view class="item accent-secondary">
<view class="item-icon">⭐</view>
<text class="item-title">全勤玩家</text>
<text class="item-sub">周目标全完成</text>
</view>
</view>
</scroll-view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.brand{display:flex;align-items:center;gap:18rpx}.avatar-wrap{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:48rpx 40rpx 32rpx;box-sizing:border-box}.heading{margin-bottom:28rpx}.title{display:block;font-size:52rpx;font-weight:800;line-height:1.1}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.hero-card{position:relative;overflow:hidden;padding:32rpx;border-radius:32rpx;background:rgba(29,32,37,.6);backdrop-filter:blur(24rpx);border:1rpx solid rgba(255,255,255,.08);box-shadow:0 20rpx 40rpx rgba(0,0,0,.08);margin-bottom:24rpx}.hero-glow{position:absolute;right:-40rpx;top:-40rpx;width:160rpx;height:160rpx;border-radius:9999rpx;background:rgba(255,64,129,.12);filter:blur(30rpx)}.hero-row{display:flex;justify-content:space-between;align-items:center;position:relative;z-index:1}.hero-num{display:block;font-size:72rpx;font-weight:800;color:#fff}.hero-label{display:block;margin-top:8rpx;font-size:24rpx;color:#aaabb0}.hero-badge{width:112rpx;height:112rpx;border-radius:9999rpx;background:linear-gradient(135deg,#ff4081,#00e5ff);display:flex;align-items:center;justify-content:center;font-size:44rpx;box-shadow:0 0 20rpx rgba(255,64,129,.2)}.grid{display:grid;grid-template-columns:1fr 1fr;gap:18rpx}.item{position:relative;overflow:hidden;padding:28rpx;border-radius:28rpx;background:rgba(29,32,37,.56);backdrop-filter:blur(24rpx);border:1rpx solid rgba(255,255,255,.06);box-shadow:0 20rpx 40rpx rgba(0,0,0,.06);min-height:220rpx}.accent-tertiary{box-shadow:0 20rpx 40rpx rgba(255,64,129,.06)}.accent-secondary{box-shadow:0 20rpx 40rpx rgba(0,229,255,.06)}.accent-primary{box-shadow:0 20rpx 40rpx rgba(127,0,255,.06)}.item-icon{width:76rpx;height:76rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;margin-bottom:24rpx;font-size:32rpx}.item-title{display:block;font-size:30rpx;font-weight:700;margin-bottom:8rpx}.item-sub{display:block;font-size:22rpx;color:#aaabb0}

View File

@ -0,0 +1 @@
Page({})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,64 @@
<view class="page">
<view class="topbar">
<view class="brand">
<view class="avatar-wrap"><image class="avatar" src="https://picsum.photos/280" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="icon-btn">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="header">
<text class="title">批量上传词汇</text>
<text class="subtitle">通过 Excel 文件快速导入您的词库。</text>
</view>
<view class="layout">
<view class="instruction-card">
<text class="section-title">上传指南</text>
<view class="steps">
<view class="step active">
<view class="step-dot active-dot">1</view>
<view class="step-card">
<text class="step-title">下载模板</text>
<text class="step-desc">获取标准 Excel 格式文件</text>
<text class="download">⬇ 下载模板.xlsx</text>
</view>
</view>
<view class="step">
<view class="step-dot">2</view>
<view class="step-card low"><text class="step-title">填写数据</text><text class="step-desc">按照列名填入单词与释义</text></view>
</view>
<view class="step">
<view class="step-dot">3</view>
<view class="step-card low"><text class="step-title">拖拽上传</text><text class="step-desc">将文件拖入右侧区域</text></view>
</view>
</view>
</view>
<view class="upload-card">
<view class="dropzone">
<view class="upload-icon">⤴</view>
<text class="drop-title">点击上传Excel</text>
<text class="drop-desc">或将文件拖拽至此处。<br />支持 .xlsx, .xls 格式,最大 10MB。</text>
<button class="choose-btn">选择文件</button>
</view>
<view class="feedback-card">
<view class="feedback-left">
<view class="status-icon">✓</view>
<view>
<text class="feedback-title">处理完成</text>
<text class="feedback-file">vocabulary_list_v2.xlsx</text>
</view>
</view>
<view class="feedback-stats">
<view class="stat"><text class="stat-num good">100</text><text class="stat-label">成功条数</text></view>
<view class="divider"></view>
<view class="stat"><text class="stat-num bad">0</text><text class="stat-label">失败条数</text></view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.brand{display:flex;align-items:center;gap:18rpx}.avatar-wrap{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 32rpx;box-sizing:border-box}.header{margin-bottom:28rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:24rpx}.layout{display:grid;grid-template-columns:1fr;gap:24rpx}.instruction-card,.upload-card,.feedback-card,.step-card,.dropzone{background:rgba(29,32,37,.56);border:1rpx solid rgba(255,255,255,.08);border-radius:28rpx;box-sizing:border-box}.instruction-card{padding:24rpx}.section-title{display:block;font-size:28rpx;font-weight:700;margin-bottom:18rpx}.steps{display:flex;flex-direction:column;gap:18rpx}.step{display:flex;align-items:stretch;gap:16rpx}.step-dot{width:44rpx;height:44rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:20rpx;font-weight:700;margin-top:10rpx}.active-dot{background:#c19cff;color:#000}.step-card{flex:1;padding:18rpx;background:#171a1f}.low{background:#111318}.step-title{display:block;font-size:24rpx;font-weight:700;margin-bottom:6rpx}.step-desc{display:block;font-size:20rpx;color:#aaabb0}.download{display:block;margin-top:12rpx;font-size:20rpx;color:#00e5ff}.upload-card{display:flex;flex-direction:column;gap:18rpx}.dropzone{padding:40rpx 28rpx;min-height:360rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;background:rgba(29,32,37,.4)}.upload-icon{width:112rpx;height:112rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;font-size:48rpx;color:#c19cff;margin-bottom:18rpx}.drop-title{display:block;font-size:34rpx;font-weight:800;margin-bottom:10rpx}.drop-desc{display:block;font-size:22rpx;color:#aaabb0;line-height:1.6;margin-bottom:24rpx}.choose-btn{border-radius:9999rpx;padding:20rpx 30rpx;background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;font-weight:700}.feedback-card{padding:24rpx;display:flex;flex-direction:column;gap:16rpx}.feedback-left{display:flex;align-items:center;gap:16rpx}.status-icon{width:56rpx;height:56rpx;border-radius:9999rpx;background:#111318;display:flex;align-items:center;justify-content:center;color:#00e5ff}.feedback-title{display:block;font-size:24rpx;font-weight:700}.feedback-file{display:block;font-size:20rpx;color:#aaabb0}.feedback-stats{display:flex;align-items:center;gap:24rpx;justify-content:flex-end}.stat{text-align:center}.stat-num{display:block;font-size:34rpx;font-weight:800}.good{color:#00e5ff}.bad{color:#aaabb0}.stat-label{display:block;font-size:18rpx;color:#aaabb0}.divider{width:1rpx;height:34rpx;background:rgba(255,255,255,.08)}

View File

@ -0,0 +1 @@
Page({})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,45 @@
<view class="page">
<view class="topbar">
<view class="brand">
<view class="avatar-wrap"><image class="avatar" src="https://picsum.photos/300" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="icon-btn">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="header">
<text class="title">打卡详情</text>
<text class="subtitle">查看近期的学习与坚持记录。</text>
</view>
<view class="card hero">
<view class="hero-row">
<view>
<text class="hero-num">12</text>
<text class="hero-label">连续打卡天数</text>
</view>
<view class="fire">🔥</view>
</view>
<view class="progress-bar"><view class="fill"></view></view>
<view class="week-row">
<text class="day">一</text><text class="day">二</text><text class="day">三</text><text class="day">四</text><text class="day active">五</text><text class="day">六</text><text class="day">日</text>
</view>
</view>
<view class="timeline">
<view class="entry">
<view class="dot done"></view>
<view class="entry-card"><text class="entry-title">今日已完成</text><text class="entry-desc">复习 45 词,正确率 92%</text></view>
</view>
<view class="entry">
<view class="dot"></view>
<view class="entry-card low"><text class="entry-title">昨日打卡</text><text class="entry-desc">完成 30 词复习</text></view>
</view>
<view class="entry">
<view class="dot"></view>
<view class="entry-card low"><text class="entry-title">本周目标</text><text class="entry-desc">累计打卡 5 / 7 天</text></view>
</view>
</view>
</scroll-view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.brand{display:flex;align-items:center;gap:18rpx}.avatar-wrap{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx;box-sizing:border-box}.header{margin-bottom:24rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:24rpx}.card{background:rgba(29,32,37,.56);border:1rpx solid rgba(255,255,255,.08);border-radius:28rpx}.hero{padding:28rpx}.hero-row{display:flex;justify-content:space-between;align-items:center}.hero-num{display:block;font-size:72rpx;font-weight:800}.hero-label{display:block;margin-top:6rpx;color:#aaabb0;font-size:22rpx}.fire{width:76rpx;height:76rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;font-size:34rpx}.progress-bar{height:10rpx;margin-top:20rpx;border-radius:9999rpx;background:#23262c;overflow:hidden}.fill{width:71%;height:100%;background:linear-gradient(90deg,#c19cff,#00e5ff)}.week-row{display:flex;justify-content:space-between;margin-top:16rpx;color:#aaabb0;font-size:22rpx}.day.active{color:#00e5ff;font-weight:700}.timeline{margin-top:18rpx;display:flex;flex-direction:column;gap:14rpx}.entry{display:flex;gap:14rpx;align-items:stretch}.dot{width:18rpx;height:18rpx;margin-top:20rpx;border-radius:9999rpx;background:#23262c;flex-shrink:0}.dot.done{background:#00e5ff;box-shadow:0 0 12rpx rgba(0,229,255,.6)}.entry-card{flex:1;padding:20rpx;border-radius:22rpx;background:#171a1f;border:1rpx solid rgba(255,255,255,.06)}.low{background:#111318}.entry-title{display:block;font-size:26rpx;font-weight:700}.entry-desc{display:block;margin-top:6rpx;color:#aaabb0;font-size:22rpx}

1
entry-edit/entry-edit.js Normal file
View File

@ -0,0 +1 @@
Page({})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,39 @@
<view class="page">
<view class="ambient-glow"></view>
<view class="topbar">
<button class="close-btn" bindtap="goBack">✕</button>
<view class="spacer"></view>
</view>
<scroll-view scroll-y class="content">
<view class="header">
<text class="title">添加新内容</text>
<text class="subtitle">构建你的专属知识库</text>
</view>
<view class="segmented">
<view class="seg active">单词</view>
<view class="seg">句子</view>
</view>
<view class="form">
<view class="field">
<text class="label">英文内容</text>
<view class="input-shell"><input class="input" placeholder="输入英文单词..." /></view>
</view>
<view class="field">
<text class="label">中文释义</text>
<view class="input-shell"><input class="input small" placeholder="输入对应的中文含义..." /></view>
</view>
<view class="field">
<text class="label">例句 <text class="muted">(可选)</text></text>
<view class="input-shell textarea-shell"><textarea class="textarea" placeholder="添加包含该单词的典型例句,帮助记忆..." /></view>
</view>
</view>
<view class="action-bar">
<button class="cancel-btn" bindtap="goBack">取消</button>
<button class="save-btn">保存</button>
</view>
</scroll-view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;position:relative;overflow-x:hidden;box-sizing:border-box}.ambient-glow{position:absolute;top:0;left:50%;transform:translateX(-50%);width:80vw;max-width:800px;height:400px;background:radial-gradient(circle,rgba(193,156,255,.08) 0%,rgba(12,14,18,0) 70%);pointer-events:none;z-index:0}.topbar{position:relative;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:24rpx 32rpx}.close-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:#000;color:#aaabb0;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.1)}.spacer{width:72rpx;height:72rpx}.content{position:relative;z-index:10;height:calc(100vh - 120rpx);padding:16rpx 32rpx 48rpx;box-sizing:border-box}.header{margin-bottom:40rpx}.title{display:block;font-size:56rpx;font-weight:800;line-height:1.1}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.segmented{display:flex;width:fit-content;padding:8rpx;background:#000;border:1rpx solid rgba(255,255,255,.1);border-radius:9999rpx;margin-bottom:40rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.2)}.seg{padding:18rpx 32rpx;border-radius:9999rpx;color:#aaabb0;font-size:24rpx}.active{background:#1d2025;color:#c19cff;font-weight:700}.form{display:flex;flex-direction:column;gap:28rpx}.field{display:flex;flex-direction:column}.label{font-size:22rpx;color:#aaabb0;font-weight:700;margin:0 0 12rpx 4rpx}.muted{color:rgba(170,171,176,.5);font-weight:400}.input-shell{border-radius:24rpx;background:#000;border:1rpx solid rgba(255,255,255,.1);box-sizing:border-box}.input{width:100%;padding:24rpx 26rpx;font-size:36rpx;color:#f6f6fc;box-sizing:border-box}.small{font-size:28rpx}.textarea-shell{background:#111318}.textarea{width:100%;min-height:220rpx;padding:24rpx 26rpx;font-size:28rpx;color:#f6f6fc;box-sizing:border-box}.action-bar{display:flex;justify-content:flex-end;gap:18rpx;padding-top:28rpx;margin-top:36rpx;border-top:1rpx solid rgba(255,255,255,.05)}.cancel-btn,.save-btn{border-radius:9999rpx;padding:22rpx 34rpx;font-weight:700}.cancel-btn{background:#000;color:#f6f6fc;border:1rpx solid rgba(255,255,255,.1)}.save-btn{background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff}

12
index/index.js Normal file
View File

@ -0,0 +1,12 @@
Page({
goToReview() {
wx.navigateTo({ url: '/pages/review-config/review-config' })
},
goToMe() {
wx.navigateTo({ url: '/pages/me/me' })
},
goHome() {},
goTo(url) {
wx.navigateTo({ url })
},
})

3
index/index.json Normal file
View File

@ -0,0 +1,3 @@
{
"navigationBarTitleText": "首页"
}

55
index/index.wxml Normal file
View File

@ -0,0 +1,55 @@
<view class="page">
<view class="topbar">
<view class="brand">
<view class="avatar-wrap"><image class="avatar" src="https://picsum.photos/200" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="icon-btn">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="greeting">
<text class="title">早安,同学</text>
<text class="subtitle">今天也要稳步推进</text>
</view>
<view class="grid-layout">
<view class="hero-card">
<view class="hero-overlay"></view>
<view class="hero-row">
<view>
<text class="hero-number">45</text>
<text class="label">今日待复习</text>
</view>
<view class="hero-icon">🧠</view>
</view>
<view class="hero-grid">
<view class="metric-card"><text class="metric-value">120</text><text class="label small">已完成</text></view>
<view class="metric-card"><text class="metric-value accent">92%</text><text class="label small">正确率</text></view>
</view>
</view>
<view class="stack">
<view class="streak-card">
<view class="streak-head">
<view class="streak-left"><view class="fire">🔥</view><text class="streak-title">连续打卡 12 天</text></view>
<text class="streak-goal">周目标 5/7</text>
</view>
<view class="progress-bar"><view class="progress-fill"></view></view>
<view class="week-row"><text class="day">一</text><text class="day">二</text><text class="day">三</text><text class="day">四</text><text class="day active">五</text><text class="day">六</text><text class="day">日</text></view>
</view>
<view class="actions">
<button class="primary-btn" bindtap="goToReview">开始今日复习</button>
<button class="secondary-btn" bindtap="goToReview">继续上次复习</button>
</view>
</view>
</view>
</scroll-view>
<view class="bottom-nav">
<view class="nav-item active" bindtap="goHome"><text class="nav-icon">⌂</text><text class="nav-label">首页</text></view>
<view class="nav-item" bindtap="goToReview"><text class="nav-icon">📖</text><text class="nav-label">复习</text></view>
<view class="nav-item" bindtap="goToMe"><text class="nav-icon">☺</text><text class="nav-label">我的</text></view>
</view>
</view>

4
index/index.wxss Normal file
View File

@ -0,0 +1,4 @@
page { background:#0c0e12; color:#f6f6fc; }
.page { min-height:100vh; background: radial-gradient(circle at top, rgba(193,156,255,0.15), transparent 30%), #0c0e12; box-sizing:border-box; }
.topbar { position:sticky; top:0; z-index:20; display:flex; justify-content:space-between; align-items:center; padding:24rpx 32rpx; background:rgba(255,255,255,.8); backdrop-filter:blur(24px); border-bottom:1rpx solid rgba(255,255,255,.2); box-shadow:0 1rpx 20rpx rgba(0,0,0,.08); }
.brand,.streak-left{display:flex;align-items:center;gap:20rpx}.avatar-wrap{width:80rpx;height:80rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:40rpx;font-weight:900;background:linear-gradient(90deg,#6366f1,#22d3ee);-webkit-background-clip:text;color:transparent}.icon-btn{color:#6366f1;width:72rpx;height:72rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.4)}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 140rpx;box-sizing:border-box}.greeting{display:flex;flex-direction:column;gap:8rpx;margin-bottom:32rpx}.title{display:block;font-size:56rpx;font-weight:800;color:#fff}.subtitle{display:block;font-size:30rpx;color:#aaabb0}.grid-layout{display:grid;grid-template-columns:1fr;gap:24rpx}.hero-card{position:relative;overflow:hidden;min-height:280rpx;padding:32rpx;border-radius:24rpx;background:rgba(29,32,37,.6);backdrop-filter:blur(24px);border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.4)}.hero-overlay{position:absolute;inset:0;background:linear-gradient(135deg,rgba(193,156,255,.05),rgba(0,227,253,.05));z-index:0}.hero-row,.hero-grid{position:relative;z-index:1}.hero-row{display:flex;justify-content:space-between;align-items:flex-start}.hero-number{display:block;font-size:72rpx;font-weight:800;color:#fff;line-height:1}.hero-icon{width:96rpx;height:96rpx;border-radius:9999rpx;background:rgba(255,255,255,.08);display:flex;align-items:center;justify-content:center;font-size:44rpx;border:1rpx solid rgba(255,255,255,.05)}.label{display:block;margin-top:8rpx;font-size:24rpx;color:#aaabb0}.hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;margin-top:44rpx}.metric-card{padding:24rpx;border-radius:20rpx;background:rgba(0,0,0,.15);border:1rpx solid rgba(255,255,255,.05)}.metric-value{display:block;font-size:44rpx;font-weight:800;color:#fff}.metric-value.accent{color:#00e3fd}.small{font-size:20rpx}.stack{display:flex;flex-direction:column;gap:24rpx}.streak-card{padding:28rpx;border-radius:24rpx;background:#111318;border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.4)}.streak-head{display:flex;justify-content:space-between;align-items:center}.fire{width:80rpx;height:80rpx;border-radius:9999rpx;background:#171a1f;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.05)}.streak-title{font-size:30rpx;font-weight:700;color:#fff}.streak-goal{font-size:24rpx;color:#00e3fd;font-weight:500}.progress-bar{height:12rpx;background:#23262c;border-radius:9999rpx;overflow:hidden;margin-top:18rpx}.progress-fill{width:71%;height:100%;background:linear-gradient(90deg,#c19cff,#00e3fd);position:relative}.progress-fill::after{content:'';position:absolute;inset:0;background:rgba(255,255,255,.2)}.week-row{display:flex;justify-content:space-between;margin-top:10rpx;font-size:22rpx;color:#aaabb0}.day.active{color:#00e3fd;font-weight:700}.actions{display:flex;flex-direction:column;gap:18rpx;margin-top:4rpx}.primary-btn,.secondary-btn{width:100%;padding:26rpx 0;border-radius:9999rpx;font-size:32rpx;font-weight:800}.primary-btn{background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;box-shadow:0 0 20rpx rgba(193,156,255,.3)}.secondary-btn{background:#23262c;color:#fff;border:1rpx solid rgba(255,255,255,.08)}.bottom-nav{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;justify-content:space-around;align-items:center;padding:20rpx 24rpx 40rpx;background:rgba(255,255,255,.7);backdrop-filter:blur(24px);border-top-left-radius:32rpx;border-top-right-radius:32rpx;box-shadow:0 -10rpx 40rpx rgba(0,0,0,.1)}.nav-item{display:flex;flex-direction:column;align-items:center;color:#aaabb0}.nav-item.active{color:#00e3fd;transform:translateY(-6rpx)}.nav-icon{width:56rpx;height:56rpx;border-radius:9999rpx;background:rgba(255,255,255,.05);display:flex;align-items:center;justify-content:center;font-size:26rpx}.nav-label{font-size:20rpx}

18
logs/logs.js Normal file
View File

@ -0,0 +1,18 @@
// logs.js
const util = require('../../utils/util.js')
Page({
data: {
logs: []
},
onLoad() {
this.setData({
logs: (wx.getStorageSync('logs') || []).map(log => {
return {
date: util.formatTime(new Date(log)),
timeStamp: log
}
})
})
}
})

3
logs/logs.json Normal file
View File

@ -0,0 +1,3 @@
{
"navigationBarTitleText": "日志"
}

6
logs/logs.wxml Normal file
View File

@ -0,0 +1,6 @@
<!--logs.wxml-->
<scroll-view class="scrollarea" scroll-y type="list">
<block wx:for="{{logs}}" wx:key="timeStamp" wx:for-item="log">
<view class="log-item">{{index + 1}}. {{log.date}}</view>
</block>
</scroll-view>

16
logs/logs.wxss Normal file
View File

@ -0,0 +1,16 @@
page {
height: 100vh;
display: flex;
flex-direction: column;
}
.scrollarea {
flex: 1;
overflow-y: hidden;
}
.log-item {
margin-top: 20rpx;
text-align: center;
}
.log-item:last-child {
padding-bottom: env(safe-area-inset-bottom);
}

24
me/me.js Normal file
View File

@ -0,0 +1,24 @@
const app = getApp()
Page({
data: {
name: '',
days: 0,
badges: 0,
},
onLoad() {
const { userInfo } = app.globalData
this.setData({
name: userInfo.name,
days: userInfo.days,
badges: userInfo.badges,
})
},
goTo(e) {
const { url } = e.currentTarget.dataset
wx.navigateTo({ url })
},
goHome() {
wx.switchTab({ url: '/pages/index/index' })
},
})

3
me/me.json Normal file
View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

74
me/me.wxml Normal file
View File

@ -0,0 +1,74 @@
<view class="page">
<view class="topbar">
<view class="topbar-left">
<view class="avatar-shell">
<image class="avatar-img" src="https://picsum.photos/240" mode="aspectFill" />
</view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="topbar-icon">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="hero-section">
<view class="hero-avatar-wrap">
<view class="hero-avatar-border">
<image class="hero-avatar" src="https://picsum.photos/241" mode="aspectFill" />
</view>
</view>
<view class="hero-info">
<text class="hero-name">{{name}}</text>
<view class="hero-badge">
<view class="pulse-dot"></view>
<text class="badge-text">累计学习 {{days}} 天</text>
</view>
</view>
</view>
<view class="grid-2">
<view class="glass-card accent-tertiary" bindtap="goTo" data-url="/pages/achievements/achievements">
<view class="card-glow"></view>
<view class="card-icon icon-tertiary">🏅</view>
<text class="card-title">成就墙</text>
<text class="card-subtitle">已点亮 {{badges}} 枚勋章</text>
</view>
<view class="glass-card accent-secondary" bindtap="goTo" data-url="/pages/checkin-detail/checkin-detail">
<view class="card-glow"></view>
<view class="card-icon icon-secondary">📅</view>
<text class="card-title">打卡详情</text>
<text class="card-subtitle">本周全勤</text>
</view>
</view>
<view class="divider-row">
<view class="divider"></view>
<text class="section-kicker">数据管理</text>
<view class="divider"></view>
</view>
<view class="grid-2 management-grid">
<view class="small-action" bindtap="goTo" data-url="/pages/vocab-manage/vocab-manage">
<view class="small-icon primary">📚</view>
<text class="small-text">词库管理</text>
</view>
<view class="small-action" bindtap="goTo" data-url="/pages/entry-edit/entry-edit">
<view class="small-icon secondary"></view>
<text class="small-text">手动新增</text>
</view>
<view class="small-action" bindtap="goTo" data-url="/pages/batch-upload/batch-upload">
<view class="small-icon tertiary">☁</view>
<text class="small-text">批量上传</text>
</view>
<view class="small-action" bindtap="goTo" data-url="/pages/progress-list/progress-list">
<view class="small-icon primary-fixed">≡</view>
<text class="small-text">进度列表</text>
</view>
</view>
<view class="settings-card" bindtap="goTo" data-url="/pages/settings/settings">
<view class="settings-icon">⚙</view>
<text class="settings-text">个性化设置</text>
<view class="chevron"></view>
</view>
</scroll-view>
</view>

1
me/me.wxss Normal file
View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{position:sticky;top:0;z-index:20;display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(255,255,255,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.2);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.topbar-left{display:flex;align-items:center;gap:20rpx}.avatar-shell{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.2);flex-shrink:0}.avatar-img{width:100%;height:100%}.brand-text{font-size:40rpx;font-weight:900;background:linear-gradient(90deg,#6366f1,#22d3ee);-webkit-background-clip:text;color:transparent}.topbar-icon{color:#6366f1}.content{height:calc(100vh - 120rpx);padding:48rpx 40rpx 32rpx;box-sizing:border-box}.hero-section{display:flex;align-items:center;gap:28rpx;margin-bottom:48rpx}.hero-avatar-wrap{padding:2rpx;border-radius:9999rpx;background:linear-gradient(135deg,#c19cff,#9146ff,#00e3fd);box-shadow:0 10rpx 30rpx rgba(193,156,255,.2)}.hero-avatar-border{width:176rpx;height:176rpx;border-radius:9999rpx;overflow:hidden;border:6rpx solid #0c0e12;background:#1d2025}.hero-avatar{width:100%;height:100%}.hero-info{display:flex;flex-direction:column;justify-content:center}.hero-name{display:block;font-size:56rpx;font-weight:800;line-height:1.1;margin-bottom:12rpx}.hero-badge{display:inline-flex;align-items:center;gap:12rpx;padding:12rpx 18rpx;border-radius:9999rpx;background:#1d2025;border:1rpx solid rgba(255,255,255,.1);width:fit-content}.pulse-dot{width:16rpx;height:16rpx;border-radius:9999rpx;background:#00e3fd;box-shadow:0 0 16rpx rgba(0,227,253,.8)}.badge-text{font-size:22rpx;color:#aaabb0}.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:18rpx}.glass-card{position:relative;overflow:hidden;padding:28rpx;border-radius:24rpx;border:1rpx solid rgba(255,255,255,.08);background:rgba(29,32,37,.6);backdrop-filter:blur(24px);box-shadow:0 20rpx 40rpx rgba(0,0,0,.08);min-height:220rpx}.card-glow{position:absolute;right:-32rpx;top:-32rpx;width:128rpx;height:128rpx;border-radius:9999rpx;filter:blur(24rpx)}.accent-tertiary .card-glow{background:rgba(255,108,149,.12)}.accent-secondary .card-glow{background:rgba(0,227,253,.12)}.card-icon{position:relative;z-index:1;width:76rpx;height:76rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;margin-bottom:24rpx;font-size:32rpx}.card-title,.card-subtitle{position:relative;z-index:1;display:block}.card-title{font-size:30rpx;font-weight:700;color:#f6f6fc;margin-bottom:6rpx}.card-subtitle{font-size:22rpx;color:#aaabb0}.divider-row{display:flex;align-items:center;gap:16rpx;margin:36rpx 0 20rpx}.divider{flex:1;height:2rpx;background:linear-gradient(90deg,transparent,rgba(255,255,255,.1),transparent)}.section-kicker{font-size:20rpx;letter-spacing:4rpx;text-transform:uppercase;color:rgba(170,171,176,.6);font-weight:700}.management-grid{margin-bottom:24rpx}.small-action{display:flex;align-items:center;gap:18rpx;padding:22rpx;border-radius:20rpx;background:rgba(17,19,24,.8);border:1rpx solid rgba(255,255,255,.05);min-height:108rpx}.small-icon{width:68rpx;height:68rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.06);flex-shrink:0;font-size:28rpx}.small-icon.primary{color:#c19cff}.small-icon.secondary{color:#00e3fd}.small-icon.tertiary{color:#ff6c95}.small-icon.primary-fixed{color:#b68aff}.small-text{font-size:24rpx;font-weight:600;color:#f6f6fc}.settings-card{display:flex;align-items:center;justify-content:space-between;padding:26rpx 24rpx;border-radius:24rpx;background:rgba(29,32,37,.4);border:1rpx solid rgba(255,255,255,.08);box-shadow:0 10rpx 30rpx rgba(0,0,0,.1)}.settings-icon{width:76rpx;height:76rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;font-size:30rpx}.settings-text{flex:1;margin-left:20rpx;font-size:30rpx;font-weight:700}.chevron{width:56rpx;height:56rpx;border-radius:9999rpx;background:rgba(255,255,255,.04);display:flex;align-items:center;justify-content:center;color:#aaabb0;font-size:46rpx;line-height:1}

View File

@ -0,0 +1 @@
Page({})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,40 @@
<view class="page">
<view class="topbar">
<view class="brand">
<view class="avatar-wrap"><image class="avatar" src="https://picsum.photos/290" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="icon-btn">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="header">
<text class="title">进度列表</text>
<text class="subtitle">查看每个词条的掌握程度。</text>
</view>
<view class="list">
<view class="row">
<view>
<text class="word">Ephemeral</text>
<text class="desc">短暂的,朝生暮死的</text>
</view>
<text class="percent cyan">95%</text>
</view>
<view class="row">
<view>
<text class="word">Ubiquitous</text>
<text class="desc">普遍存在的,无处不在的</text>
</view>
<text class="percent purple">60%</text>
</view>
<view class="row">
<view>
<text class="word">Obfuscate</text>
<text class="desc">使模糊,使混乱</text>
</view>
<text class="percent pink">30%</text>
</view>
</view>
</scroll-view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.brand{display:flex;align-items:center;gap:18rpx}.avatar-wrap{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx;box-sizing:border-box}.header{margin-bottom:24rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:24rpx}.list{background:rgba(29,32,37,.56);border:1rpx solid rgba(255,255,255,.08);border-radius:28rpx;overflow:hidden}.row{display:flex;justify-content:space-between;align-items:center;padding:24rpx 22rpx;border-bottom:1rpx solid rgba(255,255,255,.06)}.row:last-child{border-bottom:none}.word{display:block;font-size:30rpx;font-weight:700}.desc{display:block;margin-top:6rpx;color:#aaabb0;font-size:22rpx}.percent{font-size:32rpx;font-weight:800}.cyan{color:#00e5ff}.purple{color:#c19cff}.pink{color:#ff4081}

View File

@ -0,0 +1,70 @@
const app = getApp()
Page({
data: {
timeRanges: ['今日', '本周', '自定义区间'],
activeTimeRange: 0,
contentTypes: ['单词', '句子'],
activeContentType: 0,
modes: ['中文 -> 英文拼写', '英文 -> 中文释义', '英文挖空填空'],
activeMode: 0,
onlyReview: true,
shuffle: false,
questionCount: 30,
},
onLoad() {
const plan = app.globalData.reviewPlan
this.setData({
activeTimeRange: plan.timeRangeIndex,
activeContentType: plan.contentTypeIndex,
activeMode: plan.modeIndex,
onlyReview: plan.onlyReview,
shuffle: plan.shuffle,
questionCount: plan.questionCount,
})
},
persistPatch(patch) {
app.globalData.reviewPlan = { ...app.globalData.reviewPlan, ...patch }
},
setTimeRange(e) {
const activeTimeRange = Number(e.currentTarget.dataset.index)
this.setData({ activeTimeRange })
this.persistPatch({ timeRangeIndex: activeTimeRange })
},
setContentType(e) {
const activeContentType = Number(e.currentTarget.dataset.index)
this.setData({ activeContentType })
this.persistPatch({ contentTypeIndex: activeContentType })
},
setMode(e) {
const activeMode = Number(e.currentTarget.dataset.index)
this.setData({ activeMode })
this.persistPatch({ modeIndex: activeMode })
},
toggleOnlyReview() {
const onlyReview = !this.data.onlyReview
this.setData({ onlyReview })
this.persistPatch({ onlyReview })
},
toggleShuffle() {
const shuffle = !this.data.shuffle
this.setData({ shuffle })
this.persistPatch({ shuffle })
},
onQuestionCountInput(e) {
const questionCount = e.detail.value
this.setData({ questionCount })
this.persistPatch({ questionCount })
},
startReview() {
app.globalData.reviewSession = {
deck: [],
currentIndex: 0,
correctCount: 0,
wrongCount: 0,
completed: false,
currentAnswer: '',
}
wx.navigateTo({ url: '/pages/review-session/review-session' })
},
})

View File

@ -0,0 +1,3 @@
{
"navigationBarTitleText": "复习配置"
}

View File

@ -0,0 +1,46 @@
<view class="page">
<view class="topbar">
<view class="brand">
<view class="avatar-wrap"><image class="avatar" src="https://picsum.photos/201" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="icon-btn">🔔</view>
</view>
<scroll-view scroll-y class="content config-content">
<view class="heading">
<text class="title">配置复习计划</text>
<text class="subtitle">定制您的专属认知强化训练,进入深度心流状态。</text>
</view>
<view class="config-card">
<text class="section-title">时间范围</text>
<view class="chip-row">
<text wx:for="{{timeRanges}}" wx:key="index" data-index="{{index}}" bindtap="setTimeRange" class="chip {{index===activeTimeRange?'active':''}}">{{item}}</text>
</view>
</view>
<view class="config-card">
<text class="section-title">内容类型</text>
<view class="two-grid">
<view wx:for="{{contentTypes}}" wx:key="index" data-index="{{index}}" bindtap="setContentType" class="option-box {{index===activeContentType?'active':''}}">{{item}}</view>
</view>
</view>
<view class="config-card">
<text class="section-title">训练模式</text>
<view class="mode-list">
<view wx:for="{{modes}}" wx:key="index" data-index="{{index}}" bindtap="setMode" class="mode-item {{index===activeMode?'active':''}}">{{item}}</view>
</view>
</view>
<view class="config-card">
<text class="section-title">策略微调</text>
<view class="switch-row" bindtap="toggleOnlyReview"><text>仅待复习</text><text class="switch {{onlyReview?'on':''}}">{{onlyReview ? 'ON' : 'OFF'}}</text></view>
<view class="switch-row" bindtap="toggleShuffle"><text>随机打乱</text><text class="switch {{shuffle?'on':''}}">{{shuffle ? 'ON' : 'OFF'}}</text></view>
<view class="range-row"><text>题量选择</text><text class="accent">{{questionCount}} 词</text></view>
<slider min="5" max="100" step="5" value="{{questionCount}}" activeColor="#c19cff" backgroundColor="#23262c" bindchanging="onQuestionCountInput" bindchange="onQuestionCountInput" />
</view>
<button class="start-btn" bindtap="startReview">开始复习</button>
</scroll-view>
</view>

View File

@ -0,0 +1,5 @@
page { background:#0c0e12; color:#f6f6fc; }
.page { min-height:100vh; background:#0c0e12; }
.topbar { position:sticky; top:0; z-index:10; display:flex; justify-content:space-between; align-items:center; padding:24rpx 32rpx; background:rgba(12,14,18,.8); backdrop-filter:blur(24px); border-bottom:1rpx solid rgba(255,255,255,.08); }
.brand{display:flex;align-items:center;gap:20rpx}.avatar-wrap{width:80rpx;height:80rpx;border-radius:9999rpx;overflow:hidden;flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:40rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}
.config-content{height:calc(100vh - 120rpx);padding:32rpx;box-sizing:border-box}.heading{margin:16rpx 0 24rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;font-size:28rpx;color:#aaabb0;line-height:1.6}.config-card{margin-top:24rpx;padding:28rpx;border-radius:28rpx;background:rgba(29,32,37,.65);border:1rpx solid rgba(255,255,255,.08)}.section-title{display:block;font-size:32rpx;font-weight:700;margin-bottom:20rpx}.chip-row{display:flex;flex-wrap:wrap;gap:16rpx}.chip{padding:18rpx 28rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0}.chip.active{background:#c19cff;color:#000}.two-grid{display:grid;grid-template-columns:1fr 1fr;gap:18rpx}.option-box,.mode-item{padding:24rpx;border-radius:24rpx;background:#111318;border:1rpx solid rgba(255,255,255,.08);text-align:center;color:#aaabb0;min-height:96rpx;display:flex;align-items:center;justify-content:center}.option-box.active,.mode-item.active{color:#c19cff;border-color:#c19cff}.mode-list{display:flex;flex-direction:column;gap:18rpx}.switch-row,.range-row{display:flex;justify-content:space-between;align-items:center;padding:12rpx 0}.switch{padding:6rpx 16rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0}.switch.on{background:#c19cff;color:#000}.accent{color:#c19cff;font-weight:700}.range-bar{height:12rpx;border-radius:9999rpx;background:#23262c;overflow:hidden}.range-fill{width:30%;height:100%;background:linear-gradient(90deg,#c19cff,#00e3fd)}.start-btn{margin:32rpx 0 48rpx;padding:28rpx 0;border-radius:9999rpx;background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;font-size:34rpx;font-weight:800;box-shadow:0 0 20rpx rgba(193,156,255,.28)}

View File

@ -0,0 +1,30 @@
const app = getApp()
Page({
data: {
accuracy: 95,
timeUsed: '12:45',
total: 50,
mastered: 20,
reviewNeeded: 5,
},
onLoad() {
const session = app.globalData.reviewSession
const total = session.deck.length || this.data.total
const correct = session.correctCount || 0
const accuracy = total ? Math.round((correct / total) * 100) : this.data.accuracy
this.setData({
accuracy,
total,
mastered: correct,
reviewNeeded: session.wrongCount || this.data.reviewNeeded,
})
},
restart() {
app.globalData.reviewSession = { deck: [], currentIndex: 0, correctCount: 0, wrongCount: 0, completed: false, currentAnswer: '' }
wx.reLaunch({ url: '/pages/review-config/review-config' })
},
goHome() {
wx.reLaunch({ url: '/pages/index/index' })
},
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,63 @@
<view class="page">
<view class="bg-orb orb1"></view>
<view class="bg-orb orb2"></view>
<view class="hero">
<view class="badge">
<view class="badge-inner">🏆</view>
</view>
<view class="hero-copy">
<text class="headline">复习完成</text>
<text class="subtitle">优秀表现</text>
</view>
</view>
<view class="grid">
<view class="hero-card">
<view class="hero-card-head">
<view>
<text class="metric-label">正确率</text>
<view class="metric-row">
<text class="metric-big">{{accuracy}}</text>
<text class="metric-unit">%</text>
</view>
</view>
<view class="ring">✓</view>
</view>
</view>
<view class="mini-card">
<view class="mini-head"><text class="mini-ico">⏱</text><text class="mini-label">耗时</text></view>
<text class="mini-value">{{timeUsed}}</text>
</view>
<view class="mini-card">
<view class="mini-head"><text class="mini-ico">📚</text><text class="mini-label">总题数</text></view>
<text class="mini-value">{{total}}</text>
</view>
<view class="breakdown">
<view class="break-item">
<text class="break-num cyan">{{mastered}}</text>
<text class="break-label">新增已掌握</text>
</view>
<view class="break-item">
<text class="break-num pink">{{reviewNeeded}}</text>
<text class="break-label">需加强</text>
</view>
</view>
<view class="achievement">
<view class="ach-ico">🏆</view>
<view class="ach-copy">
<text class="ach-sub">新成就解锁</text>
<text class="ach-title">获得“坚持不懈”勋章</text>
</view>
</view>
</view>
<view class="actions">
<button class="primary-btn" bindtap="restart">再来一组</button>
<button class="secondary-btn" bindtap="goHome">返回首页</button>
</view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;padding:48rpx 32rpx 60rpx;box-sizing:border-box;background:#0c0e12;position:relative;overflow:hidden}.bg-orb{position:absolute;border-radius:9999rpx;pointer-events:none;filter:blur(120rpx);opacity:.2;z-index:0}.orb1{top:18%;left:50%;width:520rpx;height:520rpx;transform:translate(-50%,-50%);background:#ff6c95}.orb2{bottom:18%;left:50%;width:380rpx;height:380rpx;transform:translate(-50%,50%);background:#00e5ff}.hero,.grid,.actions{position:relative;z-index:1}.hero{display:flex;flex-direction:column;align-items:center;gap:22rpx;margin:26rpx 0 44rpx}.badge{width:144rpx;height:144rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.06);box-shadow:0 0 30rpx rgba(255,108,149,.2)}.badge-inner{width:100%;height:100%;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(255,108,149,.2),rgba(0,229,255,.2));font-size:56rpx}.headline{display:block;font-size:54rpx;font-weight:800;text-align:center}.subtitle{display:block;margin-top:8rpx;color:#00e5ff;letter-spacing:4rpx;text-transform:uppercase;text-align:center}.grid{display:grid;grid-template-columns:1fr 1fr;gap:18rpx}.hero-card{grid-column:1/-1;background:rgba(29,32,37,.7);backdrop-filter:blur(20rpx);border:1rpx solid rgba(255,255,255,.1);border-radius:28rpx;padding:32rpx;box-sizing:border-box;box-shadow:0 20rpx 40rpx rgba(0,0,0,.4);position:relative;overflow:hidden}.hero-card:after{content:'';position:absolute;top:-40rpx;right:-40rpx;width:160rpx;height:160rpx;border-radius:9999rpx;background:rgba(193,156,255,.1);filter:blur(48rpx)}.hero-card-head{display:flex;justify-content:space-between;align-items:center;position:relative;z-index:1}.metric-label{display:block;color:#aaabb0;font-size:20rpx;letter-spacing:4rpx;text-transform:uppercase}.metric-row{display:flex;align-items:baseline;gap:10rpx}.metric-big{font-size:88rpx;font-weight:800;color:#fff;line-height:1}.metric-unit{font-size:32rpx;color:#aaabb0;font-weight:700}.ring{width:124rpx;height:124rpx;border-radius:9999rpx;border:4rpx solid #23262c;display:flex;align-items:center;justify-content:center;color:#c19cff;font-size:52rpx;position:relative}.mini-card{background:rgba(29,32,37,.7);backdrop-filter:blur(20rpx);border:1rpx solid rgba(255,255,255,.1);border-radius:28rpx;padding:24rpx;box-sizing:border-box;box-shadow:0 20rpx 40rpx rgba(0,0,0,.4);display:flex;flex-direction:column;gap:18rpx}.mini-head{display:flex;align-items:center;gap:14rpx}.mini-ico{width:56rpx;height:56rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;font-size:28rpx}.mini-label{color:#aaabb0;font-size:20rpx;letter-spacing:4rpx;text-transform:uppercase}.mini-value{font-size:36rpx;font-weight:800}.breakdown{grid-column:1/-1;display:grid;grid-template-columns:1fr 1fr;gap:0;border-radius:28rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1)}.break-item{background:#1d2025;padding:30rpx;text-align:center}.break-num{display:block;font-size:54rpx;font-weight:800}.cyan{color:#00e5ff}.pink{color:#ff6c95}.break-label{display:block;margin-top:10rpx;color:#aaabb0;font-size:24rpx}.achievement{grid-column:1/-1;display:flex;align-items:center;gap:22rpx;padding:26rpx 24rpx;border-radius:28rpx;background:linear-gradient(90deg,#1d2025,#171a1f);border:1rpx solid rgba(255,255,255,.08);box-shadow:0 20rpx 40rpx rgba(0,0,0,.4)}.ach-ico{width:96rpx;height:96rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#ff6c95,#00e5ff);font-size:44rpx;flex-shrink:0}.ach-sub{display:block;color:#ff6c95;font-size:20rpx;letter-spacing:4rpx;text-transform:uppercase;font-weight:700}.ach-title{display:block;margin-top:6rpx;font-size:32rpx;font-weight:700}.actions{display:flex;gap:18rpx;margin-top:28rpx;position:relative;z-index:1}.primary-btn,.secondary-btn{flex:1;border-radius:9999rpx;padding:24rpx 0;font-weight:800}.primary-btn{background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff}.secondary-btn{background:#23262c;color:#f6f6fc}

View File

@ -0,0 +1,90 @@
const app = getApp()
const deckTemplate = [
{ word: 'prosperity', meaning: 'n. 繁荣, 兴旺', answer: 'pe' },
{ word: 'sustainable', meaning: 'adj. 可持续的', answer: 'sus' },
{ word: 'acquire', meaning: 'v. 获取, 获得', answer: 'ac' },
{ word: 'abstract', meaning: 'adj. 抽象的', answer: 'ab' },
{ word: 'benevolent', meaning: 'adj. 仁慈的', answer: 'be' },
]
Page({
data: {
progress: 0,
current: 1,
total: 0,
word: '',
meaning: '',
answer: '',
feedback: '',
showFeedback: false,
completed: false,
masterHint: false,
},
onLoad() {
if (!app.globalData.reviewSession.deck.length) {
const { questionCount, shuffle } = app.globalData.reviewPlan
let deck = deckTemplate.slice(0, Math.max(1, Math.min(questionCount, deckTemplate.length)))
if (shuffle) deck = deck.slice().sort(() => Math.random() - 0.5)
app.globalData.reviewSession = {
deck,
currentIndex: 0,
correctCount: 0,
wrongCount: 0,
completed: false,
currentAnswer: '',
}
}
this.syncSession()
},
syncSession() {
const session = app.globalData.reviewSession
const current = session.deck[session.currentIndex]
const total = session.deck.length || 1
this.setData({
progress: Math.round((session.currentIndex / total) * 100),
current: session.currentIndex + 1,
total,
word: current?.word || '',
meaning: current?.meaning || '',
answer: session.currentAnswer || '',
feedback: '',
showFeedback: false,
completed: session.completed,
masterHint: false,
})
},
onAnswerInput(e) {
const answer = e.detail.value
app.globalData.reviewSession.currentAnswer = answer
this.setData({ answer })
},
checkAnswer() {
const session = app.globalData.reviewSession
const current = session.deck[session.currentIndex]
if (!current) return
const correct = (this.data.answer || '').trim().toLowerCase() === current.answer.toLowerCase()
session.correctCount += correct ? 1 : 0
session.wrongCount += correct ? 0 : 1
this.setData({
feedback: correct ? '回答正确' : `正确答案:${current.answer}`,
showFeedback: true,
})
},
nextQuestion() {
const session = app.globalData.reviewSession
if (!session.deck.length) return
if (session.currentIndex >= session.deck.length - 1) {
session.completed = true
wx.navigateTo({ url: '/pages/review-result/review-result' })
return
}
session.currentIndex += 1
session.currentAnswer = ''
this.syncSession()
},
markMastered() {
this.setData({ masterHint: true })
wx.showToast({ title: '已标记', icon: 'success' })
},
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,40 @@
<view class="page">
<view class="topbar">
<view class="topbar-left">
<view class="avatar-shell"><image class="avatar-img" src="https://picsum.photos/220" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="topbar-icon">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="progress-box">
<view class="progress-head">
<text class="progress-label">复习进度</text>
<text class="progress-count">题号 {{current}} <text class="progress-total">/ {{total}}</text></text>
</view>
<view class="progress-bar ghost-border"><view class="progress-fill" style="width: {{progress}}%;"></view></view>
</view>
<view class="glass-card question-card ghost-border">
<view class="ambient-glow"></view>
<view class="meaning-wrap">
<text class="meaning">{{meaning}}</text>
</view>
<text class="word">p<text class="gap">_ _ _</text>perity</text>
<view class="input-shell">
<input class="answer" value="{{answer}}" placeholder="输入缺失字母..." bindinput="onAnswerInput" />
</view>
<view wx:if="{{showFeedback}}" class="feedback">{{feedback}}</view>
</view>
<view class="actions-cluster">
<button class="secondary-btn" bindtap="checkAnswer">查看解析</button>
<button class="primary-btn" bindtap="nextQuestion">下一题</button>
</view>
<view class="master-action" bindtap="markMastered">
<text class="master-text {{masterHint ? 'active' : ''}}">标记已掌握</text>
</view>
</scroll-view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);border-bottom:1rpx solid rgba(255,255,255,.08);backdrop-filter:blur(24px);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.topbar-left{display:flex;align-items:center;gap:18rpx}.avatar-shell{width:80rpx;height:80rpx;border-radius:9999rpx;overflow:hidden;border:2rpx solid rgba(193,156,255,.2);flex-shrink:0}.avatar-img{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.topbar-icon{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:32rpx;box-sizing:border-box}.progress-box{margin-bottom:28rpx}.progress-head{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:16rpx}.progress-label{font-size:24rpx;color:#aaabb0}.progress-count{font-size:28rpx;font-weight:700;color:#00e3fd}.progress-total{color:#aaabb0;font-size:22rpx;font-weight:400}.progress-bar{height:12rpx;background:#23262c;border-radius:9999rpx;overflow:hidden}.ghost-border{border:1rpx solid rgba(255,255,255,.1)}.progress-fill{height:100%;background:linear-gradient(90deg,#c19cff,#00e3fd)}.glass-card{background:rgba(29,32,37,.4);backdrop-filter:blur(24rpx)}.question-card{position:relative;overflow:hidden;border-radius:32rpx;padding:40rpx 32rpx;text-align:center;box-shadow:0 20rpx 40rpx rgba(0,0,0,.4);border:1rpx solid rgba(255,255,255,.1)}.ambient-glow{position:absolute;inset:0;background:linear-gradient(to bottom,rgba(193,156,255,.05),transparent);pointer-events:none}.meaning-wrap{margin-bottom:32rpx}.meaning{display:block;color:#aaabb0;font-size:28rpx;letter-spacing:4rpx}.word{display:block;font-size:56rpx;font-weight:800;letter-spacing:4rpx}.gap{color:#9146ff;opacity:.5}.input-shell{margin:26rpx auto 0;max-width:520rpx;background:#000;border:1rpx solid rgba(255,255,255,.08);border-radius:9999rpx}.answer{padding:22rpx 28rpx;text-align:center;color:#fff;font-size:32rpx}.feedback{margin-top:20rpx;color:#00e3fd}.actions-cluster{display:flex;flex-direction:row;gap:18rpx;justify-content:center;align-items:center;margin-top:24rpx}.secondary-btn,.primary-btn{flex:1;border-radius:9999rpx;padding:24rpx 0;font-weight:700}.secondary-btn{background:#23262c;color:#f6f6fc}.primary-btn{background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff}.master-action{margin-top:34rpx;text-align:center}.master-text{color:#aaabb0;font-size:22rpx;border-bottom:1rpx solid transparent}.master-text.active{color:#00e3fd;border-color:#00e3fd}

1
settings/settings.js Normal file
View File

@ -0,0 +1 @@
Page({})

3
settings/settings.json Normal file
View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

55
settings/settings.wxml Normal file
View File

@ -0,0 +1,55 @@
<view class="page">
<view class="topbar">
<view class="topbar-left">
<button class="back-btn" bindtap="goBack">←</button>
<text class="brand-text">VocabMaster</text>
</view>
<view class="topbar-right">
<text class="topbar-icon">🔔</text>
<view class="avatar-shell"><image class="avatar-img" src="https://picsum.photos/260" mode="aspectFill" /></view>
</view>
</view>
<scroll-view scroll-y class="content">
<view class="header">
<text class="title">设置</text>
<text class="subtitle">调整您的学习体验与交互偏好</text>
</view>
<view class="section-block">
<view class="section-head">
<view class="section-ico">⚙</view>
<text class="section-title">复习参数</text>
</view>
<view class="panel">
<view class="row">
<view><text class="label">每日新词数量</text><text class="desc">控制每天引入的新词汇量</text></view>
<view class="value-group"><text class="value">20</text><text class="edit">✎</text></view>
</view>
<view class="row">
<view><text class="label">默认难度系数</text><text class="desc">影响算法的间隔时间计算</text></view>
<view class="value-group"><text class="value accent">中等</text><text class="edit">▾</text></view>
</view>
</view>
</view>
<view class="section-block">
<view class="section-head">
<view class="section-ico">☀</view>
<text class="section-title">交互设置</text>
</view>
<view class="panel">
<view class="row">
<view><text class="label">自动进入下一词</text><text class="desc">答题后自动跳转,保持心流状态</text></view>
<view class="toggle on">ON</view>
</view>
<view class="row">
<view><text class="label">触觉反馈</text><text class="desc">操作时的轻微震动提示</text></view>
<view class="toggle">OFF</view>
</view>
</view>
</view>
<view class="save-wrap"><button class="save-btn">保存设置</button></view>
</scroll-view>
</view>

1
settings/settings.wxss Normal file
View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.topbar-left,.topbar-right{display:flex;align-items:center;gap:18rpx}.back-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:#000;color:#aaabb0;display:flex;align-items:center;justify-content:center;border:1rpx solid rgba(255,255,255,.1)}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.topbar-icon{font-size:30rpx;color:#aaabb0}.avatar-shell{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1)}.avatar-img{width:100%;height:100%}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 32rpx;box-sizing:border-box}.header{margin-bottom:32rpx}.title{display:block;font-size:56rpx;font-weight:800;line-height:1.1}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.section-block{margin-top:28rpx}.section-head{display:flex;align-items:center;gap:14rpx;margin-bottom:18rpx}.section-ico{width:76rpx;height:76rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center;font-size:30rpx}.section-title{font-size:32rpx;font-weight:800}.panel{position:relative;padding:8rpx;border-radius:24rpx;background:rgba(17,19,24,.9);border:1rpx solid rgba(255,255,255,.1);box-shadow:0 20rpx 40rpx rgba(0,0,0,.08)}.row{display:flex;justify-content:space-between;align-items:center;padding:24rpx 20rpx;border-radius:18rpx;background:#1d2025;position:relative;overflow:hidden}.row + .row{margin-top:8rpx}.row:before{content:'';position:absolute;inset:0;border:1rpx solid rgba(255,255,255,.05);border-radius:18rpx;pointer-events:none}.label{display:block;font-size:28rpx;font-weight:600;color:#fff;margin-bottom:6rpx}.desc{display:block;font-size:22rpx;color:#aaabb0}.value-group{display:flex;align-items:center;gap:16rpx}.value{font-size:28rpx;font-weight:800;color:#c19cff}.accent{color:#00e5ff}.edit{font-size:28rpx;color:#aaabb0}.toggle{padding:10rpx 18rpx;border-radius:9999rpx;background:#23262c;color:#aaabb0;font-weight:700}.toggle.on{background:#c19cff;color:#000;box-shadow:0 0 10rpx rgba(193,156,255,.5)}.save-wrap{margin-top:34rpx}.save-btn{width:100%;border-radius:9999rpx;padding:28rpx 0;background:linear-gradient(90deg,#c19cff,#9146ff);color:#fff;font-size:32rpx;font-weight:800;box-shadow:0 0 20rpx rgba(193,156,255,.3)}

View File

@ -0,0 +1 @@
Page({})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,94 @@
<view class="page">
<view class="topbar">
<view class="brand">
<view class="avatar-wrap"><image class="avatar" src="https://picsum.photos/270" mode="aspectFill" /></view>
<text class="brand-text">VocabMaster</text>
</view>
<view class="icon-btn">🔔</view>
</view>
<scroll-view scroll-y class="content">
<view class="header">
<text class="title">词库管理</text>
<text class="subtitle">管理并策划您的个人词汇集合。</text>
</view>
<view class="search-row">
<view class="search-box">
<text class="search-icon">🔎</text>
<text class="search-placeholder">搜索单词、短语或标签...</text>
</view>
<view class="filters">
<view class="filter-btn">类型 <text class="dim">单词/句子</text> ▾</view>
<view class="filter-btn">状态 <text class="dim">全部</text> ▾</view>
</view>
</view>
<view class="card-grid">
<view class="word-card cyan">
<view class="card-top">
<view>
<text class="word-title">Ephemeral</text>
<text class="phonetic">/ɪˈfemərəl/</text>
</view>
<view class="status-dot done">✓</view>
</view>
<text class="meaning">adj. 短暂的,朝生暮死的</text>
<view class="progress-block">
<view class="progress-meta"><text>掌握度</text><text class="accent-cyan">95%</text></view>
<view class="progress-bar"><view class="fill cyan-fill"></view></view>
</view>
</view>
<view class="word-card purple wide">
<view class="card-top">
<view>
<text class="word-title">Ubiquitous</text>
<text class="phonetic">/juːˈbɪkwɪtəs/</text>
</view>
<view class="status-dot learn">✎</view>
</view>
<view class="split">
<text class="meaning">adj. 普遍存在的,无处不在的</text>
<text class="example">"Smartphones have become ubiquitous in our daily lives."</text>
</view>
<view class="progress-block">
<view class="progress-meta"><text>掌握度</text><text class="accent-purple">60%</text></view>
<view class="progress-bar"><view class="fill purple-fill"></view></view>
</view>
</view>
<view class="word-card pink">
<view class="card-top">
<view>
<text class="word-title">Obfuscate</text>
<text class="phonetic">/ˈɒbfəskeɪt/</text>
</view>
<view class="status-dot review">⟳</view>
</view>
<text class="meaning">v. 使模糊,使混乱,使费解</text>
<view class="progress-block">
<view class="progress-meta"><text>掌握度</text><text class="accent-pink">30%</text></view>
<view class="progress-bar"><view class="fill pink-fill"></view></view>
</view>
</view>
<view class="word-card cyan">
<view class="card-top">
<view>
<text class="word-title">Cacophony</text>
<text class="phonetic">/kəˈkɒfəni/</text>
</view>
<view class="status-dot done">✓</view>
</view>
<text class="meaning">n. 刺耳的声音,杂音</text>
<view class="progress-block">
<view class="progress-meta"><text>掌握度</text><text class="accent-cyan">88%</text></view>
<view class="progress-bar"><view class="fill cyan-fill" style="width:88%"></view></view>
</view>
</view>
</view>
</scroll-view>
<view class="fab"></view>
</view>

View File

@ -0,0 +1 @@
page{background:#0c0e12;color:#f6f6fc}.page{min-height:100vh;background:#0c0e12;box-sizing:border-box}.topbar{display:flex;justify-content:space-between;align-items:center;padding:24rpx 32rpx;background:rgba(12,14,18,.8);backdrop-filter:blur(24px);border-bottom:1rpx solid rgba(255,255,255,.08);box-shadow:0 1rpx 20rpx rgba(0,0,0,.08)}.brand{display:flex;align-items:center;gap:18rpx}.avatar-wrap{width:64rpx;height:64rpx;border-radius:9999rpx;overflow:hidden;border:1rpx solid rgba(255,255,255,.1);flex-shrink:0}.avatar{width:100%;height:100%}.brand-text{font-size:38rpx;font-weight:800;color:#c19cff}.icon-btn{width:72rpx;height:72rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);display:flex;align-items:center;justify-content:center}.content{height:calc(100vh - 120rpx);padding:40rpx 32rpx 32rpx;box-sizing:border-box}.header{margin-bottom:28rpx}.title{display:block;font-size:52rpx;font-weight:800}.subtitle{display:block;margin-top:10rpx;color:#aaabb0;font-size:26rpx}.search-row{display:flex;flex-direction:column;gap:18rpx;margin-bottom:28rpx}.search-box{display:flex;align-items:center;gap:12rpx;padding:22rpx 26rpx;border-radius:9999rpx;background:#000;border:1rpx solid rgba(255,255,255,.1);color:#aaabb0}.search-placeholder{font-size:24rpx}.filters{display:flex;gap:14rpx;overflow-x:auto}.filter-btn{padding:18rpx 22rpx;border-radius:9999rpx;background:#23262c;color:#f6f6fc;font-size:22rpx;white-space:nowrap}.dim{color:#aaabb0;margin:0 4rpx}.card-grid{display:grid;grid-template-columns:1fr;gap:18rpx}.word-card{position:relative;overflow:hidden;padding:28rpx;border-radius:28rpx;background:rgba(29,32,37,.56);backdrop-filter:blur(24rpx);border:1rpx solid rgba(255,255,255,.06);box-shadow:0 20rpx 40rpx rgba(0,0,0,.06)}.cyan{box-shadow:0 20rpx 40rpx rgba(0,229,255,.05)}.purple{box-shadow:0 20rpx 40rpx rgba(127,0,255,.05)}.pink{box-shadow:0 20rpx 40rpx rgba(255,64,129,.05)}.wide{min-height:280rpx}.card-top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:18rpx}.word-title{display:block;font-size:38rpx;font-weight:800}.phonetic{display:block;margin-top:8rpx;font-size:22rpx;color:#aaabb0}.status-dot{width:56rpx;height:56rpx;border-radius:9999rpx;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.06)}.done{color:#00e5ff}.learn{color:#c19cff}.review{color:#ff4081}.meaning{display:block;font-size:26rpx;color:#f6f6fc;line-height:1.6}.split{display:grid;grid-template-columns:1fr 1fr;gap:18rpx;align-items:start}.example{font-size:22rpx;color:#aaabb0;font-style:italic;border-left:4rpx solid rgba(193,156,255,.3);padding-left:14rpx;line-height:1.6}.progress-block{margin-top:22rpx;padding-top:18rpx;border-top:1rpx solid rgba(255,255,255,.05)}.progress-meta{display:flex;justify-content:space-between;font-size:20rpx;color:#aaabb0;margin-bottom:10rpx}.accent-cyan{color:#00e5ff}.accent-purple{color:#c19cff}.accent-pink{color:#ff4081}.progress-bar{height:10rpx;border-radius:9999rpx;background:#111318;overflow:hidden}.fill{height:100%;border-radius:9999rpx}.cyan-fill{width:95%;background:#00e5ff}.purple-fill{width:60%;background:#c19cff}.pink-fill{width:30%;background:#ff4081}.fab{position:fixed;right:28rpx;bottom:130rpx;width:96rpx;height:96rpx;border-radius:9999rpx;background:linear-gradient(135deg,#c19cff,#00e5ff);display:flex;align-items:center;justify-content:center;color:#fff;font-size:48rpx;box-shadow:0 0 20rpx rgba(193,156,255,.2)}