diff --git a/achievements/achievements.js b/achievements/achievements.js index f24681a..f6ca52d 100644 --- a/achievements/achievements.js +++ b/achievements/achievements.js @@ -1,14 +1,12 @@ const app = getApp() const ACHIEVEMENT_ICON_MAP = { - MASTERED_10: '/assets/icons/achievements/core/mastered-10.svg', - MASTERED_50: '/assets/icons/achievements/core/mastered-50.svg', - MASTERED_100: '/assets/icons/achievements/core/mastery-advanced.svg', - MASTERED_500: '/assets/icons/achievements/core/mastery-advanced.svg', - MASTERED_1000: '/assets/icons/achievements/core/mastery-advanced.svg', - MASTERED_2000: '/assets/icons/achievements/core/mastery-2000.svg', - MASTERED_5000: '/assets/icons/achievements/core/mastery-5000.svg', - MASTERED_10000: '/assets/icons/achievements/core/mastery-10000.svg', + 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', @@ -50,7 +48,7 @@ const GROUP_META = { } const GROUP_PROGRESS = { - mastery: [10, 50, 100, 500, 1000, 2000, 5000, 10000], + mastery: [100, 1000, 3000, 5000, 7000, 10000], checkin: [7, 30, 100, 180, 360], streak: [7, 30, 100, 180, 360], accuracy: [80, 90], diff --git a/achievements/achievements.wxss b/achievements/achievements.wxss index 06f5773..9378307 100644 --- a/achievements/achievements.wxss +++ b/achievements/achievements.wxss @@ -1 +1,287 @@ -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;box-shadow:0 0 20rpx rgba(255,64,129,.2);overflow:hidden}.hero-badge-img{width:64rpx;height:64rpx}.state-card{margin-bottom:28rpx}.state-head{display:flex;justify-content:space-between;align-items:center;margin:0 6rpx 18rpx}.state-title{font-size:36rpx;font-weight:800}.state-subtitle{font-size:22rpx;color:#aaabb0}.section-card{margin-bottom:20rpx;padding:28rpx;border-radius:30rpx;background:rgba(29,32,37,.45);border:1rpx solid rgba(255,255,255,.07);backdrop-filter:blur(24rpx)}.section-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:14rpx}.section-title-wrap{display:flex;align-items:center;gap:16rpx}.section-icon{width:52rpx;height:52rpx;border-radius:9999rpx;background:rgba(255,255,255,.06);padding:8rpx;box-sizing:border-box}.section-title{display:block;font-size:32rpx;font-weight:800;line-height:1.2}.section-subtitle{display:block;margin-top:4rpx;font-size:22rpx;color:#aaabb0}.section-count{font-size:22rpx;color:#c19cff;background:rgba(193,156,255,.12);padding:8rpx 14rpx;border-radius:9999rpx}.section-progress{display:block;margin:0 0 18rpx 68rpx;font-size:22rpx;color:#8fe3ff}.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;overflow:hidden}.item-icon-img{width:44rpx;height:44rpx}.item-title{display:block;font-size:30rpx;font-weight:700;margin-bottom:8rpx}.item-sub{display:block;font-size:22rpx;color:#aaabb0} +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; + box-shadow: 0 0 20rpx rgba(255, 64, 129, .2); + overflow: hidden +} + +.hero-badge-img { + width: 64rpx; + height: 64rpx +} + +.state-card { + margin-bottom: 28rpx +} + +.state-head { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0 6rpx 18rpx +} + +.state-title { + font-size: 36rpx; + font-weight: 800 +} + +.state-subtitle { + font-size: 22rpx; + color: #aaabb0 +} + +.section-card { + margin-bottom: 20rpx; + padding: 28rpx; + border-radius: 30rpx; + background: rgba(29, 32, 37, .45); + border: 1rpx solid rgba(255, 255, 255, .07); + backdrop-filter: blur(24rpx) +} + +.section-head { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 14rpx +} + +.section-title-wrap { + display: flex; + align-items: center; + gap: 16rpx +} + +.section-icon { + width: 52rpx; + height: 52rpx; + border-radius: 9999rpx; + background: rgba(255, 255, 255, .06); + padding: 8rpx; + box-sizing: border-box +} + +.section-title { + display: block; + font-size: 32rpx; + font-weight: 800; + line-height: 1.2 +} + +.section-subtitle { + display: block; + margin-top: 4rpx; + font-size: 22rpx; + color: #aaabb0 +} + +.section-count { + font-size: 22rpx; + color: #c19cff; + background: rgba(193, 156, 255, .12); + padding: 8rpx 14rpx; + border-radius: 9999rpx +} + +.section-progress { + display: block; + margin: 0 0 18rpx 68rpx; + font-size: 22rpx; + color: #8fe3ff +} + +.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: 130rpx; + height: 130rpx; + border-radius: 9999rpx; + background: rgba(255, 255, 255, .06); + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 24rpx; + overflow: hidden +} + +.item-icon-img { + width: 110rpx; + height: 110rpx; + flex-shrink: 0 +} + +.item-title { + display: block; + font-size: 30rpx; + font-weight: 700; + margin-bottom: 8rpx; + text-align: center +} + +.item-sub { + display: block; + font-size: 22rpx; + color: #aaabb0; + text-align: center +} \ No newline at end of file diff --git a/progress-list/progress-list.js b/progress-list/progress-list.js index 2c67ea8..2158244 100644 --- a/progress-list/progress-list.js +++ b/progress-list/progress-list.js @@ -1,7 +1,7 @@ const app = getApp() const groupByType = (list) => ({ - word: list.filter((item) => item.entry_type !== 'sentence'), + word: list.filter((item) => item.entry_type === 'word'), sentence: list.filter((item) => item.entry_type === 'sentence'), }) diff --git a/review-session/review-session.js b/review-session/review-session.js index 5f2b9c3..d250558 100644 --- a/review-session/review-session.js +++ b/review-session/review-session.js @@ -37,6 +37,7 @@ Page({ currentClozeResults: [], showClozeFeedback: false, clozeSegments: [], + clozeFeedbackSummary: '', activeClozeBlankIndex: 0, }, submitting: false, @@ -74,12 +75,13 @@ Page({ const pushWordBlank = (blankIndex, blank) => { const answerText = String(blank?.answer || '') const answerLength = Math.max(1, answerText.length || Number(blank?.hint?.length || 1)) + const blankWidth = Math.max(88, Math.min(320, 32 + answerLength * 28)) segments.push({ type: 'word-blank', blankIndex, index: `blank-${blankIndex}`, - width: `${Math.max(56, Math.min(260, 26 + answerLength * 24))}rpx`, - minWidth: `${Math.max(56, Math.min(260, 26 + answerLength * 24))}rpx`, + width: `${blankWidth}rpx`, + minWidth: `${blankWidth}rpx`, maxLength: Math.max(1, answerLength), }) } @@ -97,18 +99,8 @@ Page({ } if (blanks.length === 1 && workingPrompt === (clozeQuestion.original_text || prompt)) { - const blank = blanks[0] - const answerText = String(blank?.answer || '') - const letterSegments = answerText.split('').map((char, idx) => ({ - type: 'letter-cell', - blankIndex: 0, - letterIndex: idx, - index: `blank-0-letter-${idx}`, - width: '42rpx', - minWidth: '42rpx', - maxLength: 1, - })) - return letterSegments.length ? letterSegments : [{ type: 'word-blank', blankIndex: 0, index: 'blank-0', width: '80rpx', minWidth: '80rpx', maxLength: 1 }] + // Keep the original word context visible for single-word cloze questions. + // The general start/end slicing below will render visible letters around the blank. } let cursor = 0 @@ -190,7 +182,7 @@ Page({ word: isCloze ? (current?.blank_prompt || clozeQuestion?.prompt_text || current?.prompt || '') : (current?.prompt || ''), meaning: isCloze ? (current?.answer_hint || '') : '', answer: session.currentAnswer || '', - clozeAnswers: isCloze ? (Array.isArray(session.currentAnswers) ? session.currentAnswers : Array.from({ length: currentClozeQuestion?.blanks?.length || 0 }, () => '')) : [], + clozeAnswers: isCloze ? (Array.isArray(session.currentAnswers) ? session.currentAnswers : Array.from({ length: clozeQuestion?.blanks?.length || 0 }, () => '')) : [], activeClozeBlankIndex: 0, feedback: '', revealAnswer: '', @@ -205,6 +197,7 @@ Page({ currentClozeResults: session.lastClozeResults || [], showClozeFeedback: false, clozeSegments: isCloze ? this.buildClozeSegments(clozeQuestion) : [], + clozeFeedbackSummary: '', }) }, onAnswerInput(e) { @@ -328,11 +321,15 @@ Page({ if (current.question_mode === 'C' && clozeQuestion?.blanks?.length) { const answers = (this.data.clozeAnswers || []).map((item) => (item || '').trim()) while (answers.length < clozeQuestion.blanks.length) answers.push('') - if (!answers.some((item) => item)) { + const isLetterCellMode = Array.isArray(this.data.clozeSegments) && this.data.clozeSegments.some((segment) => segment.type === 'letter-cell') + const normalizedAnswers = isLetterCellMode + ? answers + : answers + if (!normalizedAnswers.some((item) => item)) { wx.showToast({ title: '请先输入答案', icon: 'none' }) return } - payload.user_answers = answers + payload.user_answers = normalizedAnswers } else if (!answer) { wx.showToast({ title: '请先输入答案', icon: 'none' }) return @@ -352,24 +349,55 @@ Page({ const shouldShowAnswer = showExplanation || this.data.settings.showAnswerAfterSubmit const correctAnswerText = result.correct_answer_text || '' const clozeResults = Array.isArray(result.cloze_results) ? result.cloze_results : [] - if (clozeResults.length) { - session.lastClozeResults = clozeResults - app.globalData.reviewSession.lastClozeResults = clozeResults + const fallbackClozeResults = clozeResults.length + ? clozeResults + : (this.data.currentClozeQuestion?.blanks || []).map((blank, idx) => ({ + index: typeof blank?.index === 'number' ? blank.index : idx, + user_answer: '', + correct_answers: [blank?.answer, ...(Array.isArray(blank?.accepted_answers) ? blank.accepted_answers : [])].filter(Boolean), + correct_answer_text: blank?.answer || '', + is_correct: false, + })) + const normalizedClozeResults = fallbackClozeResults.map((item, idx) => { + const correctAnswers = Array.isArray(item.correct_answers) + ? item.correct_answers.filter(Boolean) + : [item.correct_answer_text, ...(Array.isArray(item.accepted_answers) ? item.accepted_answers : [])].filter(Boolean) + const standardAnswerText = correctAnswers.join(' / ') || item.correct_answer_text || '' + return { + index: item.index ?? idx, + user_answer: item.user_answer ?? '', + correct_answers: correctAnswers, + correct_answer_text: item.correct_answer_text || standardAnswerText, + standard_answer_text: standardAnswerText, + is_correct: Boolean(item.is_correct), + } + }) + const derivedClozeResults = normalizedClozeResults.length + ? normalizedClozeResults + : (correctAnswerText + ? [{ index: 0, user_answer: '', correct_answers: [correctAnswerText], correct_answer_text: correctAnswerText, standard_answer_text: correctAnswerText, is_correct: false }] + : []) + if (derivedClozeResults.length) { + session.lastClozeResults = derivedClozeResults + app.globalData.reviewSession.lastClozeResults = derivedClozeResults } + const clozeFeedbackSummary = result.is_correct ? '回答正确' : '回答错误' this.setData({ - feedback: result.is_correct ? '回答正确' : '回答错误', + feedback: clozeFeedbackSummary, feedbackType: result.is_correct ? 'correct' : 'wrong', - revealAnswer: shouldShowAnswer && correctAnswerText ? `正确答案:${correctAnswerText}` : '', + revealAnswer: '', showFeedback: true, - showClozeFeedback: clozeResults.length > 0, - currentClozeResults: clozeResults, + showClozeFeedback: derivedClozeResults.length > 0, + currentClozeResults: derivedClozeResults, + clozeFeedbackSummary, }) if (this.data.isCloze) { app.globalData.reviewSession.currentAnswers = [] this.setData({ clozeAnswers: [] }) } if (this.data.settings.autoNextQuestion || advanceAfterSubmit) { - setTimeout(() => this.nextQuestion(), shouldShowAnswer ? 1200 : 0) + const delay = shouldShowAnswer ? 2500 : 0 + setTimeout(() => this.nextQuestion(), delay) } }, complete: () => { diff --git a/review-session/review-session.wxml b/review-session/review-session.wxml index 6988575..e8453f7 100644 --- a/review-session/review-session.wxml +++ b/review-session/review-session.wxml @@ -47,14 +47,13 @@ - {{feedback}} - {{revealAnswer}} + {{clozeFeedbackSummary || feedback}} - 空 {{blankIndex + 1}} · {{blankResult.is_correct ? '正确' : '错误'}} + 空 {{blankIndex + 1}} 你的答案:{{blankResult.user_answer || '(空)'}} - 标准答案:{{blankResult.correct_answers.join(' / ')}} + 标准答案:{{blankResult.standard_answer_text || (blankResult.correct_answers && blankResult.correct_answers.length ? blankResult.correct_answers.join(' / ') : (blankResult.correct_answer_text || '(未返回)'))}} diff --git a/review-session/review-session.wxss b/review-session/review-session.wxss index aba7fa0..0ffd469 100644 --- a/review-session/review-session.wxss +++ b/review-session/review-session.wxss @@ -1 +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}.mode-tag-wrap{display:flex;justify-content:center;margin-bottom:20rpx}.mode-tag{display:inline-flex;align-items:center;gap:10rpx;padding:10rpx 22rpx;border-radius:9999rpx;background:rgba(193,156,255,.12);border:1rpx solid rgba(193,156,255,.18);color:#d8c7ff;font-size:22rpx;letter-spacing:2rpx}.meaning-wrap{margin-bottom:28rpx}.meaning{display:block;color:#aaabb0;font-size:26rpx;letter-spacing:2rpx}.cloze-wrap,.word-wrap{margin:14rpx 0 10rpx}.cloze,.word{display:block;font-size:58rpx;font-weight:800;letter-spacing:2rpx;line-height:1.25}.cloze{color:#f6f6fc}.word{color:#f6f6fc}.entry-type-hint{margin-top:14rpx;color:#8f9198;font-size:22rpx;line-height:1.6}.inline-cloze{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:center;gap:10rpx;font-size:68rpx;font-weight:900;line-height:1.2;color:#f6f6fc;letter-spacing:1rpx}.cloze-segment-text{display:inline;white-space:pre-wrap;line-height:1.2}.cloze-blank-wrap{display:inline-flex;align-items:flex-end;justify-content:center;vertical-align:baseline;position:relative;top:2rpx}.cloze-letter-cell{display:inline-flex;flex-direction:column;align-items:center;justify-content:flex-end;vertical-align:baseline}.inline-cloze-answer{display:block;width:100%;min-width:100%;padding:0 0 4rpx;background:transparent;border:none;border-bottom:5rpx solid rgba(193,156,255,.98);border-radius:0;font-size:68rpx;font-weight:900;color:#f6f6fc;text-align:center;line-height:1.05;caret-color:#c19cff;box-sizing:border-box}.letter-cell-input{font-size:68rpx}.cloze-letter-underline{width:100%;height:0}.inline-cloze-answer::placeholder{color:transparent}.cloze-input-list{margin-top:28rpx;display:flex;flex-direction:column;gap:20rpx}.cloze-input-item{padding:20rpx 18rpx;border-radius:24rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.08);text-align:left}.cloze-input-label{display:block;margin-bottom:12rpx;color:#d8c7ff;font-size:22rpx;font-weight:700;letter-spacing:1rpx}.cloze-hint{margin-bottom:12rpx;color:#8f9198;font-size:20rpx;line-height:1.5}.input-shell{margin:26rpx auto 0;max-width:520rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.08);border-radius:9999rpx}.answer{padding:22rpx 28rpx;text-align:center;color:#f6f6fc;font-size:32rpx;caret-color:#c19cff}.cloze-answer{max-width:100%;background:rgba(12,14,18,.35);border-radius:18rpx;border:1rpx solid rgba(255,255,255,.08);text-align:left;padding:22rpx 24rpx;margin:0 4rpx}.answer::placeholder{color:rgba(170,171,176,.72)}.answer::-webkit-input-placeholder{color:rgba(170,171,176,.72)}.answer::-moz-placeholder{color:rgba(170,171,176,.72)}.answer:-ms-input-placeholder{color:rgba(170,171,176,.72)}.feedback-box{margin-top:22rpx;padding:20rpx 24rpx;border-radius:24rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.06)}.feedback{display:block;color:#00e3fd}.reveal-answer{display:block;margin-top:10rpx;color:#f6f6fc;font-weight:700}.cloze-feedback-list{margin-top:18rpx;display:flex;flex-direction:column;gap:14rpx}.cloze-feedback-item{padding:18rpx 16rpx;border-radius:18rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.06)}.cloze-feedback-title{display:block;margin-bottom:8rpx;font-size:22rpx;font-weight:700;color:#c19cff}.cloze-feedback-text{display:block;font-size:22rpx;line-height:1.55;color:#e8e9ee}.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:#00e5fd;border-color:#00e5fd} +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}.mode-tag-wrap{display:flex;justify-content:center;margin-bottom:20rpx}.mode-tag{display:inline-flex;align-items:center;gap:10rpx;padding:10rpx 22rpx;border-radius:9999rpx;background:rgba(193,156,255,.12);border:1rpx solid rgba(193,156,255,.18);color:#d8c7ff;font-size:22rpx;letter-spacing:2rpx}.meaning-wrap{margin-bottom:28rpx}.meaning{display:block;color:#aaabb0;font-size:26rpx;letter-spacing:2rpx}.cloze-wrap,.word-wrap{margin:14rpx 0 10rpx}.cloze,.word{display:block;font-size:58rpx;font-weight:800;letter-spacing:2rpx;line-height:1.25}.cloze{color:#f6f6fc}.word{color:#f6f6fc}.entry-type-hint{margin-top:14rpx;color:#8f9198;font-size:22rpx;line-height:1.6}.inline-cloze{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:center;gap:10rpx;font-size:68rpx;font-weight:900;line-height:1.2;color:#f6f6fc;letter-spacing:1rpx}.cloze-segment-text{display:inline;white-space:pre-wrap;line-height:1.2}.cloze-blank-wrap{display:inline-flex;align-items:flex-end;justify-content:center;vertical-align:baseline;position:relative;top:2rpx;overflow:visible}.cloze-letter-cell{display:inline-flex;flex-direction:column;align-items:center;justify-content:flex-end;vertical-align:baseline}.cloze-blank-wrap .inline-cloze-answer{display:block;width:100%;min-width:100%;height:1.2em;padding:0;background:transparent;border:none;border-bottom:5rpx solid rgba(193,156,255,.98);border-radius:0;font-size:inherit;line-height:1.2;font-weight:900;color:#f6f6fc;text-align:center;caret-color:#c19cff;box-sizing:border-box;transform:translateY(-2rpx);min-width:88rpx}.letter-cell-input{font-size:68rpx;line-height:1.2;height:1.2em;padding:0}.cloze-letter-underline{width:100%;height:0}.inline-cloze-answer::placeholder{color:transparent}.cloze-input-list{margin-top:28rpx;display:flex;flex-direction:column;gap:20rpx}.cloze-input-item{padding:20rpx 18rpx;border-radius:24rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.08);text-align:left}.cloze-input-label{display:block;margin-bottom:12rpx;color:#d8c7ff;font-size:22rpx;font-weight:700;letter-spacing:1rpx}.cloze-hint{margin-bottom:12rpx;color:#8f9198;font-size:20rpx;line-height:1.5}.input-shell{margin:26rpx auto 0;max-width:520rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.08);border-radius:9999rpx}.answer{padding:22rpx 28rpx;text-align:center;color:#f6f6fc;font-size:32rpx;caret-color:#c19cff}.cloze-answer{max-width:100%;background:rgba(12,14,18,.35);border-radius:18rpx;border:1rpx solid rgba(255,255,255,.08);text-align:left;padding:22rpx 24rpx;margin:0 4rpx}.answer::placeholder{color:rgba(170,171,176,.72)}.answer::-webkit-input-placeholder{color:rgba(170,171,176,.72)}.answer::-moz-placeholder{color:rgba(170,171,176,.72)}.answer:-ms-input-placeholder{color:rgba(170,171,176,.72)}.feedback-box{margin-top:22rpx;padding:20rpx 24rpx;border-radius:24rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.06)}.feedback{display:block;color:#00e3fd}.reveal-answer{display:block;margin-top:10rpx;color:#f6f6fc;font-weight:700}.cloze-feedback-list{margin-top:18rpx;display:flex;flex-direction:column;gap:14rpx}.cloze-feedback-item{padding:18rpx 16rpx;border-radius:18rpx;background:rgba(255,255,255,.04);border:1rpx solid rgba(255,255,255,.06)}.cloze-feedback-title{display:block;margin-bottom:8rpx;font-size:22rpx;font-weight:700;color:#c19cff}.cloze-feedback-text{display:block;font-size:22rpx;line-height:1.55;color:#e8e9ee}.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:#00e5fd;border-color:#00e5fd}