diff --git a/achievements/achievements.js b/achievements/achievements.js index f6ca52d..c9db8df 100644 --- a/achievements/achievements.js +++ b/achievements/achievements.js @@ -1,32 +1,36 @@ const app = getApp() +function staticIcon(path) { + return `${app.globalData.staticBaseUrl}/${path.replace(/^\/+/, '')}` +} + const ACHIEVEMENT_ICON_MAP = { - MASTERED_100: '/assets/icons/achievements/core/100.svg', - MASTERED_1000: '/assets/icons/achievements/core/1000.svg', - MASTERED_3000: '/assets/icons/achievements/core/3000.svg', - MASTERED_5000: '/assets/icons/achievements/core/5000.svg', - MASTERED_7000: '/assets/icons/achievements/core/7000.svg', - MASTERED_10000: '/assets/icons/achievements/core/10000.svg', - TOTAL_100: '/assets/icons/achievements/core/total-100.svg', - CHECKIN_7: '/assets/icons/achievements/core/checkin-30.svg', - CHECKIN_30: '/assets/icons/achievements/core/checkin-30.svg', - CHECKIN_100: '/assets/icons/achievements/core/streak.svg', - CHECKIN_180: '/assets/icons/achievements/core/streak.svg', - CHECKIN_360: '/assets/icons/achievements/core/streak.svg', - CHECKIN_STREAK_7: '/assets/icons/achievements/core/streak.svg', - CHECKIN_STREAK_30: '/assets/icons/achievements/core/streak.svg', - CHECKIN_STREAK_100: '/assets/icons/achievements/core/streak.svg', - CHECKIN_STREAK_180: '/assets/icons/achievements/core/streak.svg', - CHECKIN_STREAK_360: '/assets/icons/achievements/core/streak.svg', - ACCURACY_80: '/assets/icons/achievements/core/accuracy.svg', - ACCURACY_90: '/assets/icons/achievements/core/accuracy.svg', - DAILY_REVIEW_20: '/assets/icons/achievements/core/review-volume.svg', - DAILY_REVIEW_50: '/assets/icons/achievements/core/review-volume.svg', + MASTERED_100: staticIcon('icons/achievements/core/100.svg'), + MASTERED_1000: staticIcon('icons/achievements/core/1000.svg'), + MASTERED_3000: staticIcon('icons/achievements/core/3000.svg'), + MASTERED_5000: staticIcon('icons/achievements/core/5000.svg'), + MASTERED_7000: staticIcon('icons/achievements/core/7000.svg'), + MASTERED_10000: staticIcon('icons/achievements/core/10000.svg'), + TOTAL_100: staticIcon('icons/achievements/core/total-100.svg'), + CHECKIN_7: staticIcon('icons/achievements/core/checkin-30.svg'), + CHECKIN_30: staticIcon('icons/achievements/core/checkin-30.svg'), + CHECKIN_100: staticIcon('icons/achievements/core/streak.svg'), + CHECKIN_180: staticIcon('icons/achievements/core/streak.svg'), + CHECKIN_360: staticIcon('icons/achievements/core/streak.svg'), + CHECKIN_STREAK_7: staticIcon('icons/achievements/core/streak.svg'), + CHECKIN_STREAK_30: staticIcon('icons/achievements/core/streak.svg'), + CHECKIN_STREAK_100: staticIcon('icons/achievements/core/streak.svg'), + CHECKIN_STREAK_180: staticIcon('icons/achievements/core/streak.svg'), + CHECKIN_STREAK_360: staticIcon('icons/achievements/core/streak.svg'), + ACCURACY_80: staticIcon('icons/achievements/core/accuracy.svg'), + ACCURACY_90: staticIcon('icons/achievements/core/accuracy.svg'), + DAILY_REVIEW_20: staticIcon('icons/achievements/core/review-volume.svg'), + DAILY_REVIEW_50: staticIcon('icons/achievements/core/review-volume.svg'), } const STATUS_ICON_MAP = { - 1: '/assets/icons/achievements/state/achievement-unlocked.svg', - 0: '/assets/icons/achievements/state/achievement-locked.svg', + 1: staticIcon('icons/achievements/state/achievement-unlocked.svg'), + 0: staticIcon('icons/achievements/state/achievement-locked.svg'), } const GROUP_ORDER = { @@ -39,12 +43,12 @@ const GROUP_ORDER = { } const GROUP_META = { - mastery: { title: '掌握进阶', subtitle: '从入门到精通', icon: '/assets/icons/achievements/core/mastery-advanced.svg' }, - checkin: { title: '打卡里程', subtitle: '记录坚持的脚步', icon: '/assets/icons/achievements/core/checkin-30.svg' }, - streak: { title: '连续坚持', subtitle: '不断线的努力', icon: '/assets/icons/achievements/core/streak.svg' }, - accuracy: { title: '准确率', subtitle: '复习质量提升', icon: '/assets/icons/achievements/core/accuracy.svg' }, - review: { title: '复习数量', subtitle: '积累复习量', icon: '/assets/icons/achievements/core/review-volume.svg' }, - other: { title: '其他', subtitle: '更多成就', icon: '/assets/icons/achievements/core/total-100.svg' }, + mastery: { title: '掌握进阶', subtitle: '从入门到精通', icon: staticIcon('icons/achievements/core/mastery-advanced.svg') }, + checkin: { title: '打卡里程', subtitle: '记录坚持的脚步', icon: staticIcon('icons/achievements/core/checkin-30.svg') }, + streak: { title: '连续坚持', subtitle: '不断线的努力', icon: staticIcon('icons/achievements/core/streak.svg') }, + accuracy: { title: '准确率', subtitle: '复习质量提升', icon: staticIcon('icons/achievements/core/accuracy.svg') }, + review: { title: '复习数量', subtitle: '积累复习量', icon: staticIcon('icons/achievements/core/review-volume.svg') }, + other: { title: '其他', subtitle: '更多成就', icon: staticIcon('icons/achievements/core/total-100.svg') }, } const GROUP_PROGRESS = { diff --git a/manage/vocab-manage/vocab-manage.js b/manage/vocab-manage/vocab-manage.js deleted file mode 100644 index 42ae5e2..0000000 --- a/manage/vocab-manage/vocab-manage.js +++ /dev/null @@ -1,45 +0,0 @@ -const app = getApp() - -Page({ - data: { - list: [], - loading: false, - error: '', - }, - onShow() { - this.loadList() - }, - loadList() { - if (!app.globalData.openid) { - this.setData({ error: '请先登录' }) - return - } - this.setData({ loading: true, error: '' }) - wx.request({ - url: `${app.globalData.baseUrl}/api/v1/entries`, - header: { 'X-OpenID': app.globalData.openid }, - success: (res) => { - const payload = res.data?.data || [] - this.setData({ list: payload }) - }, - fail: () => this.setData({ error: '词库加载失败' }), - complete: () => this.setData({ loading: false }), - }) - }, - goAdd() { - wx.navigateTo({ url: '/pages/manage/entry-edit/entry-edit' }) - }, - goDetail(e) { - const { id } = e.currentTarget.dataset - wx.navigateTo({ url: `/pages/manage/entry-detail/entry-detail?id=${id}` }) - }, - goBatch() { - wx.navigateTo({ url: '/pages/manage/batch-upload/batch-upload' }) - }, - goProgress() { - wx.navigateTo({ url: '/pages/progress/progress-list/progress-list' }) - }, - goSettings() { - wx.navigateTo({ url: '/pages/settings/settings' }) - }, -}) diff --git a/manage/vocab-manage/vocab-manage.json b/manage/vocab-manage/vocab-manage.json deleted file mode 100644 index 8835af0..0000000 --- a/manage/vocab-manage/vocab-manage.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "usingComponents": {} -} \ No newline at end of file diff --git a/manage/vocab-manage/vocab-manage.wxml b/manage/vocab-manage/vocab-manage.wxml deleted file mode 100644 index d526582..0000000 --- a/manage/vocab-manage/vocab-manage.wxml +++ /dev/null @@ -1,55 +0,0 @@ - - - - 词库管理 - 管理并策划你的个人词汇集合。 - - - - - - - 🔎 - 搜索单词、短语或标签... - - - - - 加载中... - 正在同步词库数据 - - - - {{error}} - - - - 暂无词条 - 点击“新增”或“批量上传”开始构建词库 - - - - - - - - {{item.en_text}} - {{item.entry_type === 'sentence' ? '句子' : '单词'}} - - {{item.status}} - - {{item.entry_type === 'sentence' ? item.zh_text : item.zh_text}} - 例句:{{item.example_text}} - 说明:{{item.example_text}} - - - - - - - diff --git a/manage/vocab-manage/vocab-manage.wxss b/manage/vocab-manage/vocab-manage.wxss deleted file mode 100644 index eb08304..0000000 --- a/manage/vocab-manage/vocab-manage.wxss +++ /dev/null @@ -1 +0,0 @@ -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)} diff --git a/me/me.js b/me/me.js index 6a2919f..d3928c5 100644 --- a/me/me.js +++ b/me/me.js @@ -20,7 +20,7 @@ Page({ this.setData({ loading: true, error: '' }) await app.ensureLogin() if (!app.globalData.openid) { - this.setData({ loading: false, error: '登录失败,请重试' }) + this.setData({ loading: false, error: '????????' }) return } wx.request({ @@ -30,7 +30,7 @@ Page({ success: (res) => { const profile = res.data?.data || {} const avatarUrl = profile.avatar_url || wx.getStorageSync(`avatarUrl:${app.globalData.openid}`) || '' - const nickname = profile.nickname || '考研搭子' + const nickname = profile.nickname || '????' const normalizedAvatar = avatarUrl.startsWith('http') ? avatarUrl : avatarUrl ? `${app.globalData.baseUrl}${avatarUrl}` : '' this.setData({ openid: app.globalData.openid, @@ -43,7 +43,7 @@ Page({ fail: () => { const storedAvatarUrl = wx.getStorageSync(`avatarUrl:${app.globalData.openid}`) || '' const normalizedAvatar = storedAvatarUrl.startsWith('http') ? storedAvatarUrl : storedAvatarUrl ? `${app.globalData.baseUrl}${storedAvatarUrl}` : '' - this.setData({ openid: app.globalData.openid, name: '考研搭子', nickname: '考研搭子', avatarUrl: normalizedAvatar, nicknameDraft: '考研搭子' }) + this.setData({ openid: app.globalData.openid, name: '????', nickname: '????', avatarUrl: normalizedAvatar, nicknameDraft: '????' }) }, complete: () => { this.loadAchievements() @@ -52,13 +52,13 @@ Page({ }) }, openNicknameModal() { - this.setData({ showNicknameModal: true, nicknameDraft: this.data.nickname || this.data.name || '考研搭子' }) + this.setData({ showNicknameModal: true, nicknameDraft: this.data.nickname || this.data.name || '????' }) }, onAvatarError() { this.setData({ avatarUrl: '' }) }, closeNicknameModal() { - this.setData({ showNicknameModal: false, nicknameDraft: this.data.nickname || this.data.name || '考研搭子' }) + this.setData({ showNicknameModal: false, nicknameDraft: this.data.nickname || this.data.name || '????' }) }, onNicknameInput(e) { this.setData({ nicknameDraft: e.detail.value }) @@ -67,7 +67,7 @@ Page({ if (!app.globalData.openid) return const nickname = (this.data.nicknameDraft || '').trim() if (!nickname) { - wx.showToast({ title: '昵称不能为空', icon: 'none' }) + wx.showToast({ title: '??????', icon: 'none' }) return } wx.request({ @@ -79,14 +79,14 @@ Page({ const profile = res.data?.data || {} const nextNickname = profile.nickname || nickname this.setData({ nickname: nextNickname, name: nextNickname, nicknameDraft: nextNickname, showNicknameModal: false }) - wx.showToast({ title: '昵称已保存', icon: 'success' }) + wx.showToast({ title: '?????', icon: 'success' }) }, - fail: () => wx.showToast({ title: '保存失败', icon: 'none' }), + fail: () => wx.showToast({ title: '????', icon: 'none' }), }) }, chooseAvatar() { if (!app.globalData.openid) { - wx.showToast({ title: '请先登录', icon: 'none' }) + wx.showToast({ title: '????', icon: 'none' }) return } wx.chooseImage({ @@ -138,30 +138,30 @@ Page({ data: { openid: app.globalData.openid }, success: (profileRes) => { const profile = profileRes.data?.data || {} - const nextNickname = profile.nickname || '考研搭子' + const nextNickname = profile.nickname || '????' this.setData({ name: nextNickname, avatarUrl: fullUrl }) }, }) - wx.showToast({ title: '头像已上传', icon: 'success' }) + wx.showToast({ title: '?????', icon: 'success' }) } catch (err) { - wx.showToast({ title: '头像上传失败', icon: 'none' }) + wx.showToast({ title: '??????', icon: 'none' }) } }, - fail: () => wx.showToast({ title: '头像上传失败', icon: 'none' }), + fail: () => wx.showToast({ title: '??????', icon: 'none' }), }) }, - fail: () => wx.showToast({ title: '头像处理失败', icon: 'none' }), + fail: () => wx.showToast({ title: '??????', icon: 'none' }), }, this) }) }, - fail: () => wx.showToast({ title: '头像处理失败', icon: 'none' }), + fail: () => wx.showToast({ title: '??????', icon: 'none' }), }) }, }) }, loadAchievements() { if (!app.globalData.openid) { - this.setData({ error: '未获取到登录态' }) + this.setData({ error: '???????' }) return } wx.request({ @@ -172,13 +172,13 @@ Page({ const badges = Array.isArray(list) ? list.filter((i) => i.is_unlocked).length : 0 this.setData({ badges }) }, - fail: () => this.setData({ error: '成就数据加载失败' }), + fail: () => this.setData({ error: '????????' }), }) }, goTo(e) { const { url } = e.currentTarget.dataset if (!app.globalData.openid) { - wx.showToast({ title: '请先登录', icon: 'none' }) + wx.showToast({ title: '????', icon: 'none' }) return } wx.navigateTo({ url }) diff --git a/me/me.wxml b/me/me.wxml index d84bc16..f6edc78 100644 --- a/me/me.wxml +++ b/me/me.wxml @@ -1,14 +1,14 @@ - + - 登录中... - 正在获取你的登录态 + 加载中... + 正在获取个人信息 {{error}} - + @@ -16,7 +16,7 @@ - 点击更换 + 更换头像 @@ -24,24 +24,24 @@ {{name}} - 累计学习 {{days}} 天 + 坚持了 {{days}} 天 - 还没有勋章 - 完成复习和打卡后就会逐渐点亮 + 还没有解锁成就 + 继续复习和打卡,成就会逐渐点亮 - + 🏅 成就墙 - 已点亮 {{badges}} 枚勋章 + 已解锁 {{badges}} 枚勋章 - + 📅 打卡详情 @@ -56,27 +56,27 @@ - + 📚 词库管理 - + 手动新增 - + 批量上传 - + 进度列表 - + - 个性化设置 + 设置中心 @@ -97,7 +97,7 @@ 首页 - 📖复习 + 复习 我的 - + \ No newline at end of file diff --git a/vocab-manage/vocab-manage.js b/vocab-manage/vocab-manage.js deleted file mode 100644 index f67a43f..0000000 --- a/vocab-manage/vocab-manage.js +++ /dev/null @@ -1,45 +0,0 @@ -const app = getApp() - -Page({ - data: { - list: [], - loading: false, - error: '', - }, - onShow() { - this.loadList() - }, - loadList() { - if (!app.globalData.openid) { - this.setData({ error: '请先登录' }) - return - } - this.setData({ loading: true, error: '' }) - wx.request({ - url: `${app.globalData.baseUrl}/api/v1/entries`, - header: { 'X-OpenID': app.globalData.openid }, - success: (res) => { - const payload = res.data?.data || [] - this.setData({ list: payload }) - }, - fail: () => this.setData({ error: '词库加载失败' }), - complete: () => this.setData({ loading: false }), - }) - }, - goAdd() { - wx.navigateTo({ url: '/pages/entry-edit/entry-edit' }) - }, - goDetail(e) { - const { id } = e.currentTarget.dataset - wx.navigateTo({ url: `/pages/entry-detail/entry-detail?id=${id}` }) - }, - goBatch() { - wx.navigateTo({ url: '/pages/batch-upload/batch-upload' }) - }, - goProgress() { - wx.navigateTo({ url: '/pages/progress-list/progress-list' }) - }, - goSettings() { - wx.navigateTo({ url: '/pages/settings/settings' }) - }, -}) diff --git a/vocab-manage/vocab-manage.json b/vocab-manage/vocab-manage.json deleted file mode 100644 index 8835af0..0000000 --- a/vocab-manage/vocab-manage.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "usingComponents": {} -} \ No newline at end of file diff --git a/vocab-manage/vocab-manage.wxml b/vocab-manage/vocab-manage.wxml deleted file mode 100644 index d526582..0000000 --- a/vocab-manage/vocab-manage.wxml +++ /dev/null @@ -1,55 +0,0 @@ - - - - 词库管理 - 管理并策划你的个人词汇集合。 - - - - - - - 🔎 - 搜索单词、短语或标签... - - - - - 加载中... - 正在同步词库数据 - - - - {{error}} - - - - 暂无词条 - 点击“新增”或“批量上传”开始构建词库 - - - - - - - - {{item.en_text}} - {{item.entry_type === 'sentence' ? '句子' : '单词'}} - - {{item.status}} - - {{item.entry_type === 'sentence' ? item.zh_text : item.zh_text}} - 例句:{{item.example_text}} - 说明:{{item.example_text}} - - - - - - - diff --git a/vocab-manage/vocab-manage.wxss b/vocab-manage/vocab-manage.wxss deleted file mode 100644 index eb08304..0000000 --- a/vocab-manage/vocab-manage.wxss +++ /dev/null @@ -1 +0,0 @@ -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)}