<template>
  <div class="exam-panel">
    <PageHeader
      title="试卷考核"
      description="参加正式考试并查看成绩"
    />

    <StatsRow :stats="examStats" />

    <div class="sub-tabs-bar">
      <button :class="['sub-tab', { active: examTab === 'pending' }]" @click="examTab = 'pending'">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
          <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
          <polyline points="14 2 14 8 20 8"></polyline>
          <line x1="16" y1="13" x2="8" y2="13"></line>
          <line x1="16" y1="17" x2="8" y2="17"></line>
        </svg>
        待考试<span v-if="pendingPapers.length" class="tab-badge">{{ pendingPapers.length }}</span>
      </button>
      <button :class="['sub-tab', { active: examTab === 'taking' }]" @click="examTab = 'taking'" :disabled="!currentTakingPaper">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
          <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
          <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
        </svg>
        答题中
      </button>
      <button :class="['sub-tab', { active: examTab === 'results' }]" @click="loadExamResults()">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
          <rect x="3" y="3" width="7" height="7"></rect>
          <rect x="14" y="3" width="7" height="7"></rect>
          <rect x="14" y="14" width="7" height="7"></rect>
          <rect x="3" y="14" width="7" height="7"></rect>
        </svg>
        成绩单<span v-if="completedResults.length" class="tab-badge">{{ completedResults.length }}</span>
      </button>
      <button :class="['sub-tab', { active: examTab === 'selftest' }]" @click="examTab = 'selftest'">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
          <circle cx="12" cy="12" r="3"></circle>
          <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
        </svg>
        自测组卷
      </button>
    </div>

    <ContentCard v-if="examTab === 'pending'" title="待考试列表">
      <div v-if="loading" class="loading-state">加载中...</div>

      <div v-else-if="pendingPapers.length === 0" class="empty-state">
        <p>暂无待考试卷</p>
        <p class="empty-hint">等待管理员发布新的考试</p>
      </div>

      <div v-else class="paper-list">
        <div v-for="paper in pendingPapers" :key="paper.id" class="paper-item paper-item--compact">
          <div class="paper-row-main">
            <h3 class="paper-title">{{ paper.title }}</h3>
            <span class="paper-status pending">待考试</span>
          </div>
          <div class="paper-meta">
            <span>{{ paper.questionCount || 0 }}题 · {{ paper.duration || 60 }}分钟</span>
            <span v-if="paper.deadline">截止 {{ paper.deadline }}</span>
          </div>
          <div class="paper-actions">
            <button class="btn btn-primary btn-sm" @click="startExam(paper.id)">开始考试</button>
          </div>
        </div>
      </div>
    </ContentCard>

    <div v-if="examTab === 'taking' && currentTakingPaper" class="exam-taking-page">
      <div class="exam-top-bar">
        <div class="exam-title-section">
          <h2 class="exam-paper-title">{{ currentTakingPaper.title || '试卷' }}</h2>
          <span class="exam-mode-badge" v-if="isSelfTest">自测模式</span>
          <span class="exam-question-count">共 {{ totalQuestions }} 题</span>
        </div>
        <div class="exam-timer-section">
          <div :class="['timer-display', { 'timer-warning': remainingTime <= 300 && !isSelfTest }]">
            <svg class="timer-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>
            </svg>
            {{ formatTime(remainingTime) }}
          </div>
        </div>
      </div>

      <div class="exam-progress-bar">
        <div class="progress-track">
          <div class="progress-fill" :style="{ width: progressPercent + '%' }"></div>
        </div>
        <div class="progress-stats">
          <span>已答 <strong>{{ answeredCount }}</strong></span>
          <span>/</span>
          <span>未答 <strong>{{ totalQuestions - answeredCount }}</strong></span>
          <span>/</span>
          <span>标记 <strong>{{ markedCount }}</strong></span>
        </div>
      </div>

      <div class="exam-main-layout">
        <div class="question-display-area">
          <div class="qda-header">
            <div class="qda-number-row">
              <span class="qda-current-num">{{ currentIndex + 1 }}</span>
              <span class="qda-total-slash">/</span>
              <span class="qda-total-count">{{ totalQuestions }}</span>
            </div>
            <div class="qda-meta-row">
              <span :class="['type-badge', currentQuestion?.type]">{{ getTypeLabel(currentQuestion?.type) }}</span>
              <span class="qda-score">{{ currentQuestion?.maxScore || currentQuestion?.score || 5 }} 分</span>
              <button
                :class="['mark-btn', { active: isMarked }]"
                @click="toggleMark(currentIndex)"
                type="button"
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg>
                {{ isMarked ? '已标记' : '标记' }}
              </button>
            </div>
          </div>

          <div v-if="currentQuestion?.type !== 'fill_blank'" class="qda-stem">
            <p v-html="renderStem(currentQuestion?.stem)"></p>
          </div>

          <div v-if="currentQuestion?.type === 'single_choice'" class="qda-options">
            <label
              v-for="(opt, oi) in (currentQuestion?.options || [])"
              :key="oi"
              :class="['option-item', {
                selected: currentQuestion.studentAnswer === (opt.key || opt.label),
                focused: currentQuestion.studentAnswer === (opt.key || opt.label)
              }]"
              @click="selectSingle(opt)"
            >
              <span class="opt-circle" :class="{ checked: currentQuestion.studentAnswer === (opt.key || opt.label) }">
                <svg v-if="currentQuestion.studentAnswer === (opt.key || opt.label)" width="10" height="10" viewBox="0 0 24 24" fill="white"><circle cx="12" cy="12" r="6"/></svg>
              </span>
              <span class="opt-label-text">{{ opt.key || opt.label || String.fromCharCode(65 + oi) }}</span>
              <span class="opt-content-text">{{ opt.text || opt.content || opt.value || '' }}</span>
            </label>
          </div>

          <div v-if="currentQuestion?.type === 'multiple_choice'" class="qda-options">
            <label
              v-for="(opt, oi) in (currentQuestion?.options || [])"
              :key="oi"
              :class="['option-item multi', { selected: isMultiOptSelected(opt) }]"
              @click="toggleMultiOpt(opt)"
            >
              <span class="opt-square" :class="{ checked: isMultiOptSelected(opt) }">
                <svg v-if="isMultiOptSelected(opt)" width="9" height="9" viewBox="0 0 24 24" fill="white"><path d="M20 6L9 17l-5-5"/></svg>
              </span>
              <span class="opt-label-text">{{ opt.key || opt.label || String.fromCharCode(65 + oi) }}</span>
              <span class="opt-content-text">{{ opt.text || opt.content || opt.value || '' }}</span>
            </label>
          </div>

          <div v-if="currentQuestion?.type === 'true_false'" class="qda-options tf-options">
            <label
              :class="['option-item tf', { selected: currentQuestion.studentAnswer === 'T' }]"
              @click="currentQuestion.studentAnswer = 'T'"
            >
              <span class="opt-circle tf-check" :class="{ checked: currentQuestion.studentAnswer === 'T' }">
                <svg v-if="currentQuestion.studentAnswer === 'T'" width="10" height="10" viewBox="0 0 24 24" fill="white"><circle cx="12" cy="12" r="6"/></svg>
              </span>
              <span class="opt-content-text">正确</span>
            </label>
            <label
              :class="['option-item tf', { selected: currentQuestion.studentAnswer === 'F' }]"
              @click="currentQuestion.studentAnswer = 'F'"
            >
              <span class="opt-circle tf-check" :class="{ checked: currentQuestion.studentAnswer === 'F' }">
                <svg v-if="currentQuestion.studentAnswer === 'F'" width="10" height="10" viewBox="0 0 24 24" fill="white"><circle cx="12" cy="12" r="6"/></svg>
              </span>
              <span class="opt-content-text">错误</span>
            </label>
          </div>

          <div v-if="currentQuestion?.type === 'fill_blank'" class="qda-input-area fb-inline">
            <div v-if="fillBlankParts.length === 1 && fillBlankParts[0].isSingleBlankMode" class="fb-fallback">
              <p class="fb-stem-text" v-html="renderStem(currentQuestion.stem)"></p>
              <input
                type="text"
                class="fb-blank-input fb-single"
                :value="getBlankValue(0)"
                @input="setBlankValue(0, $event.target.value)"
                placeholder="请输入答案..."
              />
            </div>
            <div v-else class="fb-stem-with-blanks">
              <template v-for="(seg, si) in fillBlankParts" :key="si">
                <span v-if="seg.type === 'text'" class="fb-text" v-html="renderStem(seg.content)"></span>
                <input
                  v-else
                  type="text"
                  class="fb-blank-input"
                  :placeholder="'第' + (seg.index + 1) + '空'"
                  :value="getBlankValue(seg.index)"
                  @input="setBlankValue(seg.index, $event.target.value)"
                />
              </template>
            </div>
          </div>

          <div v-if="currentQuestion?.type === 'subjective'" class="qda-input-area">
            <textarea
              class="subjective-textarea"
              rows="5"
              placeholder="请在此处作答..."
              v-model="currentQuestion.studentAnswer"
            ></textarea>
          </div>

        </div>

        <div class="answer-card-sidebar">
          <div class="ac-header">
            <h4 class="ac-title">答题卡</h4>
          </div>
          <div class="ac-legend">
            <span class="legend-item"><i class="dot dot-current"></i> 当前</span>
            <span class="legend-item"><i class="dot dot-answered"></i> 已答</span>
            <span class="legend-item"><i class="dot dot-marked"></i> 标记</span>
            <span class="legend-item"><i class="dot dot-unanswered"></i> 未答</span>
          </div>
          <div class="ac-grid">
            <button
              v-for="(q, qi) in currentTakingPaper.questions"
              :key="qi"
              :class="['ac-cell', getCardCellClass(q, qi)]"
              @click="jumpTo(qi)"
              type="button"
            >
              {{ qi + 1 }}
            </button>
          </div>
          <div class="ac-summary">
            <div class="ac-stat">
              <span class="ac-stat-label">总题数</span>
              <span class="ac-stat-value">{{ totalQuestions }}</span>
            </div>
            <div class="ac-stat">
              <span class="ac-stat-label">已答</span>
              <span class="ac-stat-value answered">{{ answeredCount }}</span>
            </div>
            <div class="ac-stat">
              <span class="ac-stat-label">未答</span>
              <span class="ac-stat-value unanswered">{{ totalQuestions - answeredCount }}</span>
            </div>
            <div class="ac-stat">
              <span class="ac-stat-label">标记</span>
              <span class="ac-stat-value marked">{{ markedCount }}</span>
            </div>
          </div>
        </div>
      </div>

      <div class="exam-bottom-bar">
        <div class="bottom-left">
          <button class="btn-exit" @click="confirmExit()" type="button">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
            退出考试
          </button>
        </div>
        <div class="bottom-center">
          <button class="btn-action prev" @click="goPrev()" :disabled="currentIndex === 0" type="button">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"/></svg>
            上一题
          </button>
          <button class="btn-action next" @click="goNext()" :disabled="currentIndex >= totalQuestions - 1" type="button">
            下一题
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
          </button>
        </div>
        <div class="bottom-right">
          <button class="btn-submit" @click="confirmSubmit()" type="button">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 11 12 14 22 4"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/></svg>
            提交答案
          </button>
        </div>
      </div>
    </div>

    <ContentCard v-if="examTab === 'results'" title="成绩单">
      <div v-if="loading" class="loading-state">加载中...</div>

      <div v-else-if="completedResults.length === 0" class="empty-state">
        <p>暂无成绩记录</p>
      </div>

      <div v-else class="results-list">
        <div
          v-for="result in completedResults"
          :key="result.id"
          class="result-item result-item--compact"
          @click="viewExamDetail(result.recordId, result.paperId)"
        >
          <div class="paper-row-main">
            <h3 class="paper-title">{{ result.paperTitle }}</h3>
            <span :class="['grade-badge', getGradeClass(result.score)]">{{ result.score }}分</span>
          </div>
          <div class="result-meta">
            <span>正确率 {{ result.accuracy || 0 }}%</span>
            <span>{{ result.timeUsed || 0 }}分钟</span>
            <span>{{ result.completedAt }}</span>
          </div>
        </div>
      </div>
    </ContentCard>

    <div v-if="examTab === 'detail'" class="result-review-page">
      <div v-if="examDetailLoading" class="loading-state">
        <div class="loading-spinner"></div>
        <p>正在获取考试详情...</p>
      </div>

      <div v-else-if="examDetailError && !examDetailData" class="empty-state">
        <p>{{ examDetailError }}</p>
        <button class="btn btn-back" @click="closeExamDetail" style="margin-top: 12px;">返回成绩单</button>
      </div>

      <div v-else-if="!examDetailData" class="empty-state">
        <p>无法加载考试详情</p>
        <button class="btn btn-back" @click="closeExamDetail" style="margin-top: 12px;">返回成绩单</button>
      </div>

      <template v-else>
        <div class="rr-top-bar">
          <div class="rr-title-section">
            <button class="btn btn-back" @click="closeExamDetail">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="15 18 9 12 15 6"></polyline></svg>
              返回
            </button>
            <h2 class="rr-paper-title">{{ examDetailData.paperTitle }}</h2>
          </div>
          <div class="rr-score-section">
            <span class="rr-total-score">{{ examDetailData.totalScore }}</span>
            <span class="rr-max-score">/ {{ examDetailData.totalMaxScore || '-' }} 分</span>
            <span v-if="examDetailData.scoreRate" class="rr-rate-badge">
              得分率 {{ Math.round(Number(examDetailData.scoreRate)) }}%
            </span>
          </div>
        </div>

        <div class="rr-main-layout">
          <div class="rr-question-area">
            <div v-if="currentDetailQuestion" class="rrq-card">
              <div class="rrq-header">
                <span class="rrq-number">第{{ detailQuestionIndex + 1 }}题</span>
                <span :class="['type-badge', currentDetailQuestion.questionType]">{{ getTypeLabel(currentDetailQuestion.questionType) }}</span>
                <span v-if="currentDetailQuestion.isCorrect === true" class="dq-status correct">正确</span>
                <span v-else-if="currentDetailQuestion.isCorrect === false" class="dq-status wrong">错误</span>
                <span v-else class="dq-status pending">待批阅</span>
              </div>

              <div class="rrq-stem" v-html="getStem(currentDetailQuestion) || '（题目内容暂不可用）'"></div>

              <div v-if="isChoiceType(currentDetailQuestion.questionType)" class="rrq-options">
                <div
                  v-for="(opt, oi) in getOptions(currentDetailQuestion)"
                  :key="oi"
                  :class="['rrq-option', {
                    'is-selected': isStudentSelected(opt, currentDetailQuestion),
                    'is-correct-answer': isCorrectAnswer(opt, currentDetailQuestion),
                    'is-wrong-selection': isStudentSelected(opt, currentDetailQuestion) && !isCorrectAnswer(opt, currentDetailQuestion)
                  }]"
                >
                  <span class="rrq-opt-key">{{ opt.key || opt.label || String.fromCharCode(65 + oi) }}</span>
                  <span class="rrq-opt-text">{{ opt.text || opt.content || opt.value || opt }}</span>
                  <span v-if="isStudentSelected(opt, currentDetailQuestion) && isCorrectAnswer(opt, currentDetailQuestion)" class="rrq-opt-mark correct">✓</span>
                  <span v-else-if="isStudentSelected(opt, currentDetailQuestion) && !isCorrectAnswer(opt, currentDetailQuestion)" class="rrq-opt-mark wrong">✗</span>
                  <span v-else-if="isCorrectAnswer(opt, currentDetailQuestion) && currentDetailQuestion.isCorrect === false" class="rrq-opt-mark missed">●</span>
                </div>
              </div>

              <div class="rrq-answer-block">
                <div class="rrq-answer-row">
                  <span class="answer-label">你的答案:</span>
                  <span :class="['answer-value', currentDetailQuestion.isCorrect === false ? 'text-wrong' : 'text-correct']">{{ formatAnswer(currentDetailQuestion.studentAnswer, currentDetailQuestion.questionType) }}</span>
                </div>
                <div class="rrq-answer-row">
                  <span class="answer-label">正确答案:</span>
                  <span class="answer-value text-correct">{{ formatAnswer(currentDetailQuestion.correctAnswer, currentDetailQuestion.questionType) }}</span>
                </div>
              </div>

              <div class="rrq-score-row">
                <span class="score-label">得分:</span>
                <span :class="['score-value', currentDetailQuestion.isCorrect === false ? 'text-wrong' : 'text-correct']">{{ currentDetailQuestion.score }} / {{ currentDetailQuestion.maxScore ?? '-' }} 分</span>
              </div>

              <div v-if="getQuestionAnalysis(currentDetailQuestion)" class="rrq-analysis">
                <svg class="analysis-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <circle cx="12" cy="12" r="10"/>
                  <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
                  <line x1="12" y1="17" x2="12.01" y2="17"/>
                </svg>
                <span class="analysis-label">题目解析</span>
              </div>
              <div v-if="getQuestionAnalysis(currentDetailQuestion)" class="rrq-explanation rrq-analysis-content">
                <span class="explanation-text">{{ getQuestionAnalysis(currentDetailQuestion) }}</span>
              </div>

              <div v-if="!getQuestionAnalysis(currentDetailQuestion) && !currentDetailQuestion.feedback" class="rrq-no-analysis">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/>
                </svg>
                <span>暂无题目解析</span>
              </div>
            </div>
          </div>

          <div class="rr-sidebar">
            <div class="rrs-header">
              <h4 class="rrs-title">答题卡</h4>
            </div>
            <div class="rrs-legend">
              <span class="legend-item"><i class="dot dot-correct"></i>正确</span>
              <span class="legend-item"><i class="dot dot-wrong"></i>错误</span>
              <span class="legend-item"><i class="dot dot-pending"></i>待批阅</span>
            </div>
            <div class="rrs-grid">
              <button
                v-for="(q, qi) in examDetailData.questions"
                :key="qi"
                :class="['rrs-cell', getReviewCellClass(q), { active: detailQuestionIndex === qi }]"
                @click="selectDetailQuestion(qi)"
                type="button"
              >
                {{ qi + 1 }}
              </button>
            </div>
            <div class="rrs-summary">
              <div class="rrs-stat">
                <span class="rrs-stat-label">总题数</span>
                <span class="rrs-stat-value">{{ examDetailData.questions.length }}</span>
              </div>
              <div class="rrs-stat">
                <span class="rrs-stat-label">正确</span>
                <span class="rrs-stat-value stat-correct">{{ detailStats.correctCount }}</span>
              </div>
              <div class="rrs-stat">
                <span class="rrs-stat-label">错误</span>
                <span class="rrs-stat-value stat-wrong">{{ detailStats.wrongCount }}</span>
              </div>
              <div class="rrs-stat">
                <span class="rrs-stat-label">待批阅</span>
                <span class="rrs-stat-value stat-pending">{{ detailStats.pendingCount }}</span>
              </div>
            </div>
          </div>
        </div>
      </template>
    </div>

    <ContentCard v-if="examTab === 'selftest'" title="自测组卷">
      <div class="selftest-form">
        <div class="selftest-desc">
          根据以下配置从题库中随机抽取题目组成自测试卷
        </div>

        <div class="form-section">
          <h4 class="section-title">选择题型数量</h4>
          <div class="form-row count-row">
            <div class="form-item">
              <label class="form-label">单选题</label>
              <input type="number" class="form-input" min="0" max="50" v-model.number="selftestConfig.singleChoiceCount" />
            </div>
            <div class="form-item">
              <label class="form-label">多选题</label>
              <input type="number" class="form-input" min="0" max="50" v-model.number="selftestConfig.multipleChoiceCount" />
            </div>
            <div class="form-item">
              <label class="form-label">判断题</label>
              <input type="number" class="form-input" min="0" max="50" v-model.number="selftestConfig.trueFalseCount" />
            </div>
            <div class="form-item">
              <label class="form-label">填空题</label>
              <input type="number" class="form-input" min="0" max="50" v-model.number="selftestConfig.fillBlankCount" />
            </div>
            <div class="form-item">
              <label class="form-label">简答题</label>
              <input type="number" class="form-input" min="0" max="50" v-model.number="selftestConfig.subjectiveCount" />
            </div>
          </div>
        </div>

        <div class="form-section">
          <h4 class="section-title">难度设置</h4>
          <div class="form-row">
            <div class="form-item">
              <label class="form-label">难度等级</label>
              <select v-model.number="selftestConfig.difficulty" class="form-select">
                <option :value="1">简单</option>
                <option :value="2">中等</option>
                <option :value="3">困难</option>
              </select>
            </div>
          </div>
        </div>

        <div class="form-actions">
          <button class="btn btn-primary" @click="startSelftest()" :disabled="isGeneratingSelftest">
            <span v-if="isGeneratingSelftest" class="btn-loading-icon"></span>
            {{ isGeneratingSelftest ? '正在生成...' : '生成自测试卷' }}
          </button>
        </div>
      </div>
    </ContentCard>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import PageHeader from '../common/PageHeader.vue'
import StatsRow from '../common/StatsRow.vue'
import ContentCard from '../common/ContentCard.vue'
import { useExam } from './composables/useExam.js'

const {
  examTab,
  pendingPapers,
  currentTakingPaper,
  completedResults,
  loading,
  examStats,
  examDetailData,
  examDetailLoading,
  examDetailError,
  selftestConfig,
  isGeneratingSelftest,
  isSelfTest,
  loadPendingPapers,
  startExam,
  startSelftest,
  submitExam,
  loadExamResults,
  viewExamDetail,
  closeExamDetail
} = useExam()

onMounted(() => {
  loadPendingPapers()
})

const currentIndex = ref(0)
const markedSet = ref(new Set())
let timerInterval = null
const detailQuestionIndex = ref(0)

const startTimer = () => {
  if (timerInterval) clearInterval(timerInterval)
  if (isSelfTest.value) return
  timerInterval = setInterval(() => {
    if (currentTakingPaper.value && currentTakingPaper.value.remainingTime > 0) {
      currentTakingPaper.value.remainingTime--
      if (currentTakingPaper.value.remainingTime <= 0) {
        clearInterval(timerInterval)
        timerInterval = null
        submitExam()
      }
    }
  }, 1000)
}

const stopTimer = () => {
  if (timerInterval) { clearInterval(timerInterval); timerInterval = null }
}

onBeforeUnmount(() => { stopTimer() })

watch(examTab, (newVal) => {
  if (newVal === 'taking') {
    currentIndex.value = 0
    markedSet.value = new Set()
    setTimeout(() => { startTimer() }, 100)
  } else {
    stopTimer()
  }
})

const totalQuestions = computed(() => currentTakingPaper.value?.questions?.length || 0)

const currentQuestion = computed(() => {
  const qs = currentTakingPaper.value?.questions
  return qs && currentIndex.value < qs.length ? qs[currentIndex.value] : null
})

const progressPercent = computed(() => totalQuestions.value > 0 ? Math.round((answeredCount.value / totalQuestions.value) * 100) : 0)

const markedCount = computed(() => markedSet.value.size)

const isMarked = computed(() => markedSet.value.has(currentIndex.value))

const remainingTime = computed(() => currentTakingPaper.value?.remainingTime || 3600)

const goPrev = () => { if (currentIndex.value > 0) currentIndex.value-- }
const goNext = () => { if (currentIndex.value < totalQuestions.value - 1) currentIndex.value++ }
const jumpTo = (idx) => {
  if (idx >= 0 && idx < totalQuestions.value) currentIndex.value = idx
}

const toggleMark = (idx) => {
  const s = new Set(markedSet.value)
  if (s.has(idx)) s.delete(idx)
  else s.add(idx)
  markedSet.value = s
}

const selectSingle = (opt) => {
  if (currentQuestion.value) {
    const val = opt.key || opt.label || ''
    currentQuestion.value.studentAnswer = val
    console.log('[答题] 单选已选择:', val, '题目ID:', (currentQuestion.value.questionId || '').substring(0, 8))
  }
}

const isMultiOptSelected = (opt) => {
  if (!currentQuestion.value?.studentAnswer) return false
  const key = String(opt.key || opt.label).trim()
  if (Array.isArray(currentQuestion.value.studentAnswer))
    return currentQuestion.value.studentAnswer.some(a => String(a).trim() === key)
  return String(currentQuestion.value.studentAnswer).split(',').map(s => s.trim()).includes(key)
}

const toggleMultiOpt = (opt) => {
  if (!currentQuestion.value) return
  let arr = currentQuestion.value.studentAnswer
  if (!arr) { arr = [] }
  else if (typeof arr === 'string') { arr = arr.split(',').map(s => s.trim()).filter(Boolean) }
  else if (!Array.isArray(arr)) { arr = [String(arr)] }
  const key = String(opt.key || opt.label).trim()
  const idx = arr.indexOf(key)
  if (idx >= 0) arr.splice(idx, 1)
  else arr.push(key)
  currentQuestion.value.studentAnswer = [...arr]
}

const getCardCellClass = (q, idx) => {
  const classes = []
  if (idx === currentIndex.value) classes.push('current')
  if (markedSet.value.has(idx)) classes.push('marked')
  if (q.studentAnswer != null && q.studentAnswer !== '' &&
      !(Array.isArray(q.studentAnswer) && q.studentAnswer.length === 0)) classes.push('answered')
  if ((q.studentAnswer == null || q.studentAnswer === '') ||
      (Array.isArray(q.studentAnswer) && q.studentAnswer.length === 0)) classes.push('unanswered')
  return classes.join(' ')
}

const renderStem = (stem) => {
  if (!stem) return ''
  return String(stem)
    .replace(/\n/g, '<br>')
    .replace(/ /g, '&nbsp;')
}

const confirmSubmit = () => {
  const unanswered = totalQuestions.value - answeredCount.value
  let msg = '确定要提交答案吗？'
  if (unanswered > 0) msg += `\n还有 ${unanswered} 道题未作答。`
  if (markedCount.value > 0) msg += `\n有 ${markedCount.value} 道标记题目。`
  if (window.confirm(msg)) {
    stopTimer()
    submitExam()
  }
}

const confirmExit = () => {
  if (window.confirm('确定要退出考试吗？已作答的答案将不会保存。')) {
    stopTimer()
    examTab.value = 'pending'
    currentIndex.value = 0
    markedSet.value = new Set()
  }
}

const _blankRe = /_{2,}|\(\s*\)|（\s*）|\[\s*\]|<blank(?:\s[^>]*)?>|___+|…+/g

const fillBlankParts = computed(() => {
  const stem = currentQuestion.value?.stem || ''
  if (!stem) return [{ type: 'text', content: '' }]
  const parts = []
  let lastIndex = 0
  let blankIndex = 0
  let match
  const re = new RegExp(_blankRe.source, _blankRe.flags)
  re.lastIndex = 0
  while ((match = re.exec(stem)) !== null) {
    if (match.index > lastIndex) {
      parts.push({ type: 'text', content: stem.substring(lastIndex, match.index) })
    }
    parts.push({ type: 'blank', index: blankIndex++ })
    lastIndex = match.index + match[0].length
  }
  if (lastIndex < stem.length) {
    parts.push({ type: 'text', content: stem.substring(lastIndex) })
  }
  if (parts.length === 0) parts.push({ type: 'text', content: stem })
  if (blankIndex === 0 && !re.test(stem)) return [{ type: 'text', content: stem, isSingleBlankMode: true }]
  return parts
})

const _ensureBlankArray = () => {
  if (!currentQuestion.value) return []
  let ans = currentQuestion.value.studentAnswer
  if (!ans) { currentQuestion.value.studentAnswer = []; return [] }
  if (Array.isArray(ans)) return ans
  if (typeof ans === 'string') {
    const arr = ans.split('|').map(s => s.trim()).filter(Boolean)
    currentQuestion.value.studentAnswer = arr.length > 1 ? arr : [ans]
    return currentQuestion.value.studentAnswer
  }
  currentQuestion.value.studentAnswer = [String(ans)]
  return currentQuestion.value.studentAnswer
}

const getBlankValue = (idx) => {
  const arr = _ensureBlankArray()
  return arr[idx] || ''
}

const setBlankValue = (idx, val) => {
  const arr = _ensureBlankArray()
  while (arr.length <= idx) arr.push('')
  arr[idx] = val
  currentQuestion.value.studentAnswer = [...arr]
}

const formatTime = (seconds) => {
  const h = Math.floor(seconds / 3600)
  const m = Math.floor((seconds % 3600) / 60)
  const s = seconds % 60
  return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`
}

const getTypeLabel = (type) => {
  const typeMap = {
    single_choice: '单选',
    multiple_choice: '多选',
    true_false: '判断',
    fill_blank: '填空',
    subjective: '简答'
  }
  return typeMap[type] || type || '未知'
}

const getGradeClass = (score) => {
  if (score >= 90) return 'excellent'
  if (score >= 80) return 'good'
  if (score >= 60) return 'pass'
  return 'fail'
}

const isMultiSelected = (studentAnswer, key) => {
  if (!studentAnswer) return false
  if (Array.isArray(studentAnswer)) return studentAnswer.includes(key)
  return String(studentAnswer).split(',').map(s => s.trim()).includes(key)
}

const toggleMultiSelect = (q, key) => {
  let current = q.studentAnswer
  if (!current) {
    current = []
  } else if (typeof current === 'string') {
    current = current.split(',').map(s => s.trim()).filter(Boolean)
  } else if (!Array.isArray(current)) {
    current = [String(current)]
  }
  const idx = current.indexOf(key)
  if (idx >= 0) {
    current.splice(idx, 1)
  } else {
    current.push(key)
  }
  q.studentAnswer = current
}

const answeredCount = computed(() => {
  if (!currentTakingPaper.value?.questions) return 0
  return currentTakingPaper.value.questions.filter(q => {
    if (Array.isArray(q.studentAnswer)) return q.studentAnswer.length > 0
    return q.studentAnswer != null && q.studentAnswer !== ''
  }).length
})

const currentDetailQuestion = computed(() => {
  const qs = examDetailData.value?.questions
  return qs && detailQuestionIndex.value < qs.length ? qs[detailQuestionIndex.value] : null
})

const detailStats = computed(() => {
  const questions = examDetailData.value?.questions || []
  let correctCount = 0, wrongCount = 0, pendingCount = 0
  questions.forEach(q => {
    if (q.isCorrect === true) correctCount++
    else if (q.isCorrect === false) wrongCount++
    else pendingCount++
  })
  return { correctCount, wrongCount, pendingCount }
})

const selectDetailQuestion = (index) => {
  if (index >= 0 && index < (examDetailData.value?.questions?.length || 0)) {
    detailQuestionIndex.value = index
  }
}

const getReviewCellClass = (q) => {
  if (q.isCorrect === true) return 'cell-correct'
  if (q.isCorrect === false) return 'cell-wrong'
  return 'cell-pending'
}

const getStem = (q) => {
  if (!q) return ''
  let c = q.content || {}
  if (typeof c === 'string') {
    try { c = JSON.parse(c) } catch (e) { return c }
  }
  return c.stem || c.question || q.stem || ''
}

const getOptions = (q) => {
  if (!q) return []
  let c = q.content || {}
  if (typeof c === 'string') {
    try { c = JSON.parse(c) } catch (e) { c = {} }
  }
  const data = c.data || c.optionsData || {}
  let options = data.options || c.options || q.options || []
  if (Array.isArray(options)) return options
  if (typeof options === 'object' && options !== null) {
    return Object.keys(options).map(k => ({ key: k, text: options[k] }))
  }
  return []
}

const isChoiceType = (type) => {
  return type === 'single_choice' || type === 'multiple_choice'
}

const getQuestionAnalysis = (q) => {
  if (!q) return ''
  let c = q.content || {}
  if (typeof c === 'string') {
    try { c = JSON.parse(c) } catch (e) { return c }
  }
  const data = c.data || c
  return data.analysis || data.解析 || data.explanation || data.answerAnalysis
    || c.analysis || c.解析 || c.explanation || c.answerAnalysis
    || q.analysis || q.questionAnalysis || q.question_analysis || ''
}

const normalizeStudentAnswer = (answer, questionType) => {
  if (answer === null || answer === undefined) return []
  if (Array.isArray(answer)) return answer.map(String)
  if (typeof answer === 'string') {
    if (questionType === 'multiple_choice') {
      return answer.split(',').map(s => s.trim()).filter(Boolean)
    }
    return [answer.trim()]
  }
  if (typeof answer === 'boolean') {
    return [answer ? 'T' : 'F']
  }
  return [String(answer)]
}

const isStudentSelected = (opt, q) => {
  const key = String(opt.key || opt.label || opt).trim()
  const studentAnswers = normalizeStudentAnswer(q.studentAnswer, q.questionType)
  return studentAnswers.some(a => a === key || a.toUpperCase() === key.toUpperCase())
}

const isCorrectAnswer = (opt, q) => {
  const key = String(opt.key || opt.label || opt).trim()
  const correctAnswers = normalizeStudentAnswer(q.correctAnswer, q.questionType)
  return correctAnswers.some(a => a === key || a.toUpperCase() === key.toUpperCase())
}

const formatAnswer = (answer, questionType) => {
  if (answer === null || answer === undefined) return '未作答'
  // 处理 Python None 序列化为字符串的情况
  if (typeof answer === 'string' && answer.trim().toLowerCase() === 'none') return '未作答'
  if (typeof answer === 'string' && answer.trim().toLowerCase() === 'null') return '未作答'
  if (Array.isArray(answer)) {
    if (answer.length === 0) return '未作答'
    return answer.join(', ')
  }
  if (typeof answer === 'boolean') {
    return answer ? '正确' : '错误'
  }
  const str = String(answer)
  if (!str.trim()) return '未作答'
  if (questionType === 'true_false') {
    if (str.toUpperCase() === 'T' || str === 'true') return '正确'
    if (str.toUpperCase() === 'F' || str === 'false') return '错误'
  }
  return str
}
</script>

<style scoped>
.exam-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 16px;
  overflow-y: auto;
  overflow-x: hidden;
  min-width: 0;
}

.sub-tabs-bar {
  display: flex;
  gap: 4px;
  margin-bottom: 12px;
  padding: 8px 12px;
  background: #FFFFFF;
  border-radius: 8px;
  border: 1px solid #E9ECEF;
  flex-wrap: wrap;
  align-items: center;
}

.sub-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px 14px;
  border: none;
  border-radius: 6px;
  background: transparent;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s ease;
  color: #495057;
  min-height: 36px;
  line-height: 1.5;
  white-space: nowrap;
}

.sub-tab:hover:not(:disabled) {
  color: #212529;
  background: #F1F3F5;
}

.sub-tab.active {
  background: #F1F3F5;
  color: #212529;
  font-weight: 600;
}

.sub-tab:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.tab-badge {
  margin-left: 4px;
  padding: 2px 6px;
  background: #E9ECEF;
  color: #495057;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  min-width: 18px;
  text-align: center;
}

.sub-tab.active .tab-badge {
  background: #ADB5BD;
  color: #212529;
}

.loading-state,
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 20px;
  color: #6C757D;
  min-height: 200px;
}

.empty-state p {
  font-size: 14px;
  font-weight: 500;
  color: #495057;
  margin-bottom: 4px;
}

.empty-hint {
  font-size: 12px;
  color: #6C757D;
  margin-top: 8px;
  max-width: 360px;
  text-align: center;
  line-height: 1.5;
}

.paper-list,
.results-list,
.wrong-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.paper-item,
.result-item {
  padding: 16px;
  background: #FFFFFF;
  border: 1px solid #E9ECEF;
  border-radius: 8px;
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
  cursor: pointer;
}

.wrong-item {
  padding: 16px;
  background: #FFFFFF;
  border: 1px solid #E9ECEF;
  border-radius: 8px;
}

.result-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  border-color: #ADB5BD;
}

.result-item:active {
  background: #F8F9FA;
}

.result-click-hint {
  margin-top: 8px;
  font-size: 11px;
  color: #ADB5BD;
  text-align: right;
}

.detail-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.detail-header {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 16px;
  background: #F8F9FA;
  border-radius: 8px;
  border: 1px solid #E9ECEF;
}

.detail-header .btn-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border: 1px solid #DEE2E6;
  border-radius: 6px;
  background: #FFFFFF;
  font-size: 12px;
  color: #495057;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  transition: all 0.15s ease;
}

.detail-header .btn-back:hover {
  background: #F1F3F5;
  border-color: #ADB5BD;
  color: #212529;
}

.detail-summary {
  flex: 1;
  min-width: 0;
}

.detail-summary h3 {
  margin: 0 0 8px 0;
  font-size: 15px;
  font-weight: 600;
  color: #212529;
}

.detail-stats {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.stat-item {
  font-size: 12px;
  color: #495057;
  padding: 2px 8px;
  background: #FFFFFF;
  border-radius: 4px;
  border: 1px solid #E9ECEF;
}

.stat-item strong {
  color: #212529;
}

.detail-questions {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.detail-question-item {
  padding: 16px;
  background: #FFFFFF;
  border: 1px solid #E9ECEF;
  border-radius: 8px;
  border-left: 3px solid #DEE2E6;
  transition: box-shadow 0.15s ease;
}

.detail-question-item.is-correct {
  border-left-color: #2B8A3E;
}

.detail-question-item.is-wrong {
  border-left-color: #C92A2A;
}

.dq-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid #E9ECEF;
}

.dq-number {
  font-weight: 600;
  font-size: 13px;
  color: #212529;
  background: #F8F9FA;
  padding: 2px 8px;
  border-radius: 4px;
}

.dq-status {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  margin-left: auto;
}

.dq-status.correct {
  background: #EBFBEE;
  color: #2B8A3E;
  border: 1px solid #D3F9D8;
}

.dq-status.wrong {
  background: #FFF5F5;
  color: #C92A2A;
  border: 1px solid #FFD6D6;
}

.dq-status.pending {
  background: #FFF9DB;
  color: #E67700;
  border: 1px solid #FFE066;
}

.dq-stem {
  font-size: 14px;
  line-height: 1.6;
  color: #212529;
  margin-bottom: 12px;
  padding: 10px 12px;
  background: #F8F9FA;
  border-radius: 6px;
  font-weight: 400;
}

.dq-options {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
}

.dq-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  background: #F8F9FA;
  border: 1px solid #E9ECEF;
  transition: all 0.15s ease;
}

.dq-option.is-selected {
  background: #E7F5FF;
  border-color: #74C0FC;
}

.dq-option.is-correct-answer {
  background: #EBFBEE;
  border-color: #69DB7C;
}

.dq-option.is-wrong-selection {
  background: #FFF5F5;
  border-color: #FF8787;
}

.dq-opt-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 4px;
  font-weight: 600;
  font-size: 12px;
  background: #DEE2E6;
  color: #495057;
  flex-shrink: 0;
}

.dq-option.is-selected .dq-opt-key {
  background: #74C0FC;
  color: #FFFFFF;
}

.dq-option.is-correct-answer .dq-opt-key {
  background: #69DB7C;
  color: #FFFFFF;
}

.dq-option.is-wrong-selection .dq-opt-key {
  background: #FF8787;
  color: #FFFFFF;
}

.dq-opt-text {
  flex: 1;
  color: #212529;
}

.dq-opt-mark {
  font-size: 14px;
  font-weight: 600;
  flex-shrink: 0;
}

.dq-opt-mark.correct {
  color: #2B8A3E;
}

.dq-opt-mark.wrong {
  color: #C92A2A;
}

.dq-opt-mark.missed {
  color: #E67700;
}

.dq-answers {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 8px;
  padding: 10px 12px;
  background: #F8F9FA;
  border-radius: 6px;
  border: 1px solid #E9ECEF;
}

.dq-answer-row {
  display: flex;
  gap: 8px;
  font-size: 13px;
}

.answer-label {
  color: #495057;
  font-weight: 500;
  flex-shrink: 0;
  min-width: 60px;
}

.answer-value {
  font-weight: 600;
  word-break: break-all;
}

.text-correct {
  color: #2B8A3E;
}

.text-wrong {
  color: #C92A2A;
}

.dq-score-row {
  display: flex;
  gap: 8px;
  font-size: 13px;
  padding: 6px 12px;
  background: #F8F9FA;
  border-radius: 4px;
  margin-bottom: 8px;
}

.score-label {
  color: #495057;
  font-weight: 500;
}

.score-value {
  font-weight: 600;
}

.loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid #E9ECEF;
  border-top-color: #228BE6;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  margin: 0 auto 12px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 16px;
  color: #868E96;
  font-size: 14px;
}

.paper-header,
.result-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid #E9ECEF;
}

.paper-title {
  font-size: 14px;
  font-weight: 600;
  color: #212529;
  margin: 0;
}

.paper-status,
.grade-badge {
  padding: 2px 10px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
}

.paper-status.pending {
  background: #FFF9DB;
  color: #E67700;
  border: 1px solid #FFE066;
}

.grade-badge.excellent {
  background: #EBFBEE;
  color: #2B8A3E;
  border: 1px solid #D3F9D8;
}

.grade-badge.good {
  background: #E7F5FF;
  color: #1C7ED6;
  border: 1px solid #BDE0FE;
}

.grade-badge.pass {
  background: #FFF9DB;
  color: #E67700;
  border: 1px solid #FFE066;
}

.grade-badge.fail {
  background: #FFF5F5;
  color: #C92A2A;
  border: 1px solid #FFD6D6;
}

.paper-meta,
.result-details {
  display: flex;
  gap: 16px;
  margin-bottom: 10px;
  font-size: 12px;
  color: #495057;
  flex-wrap: wrap;
}

.paper-meta span,
.detail-item {
  padding: 2px 8px;
  background: #F8F9FA;
  border-radius: 4px;
}

.detail-item {
  display: flex;
  gap: 6px;
}

.detail-item .label {
  color: #495057;
  font-weight: 500;
}

.detail-item .value {
  color: #212529;
  font-weight: 600;
}

.paper-actions,
.action-bar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* 紧凑型待考试/成绩单列表样式 */
.paper-item--compact,
.result-item--compact {
  padding: 12px 14px !important;
  gap: 6px !important;
}

.paper-row-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.paper-row-main .paper-title {
  font-size: 13px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.paper-row-main .paper-status,
.paper-row-main .grade-badge {
  flex-shrink: 0;
  font-size: 11px;
  padding: 1px 8px;
}

.result-meta {
  display: flex;
  gap: 12px;
  font-size: 11px;
  color: #868E96;
  flex-wrap: wrap;
}

.result-meta span::before {
  content: "·";
  margin-right: 12px;
  color: #CED4DA;
}

.result-meta span:first-child::before {
  display: none;
}

.paper-item--compact .paper-meta {
  margin-bottom: 0 !important;
  font-size: 11px;
  gap: 12px;
}

.paper-item--compact .paper-actions {
  margin-top: 4px;
}

.taking-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding: 12px 16px;
  background: #F8F9FA;
  border-radius: 8px;
  border: 1px solid #E9ECEF;
}

.taking-header h3 {
  margin: 0;
  font-size: 16px;
  color: #212529;
  font-weight: 600;
}

.timer {
  font-size: 18px;
  font-weight: 600;
  color: #C92A2A;
  font-family: 'Courier New', monospace;
  background: #FFF5F5;
  padding: 6px 14px;
  border-radius: 6px;
  border: 1px solid #FFD6D6;
}

.questions-container {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 12px;
}

.question-item {
  padding: 16px;
  background: #FFFFFF;
  border: 1px solid #E9ECEF;
  border-radius: 8px;
  transition: box-shadow 0.15s ease;
}

.question-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.question-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid #E9ECEF;
}

.question-number {
  font-weight: 600;
  font-size: 13px;
  color: #212529;
  background: #F8F9FA;
  padding: 2px 8px;
  border-radius: 4px;
}

.type-badge {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  background: #FFFFFF;
  color: #212529;
  border: 1px solid #DEE2E6;
  display: inline-block;
}

.question-content {
  font-size: 14px;
  line-height: 1.6;
  color: #212529;
  margin-bottom: 12px;
  padding: 10px 12px;
  background: #F8F9FA;
  border-radius: 6px;
  border-left: 3px solid #212529;
  font-weight: 400;
}

.options-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 10px;
}

.option-label {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  cursor: pointer;
  border-radius: 6px;
  transition: background 0.15s ease;
  background: #F8F9FA;
  border: 1px solid transparent;
  font-size: 13px;
}

.option-label:hover {
  background: #F1F3F5;
  border-color: #E9ECEF;
}

.option-label input[type="radio"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: #212529;
  flex-shrink: 0;
}

.answer-comparison {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 10px;
  padding: 12px;
  background: #F8F9FA;
  border-radius: 8px;
  border: 1px solid #E9ECEF;
}

.answer-comparison > div {
  padding: 10px;
  background: #FFFFFF;
  border-radius: 6px;
  border: 1px solid #E9ECEF;
}

.wrong {
  color: #C92A2A;
  font-weight: 600;
  font-size: 13px;
  padding: 8px;
  background: #FFF5F5;
  border-radius: 4px;
  border-left: 3px solid #C92A2A;
  display: block;
  margin-top: 6px;
}

.correct {
  color: #2B8A3E;
  font-weight: 600;
  font-size: 13px;
  padding: 8px;
  background: #EBFBEE;
  border-radius: 4px;
  border-left: 3px solid #2B8A3E;
  display: block;
  margin-top: 6px;
}

.btn {
  border-radius: 6px;
  padding: 0 14px;
  height: 36px;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.15s ease;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  box-sizing: border-box;
  white-space: nowrap;
}

.btn-primary {
  background: #212529;
  color: #FFFFFF;
}

.btn-primary:hover:not(:disabled) {
  background: #000000;
}

.btn-danger {
  background: #C92A2A;
  color: #FFFFFF;
}

.btn-danger:hover:not(:disabled) {
  background: #A02B2B;
}

.btn-sm {
  height: 32px;
  padding: 0 10px;
  font-size: 12px;
  min-width: 70px;
}

.form-item {
  margin-bottom: 16px;
}

.form-label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: #212529;
  margin-bottom: 6px;
}

.form-input {
  width: 100%;
  height: 36px;
  padding: 6px 12px;
  border: 1px solid #DEE2E6;
  border-radius: 6px;
  font-size: 13px;
  color: #212529;
  background: #FFFFFF;
  transition: border-color 0.15s ease;
}

.form-input:focus {
  border-color: #212529;
  outline: none;
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.05);
}

.form-input:hover {
  border-color: #CED4DA;
}

/* 自测表单样式 */
.selftest-form {
  max-width: 600px;
  margin: 0 auto;
}
.selftest-desc {
  font-size: 13px;
  color: #868E96;
  margin-bottom: 24px;
  line-height: 1.5;
}
.form-section {
  margin-bottom: 24px;
}
.section-title {
  font-size: 14px;
  font-weight: 600;
  color: #212529;
  margin: 0 0 12px 0;
  padding-bottom: 8px;
  border-bottom: 1px solid #E9ECEF;
}
.form-row.count-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 12px;
}
.form-row .form-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.form-row .form-item .form-label {
  font-size: 12px;
  color: #495057;
  font-weight: 500;
}
.form-row .form-item .form-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid #DEE2E6;
  border-radius: 6px;
  font-size: 14px;
  text-align: center;
  outline: none;
  transition: border-color 0.15s ease;
}
.form-row .form-item .form-input:focus {
  border-color: #228BE6;
}
.form-select {
  width: 100%;
  height: 36px;
  padding: 6px 12px;
  border: 1px solid #DEE2E6;
  border-radius: 6px;
  font-size: 13px;
  color: #212529;
  background: #FFFFFF;
  transition: border-color 0.15s ease;
  cursor: pointer;
}
.form-select:focus {
  border-color: #212529;
  outline: none;
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.05);
}
.form-select:hover {
  border-color: #CED4DA;
}
.form-actions {
  text-align: center;
  padding-top: 16px;
  border-top: 1px solid #E9ECEF;
}
.btn-loading-icon {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: #FFFFFF;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
  margin-right: 6px;
  vertical-align: middle;
}

/* ========== Professional Exam Taking Page ========== */
.exam-taking-page {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: #F8F9FA;
}

/* Top Bar */
.exam-top-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  background: #FFFFFF;
  border-bottom: 1px solid #DEE2E6;
  gap: 16px;
}
.exam-title-section {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.exam-paper-title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: #212529;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.exam-mode-badge {
  padding: 2px 8px;
  background: #E9ECEF;
  color: #495057;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  flex-shrink: 0;
}
.exam-question-count {
  font-size: 12px;
  color: #868E96;
  white-space: nowrap;
  flex-shrink: 0;
}
.exam-timer-section { flex-shrink: 0; }
.timer-display {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  background: #212529;
  color: #FFFFFF;
  border-radius: 6px;
  font-family: 'SF Mono', Consolas, 'Courier New', monospace;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 1px;
}
.timer-display.timer-warning {
  background: #C92A2A;
  animation: timerPulse 1.5s ease-in-out infinite;
}
@keyframes timerPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.65; }
}
.timer-icon {
  width: 16px; height: 16px; flex-shrink: 0;
}

/* Progress Bar */
.exam-progress-bar {
  padding: 8px 20px;
  background: #FFFFFF;
  border-bottom: 1px solid #E9ECEF;
  display: flex;
  align-items: center;
  gap: 16px;
}
.progress-track {
  flex: 1;
  height: 5px;
  background: #E9ECEF;
  border-radius: 3px;
  overflow: hidden;
  min-width: 100px;
}
.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #212529, #495057);
  border-radius: 3px;
  transition: width 0.35s ease;
}
.progress-stats {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11.5px;
  color: #868E96;
  white-space: nowrap;
  flex-shrink: 0;
}
.progress-stats strong { color: #212529; }

/* Main Layout */
.exam-main-layout {
  flex: 1;
  display: flex;
  gap: 0;
  min-height: 0;
  overflow: hidden;
}

/* Question Display Area */
.question-display-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #FFFFFF;
  overflow-y: auto;
  padding: 24px;
  min-width: 0;
}
.qda-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 2px solid #F1F3F5;
}
.qda-number-row {
  display: flex;
  align-items: baseline;
  gap: 4px;
}
.qda-current-num {
  font-size: 28px;
  font-weight: 800;
  color: #212529;
  line-height: 1;
}
.qda-total-slash {
  font-size: 18px;
  color: #ADB5BD;
  font-weight: 300;
}
.qda-total-count {
  font-size: 16px;
  color: #ADB5BD;
  font-weight: 500;
}
.qda-meta-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.mark-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border: 1px solid #DEE2E6;
  border-radius: 5px;
  background: #FFFFFF;
  color: #868E96;
  font-size: 11.5px;
  cursor: pointer;
  transition: all 0.15s ease;
  white-space: nowrap;
}
.mark-btn:hover { border-color: #ADB5BD; color: #495057; background: #F8F9FA; }
.mark-btn.active {
  border-color: #E67700;
  color: #E67700;
  background: #FFF9DB;
}

/* Stem */
.qda-stem {
  margin-bottom: 20px;
}
.qda-stem p {
  margin: 0;
  font-size: 15px;
  line-height: 1.75;
  color: #212529;
  font-weight: 400;
}

/* Options */
.qda-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}
.option-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.15s ease;
  background: #F8F9FA;
  border: 2px solid transparent;
  user-select: none;
}
.option-item:hover { background: #F1F3F5; border-color: #DEE2E6; }
.option-item.selected {
  background: #EBFBEE;
  border-color: #40C057;
}
.opt-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid #CED4DA;
  background: #FFFFFF;
  flex-shrink: 0;
  transition: all 0.15s ease;
}
.opt-circle.checked {
  border-color: #212529;
  background: #212529;
}
.opt-square {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: 2px solid #CED4DA;
  background: #FFFFFF;
  flex-shrink: 0;
  transition: all 0.15s ease;
}
.opt-square.checked {
  border-color: #212529;
  background: #212529;
}
.opt-label-text {
  font-weight: 700;
  font-size: 14px;
  color: #495057;
  min-width: 20px;
  flex-shrink: 0;
}
.option-item.selected .opt-label-text { color: #212529; }
.opt-content-text {
  font-size: 14.5px;
  line-height: 1.55;
  color: #343A40;
  word-break: break-word;
}

/* Input Areas */
.qda-input-area {
  margin-bottom: 20px;
}
.subjective-textarea {
  width: 100%;
  padding: 12px 16px;
  border: 2px solid #DEE2E6;
  border-radius: 8px;
  font-size: 14.5px;
  color: #212529;
  background: #FFFFFF;
  transition: border-color 0.15s ease;
  box-sizing: border-box;
  font-family: inherit;
}
.subjective-textarea:focus {
  outline: none;
  border-color: #212529;
  box-shadow: 0 0 0 3px rgba(33,37,41,.08);
}

/* Fill Blank Inline Mode */
.fb-inline { padding: 4px 0; }
.fb-stem-with-blanks {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px;
  line-height: 2;
  font-size: 15px;
  color: #212529;
}
.fb-text {
  word-break: break-word;
}
.fb-blank-input {
  display: inline-block;
  width: 140px;
  min-width: 80px;
  max-width: 240px;
  height: 30px;
  padding: 2px 8px;
  border: none;
  border-bottom: 2px solid #ADB5BD;
  border-radius: 0;
  background: #F8F9FA;
  font-size: 14.5px;
  color: #212529;
  text-align: center;
  transition: all 0.15s ease;
  vertical-align: baseline;
  font-family: inherit;
  box-sizing: border-box;
}
.fb-blank-input:hover { border-bottom-color: #868E96; background: #F1F3F5; }
.fb-blank-input:focus {
  outline: none;
  border-bottom-color: #212529;
  border-bottom-width: 2.5px;
  background: #FFFFFF;
  box-shadow: 0 2px 0 0 rgba(33,37,41,.08);
}
.fb-fallback { display: flex; flex-direction: column; gap: 12px; }
.fb-stem-text { margin: 0; font-size: 15px; line-height: 1.75; color: #212529; }
.fb-blank-input.fb-single {
  width: 100%;
  max-width: none;
  height: 38px;
  padding: 8px 14px;
  border: 2px solid #DEE2E6;
  border-radius: 7px;
  text-align: left;
}
.fb-blank-input.fb-single:focus {
  border-color: #212529;
  box-shadow: 0 0 0 3px rgba(33,37,41,.08);
}
.subjective-textarea {
  resize: vertical;
  min-height: 120px;
  line-height: 1.65;
}

/* Nav Hint in Question Area */
.qda-nav-hint {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding-top: 16px;
  border-top: 1px solid #F1F3F5;
  margin-top: auto;
}
.nav-hint-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  border: 1px solid #DEE2E6;
  border-radius: 6px;
  background: #FFFFFF;
  color: #495057;
  font-size: 12.5px;
  cursor: pointer;
  transition: all 0.15s ease;
}
.nav-hint-btn:hover:not(:disabled) { background: #F1F3F5; border-color: #ADB5BD; color: #212529; }
.nav-hint-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.nav-position {
  font-size: 13px;
  color: #868E96;
  font-weight: 500;
  min-width: 60px;
  text-align: center;
}

/* Answer Card Sidebar */
.answer-card-sidebar {
  width: 260px;
  flex-shrink: 0;
  background: #FFFFFF;
  border-left: 1px solid #E9ECEF;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
.ac-header {
  padding: 14px 16px 10px;
  border-bottom: 1px solid #F1F3F5;
}
.ac-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: #212529;
}
.ac-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  padding: 10px 16px;
  border-bottom: 1px solid #F1F3F5;
}
.legend-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #868E96;
}
.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
}
.dot-current { background: #212529; }
.dot-answered { background: #40C057; }
.dot-marked { background: #E67700; }
.dot-unanswered { background: #DEE2E6; }

/* Card Grid */
.ac-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  padding: 12px 16px;
}
.ac-cell {
  aspect-ratio: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1.5px solid #E9ECEF;
  background: #FFFFFF;
  font-size: 12.5px;
  font-weight: 600;
  color: #495057;
  cursor: pointer;
  transition: all 0.12s ease;
  user-select: none;
}
.ac-cell:hover:not(.current) {
  border-color: #ADB5BD;
  background: #F8F9FA;
}
.ac-cell.current {
  border-color: #212529;
  background: #212529;
  color: #FFFFFF;
  box-shadow: 0 0 0 2px rgba(33,37,41,.15);
}
.ac-cell.answered {
  border-color: #B2F2BB;
  background: #D3F9D8;
  color: #2B8A3E;
}
.ac-cell.current.answered {
  background: #37B24D;
  color: #FFFFFF;
  border-color: #37B24D;
}
.ac-cell.marked {
  border-color: #FFD43B;
  background: #FFE066;
  color: #854D0E;
}
.ac-cell.current.marked {
  background: #E67700;
  color: #FFFFFF;
  border-color: #E67700;
}
.ac-cell.unanswered {
  background: #F8F9FA;
  color: #ADB5BD;
}
.ac-cell.current.unanswered {
  background: #495057;
  color: #FFFFFF;
  border-color: #495057;
}

/* Card Summary */
.ac-summary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid #F1F3F5;
  margin-top: auto;
}
.ac-stat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 8px;
  background: #F8F9FA;
  border-radius: 5px;
}
.ac-stat-label {
  font-size: 11.5px;
  color: #868E96;
}
.ac-stat-value {
  font-size: 13px;
  font-weight: 700;
  color: #212529;
}
.ac-stat-value.answered { color: #2B8A3E; }
.ac-stat-value.unanswered { color: #868E96; }
.ac-stat-value.marked { color: #E67700; }

/* Bottom Bar */
.exam-bottom-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 20px;
  background: #FFFFFF;
  border-top: 1px solid #DEE2E6;
  gap: 12px;
}
.bottom-left, .bottom-center, .bottom-right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.bottom-center { gap: 10px; }

.btn-exit {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 7px 14px;
  border: 1px solid #DEE2E6;
  border-radius: 6px;
  background: #FFFFFF;
  color: #868E96;
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s ease;
}
.btn-exit:hover { background: #FFF5F5; border-color: #FFC9C9; color: #C92A2A; }

.btn-action {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 8px 18px;
  border: 1.5px solid #DEE2E6;
  border-radius: 7px;
  background: #FFFFFF;
  color: #495057;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}
.btn-action:hover:not(:disabled) { background: #F1F3F5; border-color: #ADB5BD; color: #212529; }
.btn-action:disabled { opacity: 0.35; cursor: not-allowed; }

.btn-submit {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 8px 22px;
  border: none;
  border-radius: 7px;
  background: #212529;
  color: #FFFFFF;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}
.btn-submit:hover { background: #343A40; box-shadow: 0 2px 8px rgba(0,0,0,.15); }

/* ========== Result Review Page (答题卡+题目详情) ========== */
.result-review-page {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: #F8F9FA;
}

/* Top Bar */
.rr-top-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  background: #FFFFFF;
  border-bottom: 1px solid #DEE2E6;
  gap: 16px;
}
.rr-title-section {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.rr-paper-title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  color: #212529;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rr-score-section {
  display: flex;
  align-items: baseline;
  gap: 4px;
  flex-shrink: 0;
}
.rr-total-score {
  font-size: 24px;
  font-weight: 800;
  color: #212529;
  font-family: 'SF Mono', Consolas, monospace;
}
.rr-max-score {
  font-size: 13px;
  color: #868E96;
}
.rr-rate-badge {
  margin-left: 8px;
  padding: 3px 10px;
  background: #EBFBEE;
  color: #2B8A3E;
  font-size: 12px;
  font-weight: 600;
  border-radius: 5px;
  border: 1px solid #D3F9D8;
}

/* Main Layout */
.rr-main-layout {
  flex: 1;
  display: flex;
  gap: 0;
  min-height: 0;
  overflow: hidden;
}

/* Question Area */
.rr-question-area {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  background: #FFFFFF;
  padding: 24px;
}
.rrq-card {
  max-width: 100%;
}
.rrq-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 2px solid #F1F3F5;
}
.rrq-number {
  font-weight: 700;
  font-size: 16px;
  color: #212529;
  background: #F8F9FA;
  padding: 3px 10px;
  border-radius: 5px;
}
.rrq-stem {
  font-size: 15px;
  line-height: 1.75;
  color: #212529;
  margin-bottom: 16px;
  padding: 12px 14px;
  background: #F8F9FA;
  border-radius: 7px;
  font-weight: 400;
}
.rrq-fallback-info {
  margin-bottom: 16px;
  padding: 12px 14px;
  background: #fff7e6;
  border-left: 3px solid #fa8c16;
  border-radius: 6px;
  font-size: 13px;
  line-height: 1.8;
  color: #874d00;
}
.fallback-row {
  margin-bottom: 4px;
}
.fallback-row:last-child {
  margin-bottom: 0;
}
.fallback-hint {
  font-weight: 600;
  display: inline-block;
  min-width: 90px;
}
.fallback-row code {
  background: #fff;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 12px;
  color: #666;
}
.rrq-options {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-bottom: 18px;
}
.rrq-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  border-radius: 7px;
  font-size: 13.5px;
  background: #F8F9FA;
  border: 2px solid transparent;
  transition: all 0.15s ease;
}
.rrq-option.is-selected { background: #E7F5FF; border-color: #74C0FC; }
.rrq-option.is-correct-answer { background: #EBFBEE; border-color: #69DB7C; }
.rrq-option.is-wrong-selection { background: #FFF5F5; border-color: #FF8787; }
.rrq-opt-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  font-weight: 700;
  font-size: 12px;
  background: #DEE2E6;
  color: #495057;
  flex-shrink: 0;
}
.rrq-option.is-selected .rrq-opt-key { background: #74C0FC; color: #FFF; }
.rrq-option.is-correct-answer .rrq-opt-key { background: #69DB7C; color: #FFF; }
.rrq-option.is-wrong-selection .rrq-opt-key { background: #FF8787; color: #FFF; }
.rrq-opt-text { flex: 1; color: #212529; line-height: 1.55; word-break: break-word; }
.rrq-opt-mark {
  font-size: 15px;
  font-weight: 700;
  flex-shrink: 0;
}
.rrq-opt-mark.correct { color: #2B8A3E; }
.rrq-opt-mark.wrong { color: #C92A2A; }
.rrq-opt-mark.missed { color: #E67700; }

.rrq-answer-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 10px;
  padding: 12px 14px;
  background: #F8F9FA;
  border-radius: 7px;
  border: 1px solid #E9ECEF;
}
.rrq-answer-row {
  display: flex;
  gap: 8px;
  font-size: 13.5px;
  align-items: baseline;
}
.rrq-score-row {
  display: flex;
  gap: 8px;
  font-size: 13.5px;
  padding: 8px 14px;
  background: #F8F9FA;
  border-radius: 5px;
  margin-bottom: 10px;
}
.rrq-explanation {
  display: flex;
  gap: 8px;
  padding: 12px 14px;
  background: #FFF9DB;
  border-radius: 7px;
  font-size: 13.5px;
  color: #495057;
  line-height: 1.6;
  border: 1px solid #FFE066;
}
.explanation-icon,
.analysis-icon,
.feedback-icon {
  flex-shrink: 0;
  color: #E67700;
}
.feedback-icon {
  color: #5C7CFA;
}
.explanation-text { flex: 1; }

/* Analysis Section Header */
.rrq-analysis {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  margin-bottom: 4px;
}
.analysis-label {
  font-size: 12px;
  font-weight: 600;
  color: #E67700;
}

/* Feedback Section Header */
.rrq-feedback {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  margin-bottom: 4px;
}
.feedback-label {
  font-size: 12px;
  font-weight: 600;
  color: #5C7CFA;
}

/* Content blocks with specific styling */
.rrq-analysis-content {
  background: #FFF9DB;
  border-color: #FFE066;
}
.rrq-feedback-content {
  background: #E7F5FF;
  border-color: #A5D8FF;
}
.rrq-feedback-content .explanation-text {
  color: #1864AB;
}

/* No Analysis State */
.rrq-no-analysis {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 10px;
  padding: 10px 14px;
  color: #ADB5BD;
  font-size: 12px;
  font-style: italic;
}

/* Sidebar - Answer Card */
.rr-sidebar {
  width: 260px;
  flex-shrink: 0;
  background: #FFFFFF;
  border-left: 1px solid #E9ECEF;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
.rrs-header {
  padding: 14px 16px 10px;
  border-bottom: 1px solid #F1F3F5;
}
.rrs-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: #212529;
}
.rrs-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  padding: 10px 16px;
  border-bottom: 1px solid #F1F3F5;
}
.legend-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #868E96;
}
.dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
}
.dot-correct { background: #40C057; }
.dot-wrong { background: #FA5252; }
.dot-pending { background: #FAB005; }

/* Review Grid Cells */
.rrs-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  padding: 12px 16px;
}
.rrs-cell {
  aspect-ratio: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1.5px solid #E9ECEF;
  background: #FFFFFF;
  font-size: 12.5px;
  font-weight: 600;
  color: #495057;
  cursor: pointer;
  transition: all 0.12s ease;
  user-select: none;
}
.rrs-cell:hover:not(.active) {
  border-color: #ADB5BD;
  background: #F8F9FA;
}
.rrs-cell.active {
  border-color: #212529;
  background: #212529;
  color: #FFFFFF;
  box-shadow: 0 0 0 2px rgba(33,37,41,.15);
  transform: scale(1.08);
}
.rrs-cell.cell-correct {
  border-color: #B2F2BB;
  background: #D3F9D8;
  color: #2B8A3E;
}
.rrs-cell.cell-correct.active {
  background: #37B24D;
  color: #FFFFFF;
  border-color: #37B24D;
}
.rrs-cell.cell-wrong {
  border-color: #FFCCCB;
  background: #FFE3E3;
  color: #C92A2A;
}
.rrs-cell.cell-wrong.active {
  background: #E03131;
  color: #FFFFFF;
  border-color: #E03131;
}
.rrs-cell.cell-pending {
  border-color: #FFE066;
  background: #FFF9DB;
  color: #E67700;
}
.rrs-cell.cell-pending.active {
  background: #F59F00;
  color: #FFFFFF;
  border-color: #F59F00;
}

/* Sidebar Summary */
.rrs-summary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid #F1F3F5;
  margin-top: auto;
}
.rrs-stat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 8px;
  background: #F8F9FA;
  border-radius: 5px;
}
.rrs-stat-label {
  font-size: 11.5px;
  color: #868E96;
}
.rrs-stat-value {
  font-size: 13px;
  font-weight: 700;
  color: #212529;
}
.rrs-stat-value.stat-correct { color: #2B8A3E; }
.rrs-stat-value.stat-wrong { color: #C92A2A; }
.rrs-stat-value.stat-pending { color: #E67700; }

/* Responsive */
@media (max-width: 900px) {
  .exam-main-layout { flex-direction: column; }
  .answer-card-sidebar {
    width: 100%;
    max-height: 220px;
    border-left: none;
    border-top: 1px solid #E9ECEF;
  }
  .ac-grid { grid-template-columns: repeat(8, 1fr); }

  /* Result Review Page responsive */
  .rr-main-layout { flex-direction: column; }
  .rr-sidebar {
    width: 100%;
    max-height: 240px;
    border-left: none;
    border-top: 1px solid #E9ECEF;
  }
  .rrs-grid { grid-template-columns: repeat(8, 1fr); }
}
@media (max-width: 600px) {
  .exam-top-bar { flex-wrap: wrap; padding: 10px 14px; }
  .exam-paper-title { font-size: 13px; }
  .question-display-area { padding: 16px 14px; }
  .qda-current-num { font-size: 22px; }
  .ac-grid { grid-template-columns: repeat(10, 1fr); }
  .exam-bottom-bar { flex-wrap: wrap; justify-content: center; padding: 8px 14px; }
  .bottom-left { order: 3; width: 100%; justify-content: center; }

  /* Result Review Page mobile */
  .rr-top-bar { flex-wrap: wrap; padding: 10px 14px; gap: 10px; }
  .rr-paper-title { font-size: 13px; }
  .rr-total-score { font-size: 20px; }
  .rr-question-area { padding: 16px 14px; }
  .rrq-stem { font-size: 14px; padding: 10px 12px; }
  .rrs-grid { grid-template-columns: repeat(10, 1fr); }
}
</style>
