// screens-assessments.jsx — Student assessments / test engine
// Hub (assigned · history · leaderboard) + intro + type-aware attempt + submitted/result + review.
// Question types: mcq · multi · tf · numeric · short · fill · match.
// Result modes: instant (score on submit) · delayed (teacher publishes later).
// Class context: filters strictly to the signed-in student's class.

const { useState: useStateA, useMemo: useMemoA, useEffect: useEffectA } = React;

// ─────────────────────────────────────────────────────────────
// STUDENT CONTEXT — drives "this class only" filter
// ─────────────────────────────────────────────────────────────
const STUDENT_CONTEXT = { name: 'Aarav Reddy', cls: '8-B', school: 'DPS Hyderabad', grade: 8 };

// ─────────────────────────────────────────────────────────────
// QUESTION BANKS — keyed by id; each assessment references one
// ─────────────────────────────────────────────────────────────
const BANK_LINEAR = [
  { type: 'mcq', q: 'Solve for x:  2x + 5 = 17', opts: ['x = 5', 'x = 6', 'x = 7', 'x = 8'], correct: 1,
    expl: 'Subtract 5 from both sides: 2x = 12, then divide by 2: x = 6.' },
  { type: 'mcq', q: 'If 3y − 4 = 11, what is y?', opts: ['3', '4', '5', '6'], correct: 2,
    expl: 'Add 4 to both sides: 3y = 15, then divide by 3: y = 5.' },
  { type: 'mcq', q: 'Which of these is a linear equation in one variable?', opts: ['x² + 3 = 7', '2x + y = 5', '4x − 9 = 11', 'x + y² = 4'], correct: 2,
    expl: 'A linear equation in one variable has only one variable to the first power.' },
  { type: 'mcq', q: 'Solve:  (x + 3) / 2 = 7', opts: ['x = 8', 'x = 11', 'x = 14', 'x = 17'], correct: 1,
    expl: 'Multiply both sides by 2: x + 3 = 14, then x = 11.' },
  { type: 'mcq', q: 'The sum of two consecutive integers is 41. The smaller one is:', opts: ['19', '20', '21', '22'], correct: 1,
    expl: 'Let n and n+1. Then 2n + 1 = 41 → n = 20.' },
  { type: 'mcq', q: 'Solve:  5(x − 2) = 3x + 4', opts: ['x = 6', 'x = 7', 'x = 8', 'x = 9'], correct: 1,
    expl: '5x − 10 = 3x + 4  →  2x = 14  →  x = 7.' },
  { type: 'mcq', q: 'If 7x = 49, then x equals:', opts: ['5', '6', '7', '8'], correct: 2,
    expl: 'Divide both sides by 7: x = 7.' },
  { type: 'mcq', q: 'Solve:  x/4 + 3 = 9', opts: ['x = 18', 'x = 24', 'x = 30', 'x = 36'], correct: 1,
    expl: 'Subtract 3: x/4 = 6 → x = 24.' },
  { type: 'mcq', q: 'A number tripled gives 51. The number is:', opts: ['15', '17', '19', '21'], correct: 1,
    expl: '3x = 51  →  x = 17.' },
  { type: 'mcq', q: 'Solve:  4x − 2 = 2x + 10', opts: ['x = 4', 'x = 6', 'x = 8', 'x = 10'], correct: 1,
    expl: '2x = 12  →  x = 6.' },
];

// Mixed question types — Photosynthesis (Science)
const BANK_PHOTO = [
  { type: 'mcq', q: 'Which gas do plants absorb during photosynthesis?',
    opts: ['Oxygen (O₂)', 'Carbon dioxide (CO₂)', 'Nitrogen (N₂)', 'Hydrogen (H₂)'], correct: 1,
    expl: 'Plants take in CO₂ from the atmosphere through stomata in their leaves.' },
  { type: 'multi', q: 'Select all the products of photosynthesis.',
    opts: ['Glucose (C₆H₁₂O₆)', 'Oxygen (O₂)', 'Carbon dioxide (CO₂)', 'Water (H₂O)', 'ATP'], correct: [0, 1],
    expl: 'Photosynthesis produces glucose and oxygen from CO₂ and H₂O. CO₂ and water are inputs, not products.' },
  { type: 'tf', q: 'Photosynthesis only occurs during the day.', correct: true,
    expl: 'The light-dependent reactions need sunlight, so photosynthesis effectively halts at night.' },
  { type: 'numeric', q: 'On average, how many oxygen molecules are released per glucose molecule produced?',
    correct: 6, tolerance: 0, unit: 'O₂',
    expl: 'The balanced equation: 6CO₂ + 6H₂O → C₆H₁₂O₆ + 6O₂ — six O₂ molecules per glucose.' },
  { type: 'short', q: 'Name the green pigment that absorbs light energy in plants.',
    correct: ['chlorophyll', 'chlorophyl'],
    expl: 'Chlorophyll absorbs red and blue light and reflects green, giving leaves their colour.' },
  { type: 'fill', q: 'Photosynthesis converts ___ energy into ___ energy stored in glucose.',
    blanks: 2, correct: [['light', 'sunlight', 'solar'], ['chemical']],
    expl: 'Light energy is captured by chlorophyll and stored as chemical energy in glucose bonds.' },
  { type: 'match', q: 'Match each plant part to its role.',
    pairs: [
      { left: 'Stomata', right: 'Gas exchange' },
      { left: 'Roots', right: 'Water absorption' },
      { left: 'Xylem', right: 'Water transport up' },
      { left: 'Chloroplast', right: 'Site of photosynthesis' },
    ],
    expl: 'Stomata are pores in leaves; xylem moves water from roots upward; chloroplasts house chlorophyll.' },
  { type: 'mcq', q: 'Which part of the plant cell carries out photosynthesis?',
    opts: ['Mitochondria', 'Nucleus', 'Chloroplast', 'Ribosome'], correct: 2,
    expl: 'Chloroplasts contain chlorophyll and are the site of both light and dark reactions.' },
];

// Mixed types — English Tenses (delayed mode, teacher reviews short answers)
const BANK_GRAMMAR = [
  { type: 'mcq', q: 'Pick the correct form:  By next month, she ___ her degree.',
    opts: ['will finish', 'will have finished', 'will be finishing', 'finishes'], correct: 1,
    expl: 'Future perfect — an action completed before a future point.' },
  { type: 'fill', q: 'I ___ breakfast when the phone rang.',
    blanks: 1, correct: [['was eating', 'wasn\'t eating']],
    expl: 'Past continuous "was eating" — an ongoing action interrupted by another.' },
  { type: 'fill', q: 'They ___ in Pune for ten years.',
    blanks: 1, correct: [['have lived', 'have been living']],
    expl: 'Present perfect with duration ("for ten years") needs "have lived" or "have been living".' },
  { type: 'tf', q: '"She didn\'t went to school yesterday" is grammatically correct.', correct: false,
    expl: 'After "did/didn\'t", the main verb stays in base form: "She didn\'t go to school."' },
  { type: 'mcq', q: 'Which sentence uses present perfect correctly?',
    opts: ['I have seen that movie last week.', 'She has lived here since 2019.', 'They have went to the park.', 'He had ate dinner already.'], correct: 1,
    expl: 'Present perfect with "since" + a starting point is the standard pattern.' },
  { type: 'short', q: 'Name the tense:  "I had finished my homework before dinner."',
    correct: ['past perfect', 'past-perfect', 'pastperfect'],
    expl: 'Past perfect — an action complete before another past action.' },
  { type: 'multi', q: 'Select all sentences that use a continuous tense.',
    opts: ['She is reading a book.', 'He runs every morning.', 'They were waiting for hours.', 'I will be travelling.', 'We left yesterday.'], correct: [0, 2, 3],
    expl: 'Continuous tenses use a form of "be" + "-ing".' },
  { type: 'mcq', q: 'Choose the correct future-continuous form:  This time tomorrow we ___.',
    opts: ['will fly', 'are flying', 'will be flying', 'flew'], correct: 2,
    expl: 'Future continuous "will be + -ing" describes an action in progress at a future moment.' },
];

// Pure numeric — Mental math (kept short for the prototype)
const BANK_MENTAL = [
  { type: 'numeric', q: '24 × 7 = ?', correct: 168, tolerance: 0, expl: '24 × 7 = (20×7) + (4×7) = 140 + 28 = 168.' },
  { type: 'numeric', q: '(63 ÷ 9) × 4 = ?', correct: 28, tolerance: 0, expl: '63 ÷ 9 = 7;  7 × 4 = 28.' },
  { type: 'numeric', q: '15² = ?', correct: 225, tolerance: 0, expl: '15² = 225.' },
  { type: 'numeric', q: '0.4 × 250 = ?', correct: 100, tolerance: 0, expl: '0.4 × 250 = 4 × 25 = 100.' },
  { type: 'numeric', q: 'What is 35% of 80?', correct: 28, tolerance: 0, expl: '0.35 × 80 = 28.' },
];

// Civics — short + mcq (already completed in our data)
const BANK_CIVICS = [
  { type: 'short', q: 'In which year did the Indian Constitution come into effect?', correct: ['1950'],
    expl: 'The Constitution came into effect on 26 January 1950 — Republic Day.' },
  { type: 'mcq', q: 'Who is known as the chief architect of the Indian Constitution?',
    opts: ['Mahatma Gandhi', 'Jawaharlal Nehru', 'B. R. Ambedkar', 'Sardar Patel'], correct: 2,
    expl: 'Dr. B. R. Ambedkar chaired the Drafting Committee.' },
  { type: 'multi', q: 'Select all features of the Indian Constitution.',
    opts: ['Federal structure', 'Parliamentary government', 'Single citizenship', 'Bicameral legislature', 'Hereditary monarchy'], correct: [0, 1, 2, 3],
    expl: 'The Constitution is federal, parliamentary, with single citizenship and a bicameral Parliament. India is a republic, not a monarchy.' },
  { type: 'tf', q: 'The Preamble declares India to be a sovereign, socialist, secular, democratic republic.', correct: true,
    expl: 'The 42nd Amendment in 1976 inserted "socialist" and "secular" into the Preamble.' },
];

// History — short answers (delayed mode — teacher grades)
const BANK_HISTORY = [
  { type: 'short', q: 'Name the year of Indian Independence.', correct: ['1947'],
    expl: 'India gained independence on 15 August 1947.' },
  { type: 'short', q: 'Who was the first Prime Minister of India?',
    correct: ['jawaharlal nehru', 'nehru', 'pandit nehru'],
    expl: 'Jawaharlal Nehru served from 1947 to 1964.' },
  { type: 'mcq', q: 'The Quit India movement was launched in:',
    opts: ['1939', '1942', '1944', '1947'], correct: 1,
    expl: 'Launched on 8 August 1942 by Mahatma Gandhi.' },
  { type: 'short', q: 'In one sentence, explain the significance of the Salt March.',
    correct: [], teacherGraded: true,
    expl: 'Open response — graded by your teacher when results are published.' },
];

const BANKS = {
  linear: BANK_LINEAR,
  photo: BANK_PHOTO,
  grammar: BANK_GRAMMAR,
  mental: BANK_MENTAL,
  civics: BANK_CIVICS,
  history: BANK_HISTORY,
};

// ─────────────────────────────────────────────────────────────
// ASSESSMENTS — already class-filtered demo set + cross-class items proving filter works
// ─────────────────────────────────────────────────────────────
const RAW_ASSESSMENTS = [
  // ── 8-B (this student's class) ─────────────────────────────────
  { id: 'a1', sub: 'Mathematics', icon: 'flask', clr: 'var(--p600)', bg: 'var(--p50)',
    title: 'Linear equations · Practice quiz',
    by: 'Mrs. Reddy', cls: '8-B', school: 'DPS Hyderabad',
    bank: 'linear', resultsMode: 'instant',
    qCount: 10, marks: 20, durationMin: 20, attempts: 'unlimited',
    assignedOn: 'Mon 10 Mar', dueOn: 'Fri 14 Mar 11:59 PM',
    state: 'assigned', urgency: 'soon' },

  { id: 'a2', sub: 'Science', icon: 'flask', clr: 'var(--success)', bg: 'var(--success-50)',
    title: 'Photosynthesis · Concept check',
    by: 'Mr. Khan', cls: '8-B', school: 'DPS Hyderabad',
    bank: 'photo', resultsMode: 'instant',
    qCount: 8, marks: 24, durationMin: 15, attempts: '1 of 1',
    assignedOn: 'Tue 11 Mar', dueOn: 'Today · 9:00 PM',
    state: 'assigned', urgency: 'late' },

  { id: 'a3', sub: 'English', icon: 'book-open', clr: '#1E40AF', bg: 'var(--info-50)',
    title: 'Grammar drill · Tenses',
    by: 'Ms. Iyer', cls: '8-B', school: 'DPS Hyderabad',
    bank: 'grammar', resultsMode: 'delayed',
    qCount: 8, marks: 24, durationMin: 25, attempts: '0 of 2',
    assignedOn: 'Wed 12 Mar', dueOn: 'Mon 17 Mar',
    state: 'in_progress', urgency: 'ok', progress: 3 },

  { id: 'a7', sub: 'History', icon: 'globe', clr: 'var(--warning)', bg: 'var(--warning-50)',
    title: 'Mid-term · Independence movement',
    by: 'Mrs. Pillai', cls: '8-B', school: 'DPS Hyderabad',
    bank: 'history', resultsMode: 'delayed',
    qCount: 4, marks: 20, durationMin: 30, attempts: '1 of 1',
    assignedOn: 'Fri 7 Mar', dueOn: 'Mon 10 Mar',
    state: 'awaiting',
    submittedOn: 'Mon 10 Mar · 4:18 PM', willPublishOn: 'by Fri 14 Mar' },

  { id: 'a4', sub: 'Mathematics', icon: 'flask', clr: 'var(--p600)', bg: 'var(--p50)',
    title: 'Mental math · Sprint 4',
    by: 'Mrs. Reddy', cls: '8-B', school: 'DPS Hyderabad',
    bank: 'mental', resultsMode: 'instant',
    qCount: 5, marks: 20, durationMin: 5, attempts: '1 of 2',
    assignedOn: 'Sat 7 Mar', dueOn: 'Mon 9 Mar',
    state: 'completed', score: 17, scoreMax: 20, scorePct: 85,
    rank: 6, classRank: '6 / 32', timeTaken: '4m 12s',
    completedOn: 'Mon 9 Mar · 8:45 PM', grade: 'A', clrGrade: 'var(--success)',
    classAvgPct: 71, classTopPct: 96 },

  { id: 'a5', sub: 'Science', icon: 'flask', clr: 'var(--success)', bg: 'var(--success-50)',
    title: 'States of matter · Quiz',
    by: 'Mr. Khan', cls: '8-B', school: 'DPS Hyderabad',
    bank: 'photo', resultsMode: 'instant',
    qCount: 10, marks: 20, durationMin: 12, attempts: '1 of 1',
    assignedOn: 'Wed 4 Mar', dueOn: 'Sat 7 Mar',
    state: 'completed', score: 18, scoreMax: 20, scorePct: 90,
    rank: 3, classRank: '3 / 32', timeTaken: '8m 47s',
    completedOn: 'Fri 6 Mar · 7:12 PM', grade: 'A1', clrGrade: 'var(--success)',
    classAvgPct: 76, classTopPct: 98 },

  { id: 'a6', sub: 'Social Studies', icon: 'globe', clr: 'var(--c600)', bg: 'var(--c50)',
    title: 'Indian Constitution · Chapter test',
    by: 'Mrs. Pillai', cls: '8-B', school: 'DPS Hyderabad',
    bank: 'civics', resultsMode: 'delayed',
    qCount: 4, marks: 30, durationMin: 30, attempts: '1 of 1',
    assignedOn: 'Mon 25 Feb', dueOn: 'Thu 28 Feb',
    state: 'completed', score: 22, scoreMax: 30, scorePct: 73,
    rank: 11, classRank: '11 / 32', timeTaken: '24m 02s',
    completedOn: 'Wed 27 Feb · 5:30 PM',
    publishedOn: 'Sat 1 Mar · 10:00 AM',
    grade: 'B1', clrGrade: 'var(--warning)',
    classAvgPct: 68, classTopPct: 93,
    teacherComments: {
      0: { text: 'Correct year — but try to also remember the exact day (26 January). Republic Day is named after this.', clr: 'positive' },
      2: { text: 'Good — but you missed "Bicameral legislature". Revise Articles 79–82 for Parliament composition.', clr: 'neutral' },
    } },

  // ── Cross-class (filtered out — proves the class filter is real) ──
  { id: 'x1', sub: 'Mathematics', cls: '7-A', school: 'DPS Hyderabad',
    title: 'Fractions revision', state: 'assigned', bank: 'linear', resultsMode: 'instant' },
  { id: 'x2', sub: 'Science', cls: '9-B', school: 'DPS Hyderabad',
    title: 'Cells & tissues', state: 'assigned', bank: 'photo', resultsMode: 'instant' },
];

// Strict filter — student only sees assessments for their current class.
const ASSESSMENTS = RAW_ASSESSMENTS.filter(a =>
  a.cls === STUDENT_CONTEXT.cls && a.school === STUDENT_CONTEXT.school
);
const FILTERED_OUT_COUNT = RAW_ASSESSMENTS.length - ASSESSMENTS.length;

// Resolve a question bank for a given assessment
const banksFor = (a) => BANKS[a.bank] || BANK_LINEAR;

// Type metadata — labels + icons used in chips and the intro screen
const TYPE_META = {
  mcq:     { lab: 'Multiple choice', icon: 'circle' },
  multi:   { lab: 'Multi-select',    icon: 'check' },
  tf:      { lab: 'True / False',    icon: 'check' },
  numeric: { lab: 'Numeric answer',  icon: 'flask' },
  short:   { lab: 'Short answer',    icon: 'edit' },
  fill:    { lab: 'Fill-in-the-blank', icon: 'edit' },
  match:   { lab: 'Match the pairs', icon: 'clipboard' },
};

// Summary of what types appear in an assessment's bank — for the intro chip strip
const summarizeTypes = (a) => {
  const bank = banksFor(a);
  const counts = bank.reduce((acc, q) => { acc[q.type] = (acc[q.type] || 0) + 1; return acc; }, {});
  return Object.entries(counts).map(([t, n]) => ({ t, n, lab: TYPE_META[t]?.lab || t }));
};

// ─────────────────────────────────────────────────────────────
// CORRECTNESS — type-aware grading helper
// ─────────────────────────────────────────────────────────────
function isCorrectAnswer(q, ans) {
  if (ans === null || ans === undefined) return false;
  switch (q.type) {
    case 'mcq': return ans === q.correct;
    case 'multi': {
      if (!Array.isArray(ans)) return false;
      const a = [...ans].sort().join(',');
      const c = [...q.correct].sort().join(',');
      return a === c;
    }
    case 'tf': return ans === q.correct;
    case 'numeric': {
      const n = Number(ans);
      if (Number.isNaN(n)) return false;
      const tol = q.tolerance || 0;
      return Math.abs(n - q.correct) <= tol;
    }
    case 'short': {
      if (q.teacherGraded) return false; // graded later
      const a = String(ans).trim().toLowerCase();
      return q.correct.some(c => String(c).toLowerCase() === a);
    }
    case 'fill': {
      if (!Array.isArray(ans) || ans.length !== q.blanks) return false;
      return ans.every((piece, i) => {
        const accepted = q.correct[i];
        const a = String(piece).trim().toLowerCase();
        return Array.isArray(accepted)
          ? accepted.some(c => String(c).toLowerCase() === a)
          : String(accepted).toLowerCase() === a;
      });
    }
    case 'match': {
      if (!Array.isArray(ans) || ans.length !== q.pairs.length) return false;
      return ans.every((rightIdx, leftIdx) => rightIdx === leftIdx);
    }
    default: return false;
  }
}

// ─────────────────────────────────────────────────────────────
// PRACTICE POOL — extra easier questions per bank, used after a weak result
// to drill the topic types where the student < 60%. No timer, no marks.
// ─────────────────────────────────────────────────────────────
const PRACTICE_POOL = {
  photo: [
    { type: 'mcq', q: 'Which colour of light is least absorbed by chlorophyll?',
      opts: ['Blue', 'Red', 'Green', 'Violet'], correct: 2,
      expl: 'Chlorophyll reflects green light — that is why leaves look green.' },
    { type: 'tf', q: 'The reactants of photosynthesis are oxygen and glucose.', correct: false,
      expl: 'Reactants are CO₂ and H₂O. Oxygen and glucose are the products.' },
    { type: 'fill', q: 'In the chemical equation, six molecules of ___ react with six molecules of ___ to make glucose.',
      blanks: 2, correct: [['carbon dioxide', 'CO2', 'CO₂'], ['water', 'H2O', 'H₂O']],
      expl: '6CO₂ + 6H₂O + light → C₆H₁₂O₆ + 6O₂.' },
    { type: 'multi', q: 'Select all conditions required for photosynthesis to happen.',
      opts: ['Sunlight', 'Chlorophyll', 'Soil', 'Carbon dioxide', 'Wind'], correct: [0, 1, 3],
      expl: 'Light, chlorophyll and CO₂ are essential. Soil aids water uptake but is not strictly required (hydroponics works). Wind is irrelevant.' },
    { type: 'short', q: 'In one word, name the energy-storage molecule produced by photosynthesis.',
      correct: ['glucose'],
      expl: 'Glucose stores chemical energy in its bonds, available to the plant later.' },
  ],
  linear: [
    { type: 'mcq', q: 'What value of x satisfies  9x = 81?',
      opts: ['7', '8', '9', '10'], correct: 2,
      expl: 'Divide both sides by 9 → x = 9.' },
    { type: 'numeric', q: 'Solve:  6x − 14 = 4',
      correct: 3, tolerance: 0,
      expl: '6x = 18  →  x = 3.' },
    { type: 'fill', q: 'When you move a term across the "=" sign, you change its ___ .',
      blanks: 1, correct: [['sign']],
      expl: 'Transposition flips the sign — additive becomes subtractive.' },
  ],
  grammar: [
    { type: 'fill', q: 'She ___ (write) a book since last summer.',
      blanks: 1, correct: [['has been writing', 'has written']],
      expl: 'Present-perfect-continuous is the most natural fit with "since last summer".' },
    { type: 'tf', q: '"He don\'t play cricket" is correct.', correct: false,
      expl: 'Third person singular needs "doesn\'t" — "He doesn\'t play cricket".' },
    { type: 'mcq', q: 'Which is the past-perfect form of "go"?',
      opts: ['gone', 'went', 'had gone', 'has gone'], correct: 2,
      expl: 'Past-perfect = had + past participle → "had gone".' },
  ],
  civics: [
    { type: 'mcq', q: 'Which house of Parliament is permanent?',
      opts: ['Lok Sabha', 'Rajya Sabha', 'Vidhan Sabha', 'None'], correct: 1,
      expl: 'Rajya Sabha (Council of States) is permanent — it is never dissolved.' },
    { type: 'fill', q: 'The ___ of India is the head of state.',
      blanks: 1, correct: [['president', 'President']],
      expl: 'The President is the head of state under Articles 52–62.' },
    { type: 'tf', q: 'The Indian Constitution can be amended.', correct: true,
      expl: 'Article 368 provides the procedure to amend the Constitution.' },
  ],
  history: [
    { type: 'short', q: 'Name the leader who led the Salt March.',
      correct: ['mahatma gandhi', 'gandhi', 'mohandas gandhi'],
      expl: 'Mahatma Gandhi led the 24-day, 240-mile Dandi March in 1930.' },
    { type: 'mcq', q: 'In which year was the Indian National Congress founded?',
      opts: ['1875', '1885', '1905', '1919'], correct: 1,
      expl: 'Founded in Bombay in December 1885.' },
  ],
  mental: [
    { type: 'numeric', q: '12 × 13 = ?', correct: 156, tolerance: 0,
      expl: '12 × 13 = (12 × 10) + (12 × 3) = 120 + 36 = 156.' },
    { type: 'numeric', q: 'What is 20% of 240?', correct: 48, tolerance: 0,
      expl: '0.20 × 240 = 48.' },
    { type: 'numeric', q: '√196 = ?', correct: 14, tolerance: 0,
      expl: '14² = 196.' },
  ],
};

// Class-average correct % per question type (used by the result topic-mastery bars).
// Type-keyed because a student's review groups answers by question type.
const CLASS_TYPE_AVG_PCT = {
  mcq: 78,
  multi: 62,
  tf: 84,
  numeric: 71,
  short: 65,
  fill: 60,
  match: 58,
};

// ─────────────────────────────────────────────────────────────
// PARENT VIEW — children + their recent assessment activity
// (read by ParentHome and parent profile spotlight; isolated here so
// any data shift updates both surfaces in one place.)
// ─────────────────────────────────────────────────────────────
const PARENT_KIDS_RESULTS = [
  {
    childId: 'aarav', name: 'Aarav', cls: '8-B', initial: 'A', clr: '',
    items: [
      { aid: 'a5', sub: 'Science', title: 'States of matter · Quiz',
        score: 18, scoreMax: 20, scorePct: 90, classAvgPct: 76,
        when: '2h ago', state: 'completed', icon: 'flask', clr: 'var(--success)', bg: 'var(--success-50)' },
      { aid: 'a4', sub: 'Mathematics', title: 'Mental math · Sprint 4',
        score: 17, scoreMax: 20, scorePct: 85, classAvgPct: 71,
        when: 'Mon · 9 Mar', state: 'completed', icon: 'flask', clr: 'var(--p600)', bg: 'var(--p50)' },
      { aid: 'a7', sub: 'History', title: 'Mid-term · Independence movement',
        when: 'Mon · 4:18 PM', state: 'awaiting', icon: 'globe', clr: 'var(--warning)', bg: 'var(--warning-50)' },
    ],
  },
  {
    childId: 'diya', name: 'Diya', cls: '5-A', initial: 'D', clr: 'coral',
    items: [
      { sub: 'Hindi', title: 'Class test · Vyakaran',
        score: 92, scoreMax: 100, scorePct: 92, classAvgPct: 74,
        when: '4h ago', state: 'completed', icon: 'book-open', clr: '#1E40AF', bg: 'var(--info-50)' },
    ],
  },
  {
    childId: 'vihaan', name: 'Vihaan', cls: '2-C', initial: 'V', clr: 'green',
    items: [
      { sub: 'English', title: 'Reading worksheet',
        when: 'Today · 11 AM', state: 'awaiting', icon: 'book-open', clr: '#1E40AF', bg: 'var(--info-50)' },
    ],
  },
];
window.PARENT_KIDS_RESULTS = PARENT_KIDS_RESULTS;
window.CLASS_TYPE_AVG_PCT = CLASS_TYPE_AVG_PCT;
window.PRACTICE_POOL = PRACTICE_POOL;

const LEADERBOARD = [
  { rank: 1, name: 'Ananya Sharma', cls: '8-B', avg: 96, tests: 12, badge: '🥇' },
  { rank: 2, name: 'Rahul Iyer', cls: '8-B', avg: 94, tests: 12, badge: '🥈' },
  { rank: 3, name: 'Diya Kapoor', cls: '8-B', avg: 92, tests: 11, badge: '🥉' },
  { rank: 4, name: 'Aarav Reddy', cls: '8-B', avg: 89, tests: 11, badge: '', isMe: true },
  { rank: 5, name: 'Vihaan Mehta', cls: '8-B', avg: 87, tests: 12, badge: '' },
  { rank: 6, name: 'Saanvi Patel', cls: '8-B', avg: 85, tests: 10, badge: '' },
  { rank: 7, name: 'Arjun Nair', cls: '8-B', avg: 84, tests: 12, badge: '' },
  { rank: 8, name: 'Kavya Menon', cls: '8-B', avg: 82, tests: 11, badge: '' },
  { rank: 9, name: 'Ishaan Joshi', cls: '8-B', avg: 81, tests: 10, badge: '' },
  { rank: 10, name: 'Myra Bose', cls: '8-B', avg: 79, tests: 11, badge: '' },
  { rank: 11, name: 'Veer Khanna', cls: '8-B', avg: 78, tests: 11, badge: '' },
  { rank: 12, name: 'Aadhya Rao', cls: '8-B', avg: 76, tests: 9, badge: '' },
];

window.ASSESSMENTS = ASSESSMENTS;
window.STUDENT_CONTEXT = STUDENT_CONTEXT;
window.LEADERBOARD = LEADERBOARD;
window.BANKS = BANKS;

// ─────────────────────────────────────────────────────────────
// HUB — assigned · completed · leaderboard
// ─────────────────────────────────────────────────────────────
function AssessmentsHubScreen({ nav, params }) {
  const initialTab = (params && params.tab) || 'assigned';
  const [tab, setTab] = useStateA(['assigned', 'history'].includes(initialTab) ? initialTab : 'assigned');

  const assigned  = ASSESSMENTS.filter(a => a.state === 'assigned' || a.state === 'in_progress');
  const awaiting  = ASSESSMENTS.filter(a => a.state === 'awaiting');
  const completed = ASSESSMENTS.filter(a => a.state === 'completed');
  const history   = [...awaiting, ...completed];
  const avg = Math.round(completed.reduce((s, a) => s + a.scorePct, 0) / Math.max(completed.length, 1));

  return (
    <div className="app screen-in">
      <StatusBar/>
      <NavHeader title="Assessments" onBack={() => nav.pop()}
        right={<button onClick={() => nav.push('leaderboard')} style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--n50)', display: 'grid', placeItems: 'center' }} aria-label="Class leaderboard"><Icon name="trophy" size={18}/></button>}
      />

      {/* Class context strip — clarifies "this class only" filtering */}
      <div style={{ padding: '0 20px 12px' }}>
        <div className="row" style={{ gap: 10, padding: '10px 12px', background: 'var(--p50)', borderRadius: 11, border: '1px solid var(--n100)' }}>
          <div style={{ width: 28, height: 28, borderRadius: 8, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
            <Icon name="grad" size={14}/>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--p700)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>YOUR CLASS</div>
            <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--n900)', marginTop: 1 }}>Class {STUDENT_CONTEXT.cls} · {STUDENT_CONTEXT.school}</div>
          </div>
          <span className="pill pill-p" style={{ fontSize: 10 }}>Filtered</span>
        </div>
      </div>

      {/* Hero stats */}
      <div style={{ padding: '0 20px 14px' }}>
        <div className="card-flat" style={{ padding: 14, display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 8 }}>
          {[
            { v: assigned.length, l: 'Pending', clr: 'var(--c600)' },
            { v: awaiting.length, l: 'Awaiting', clr: 'var(--warning)' },
            { v: completed.length, l: 'Completed', clr: 'var(--n900)' },
            { v: `${avg}%`, l: 'Avg', clr: 'var(--success)' },
          ].map((s, i) => (
            <div key={i} style={{ textAlign: 'center', borderRight: i < 3 ? '1px solid var(--n200)' : 'none' }}>
              <div style={{ fontSize: 18, fontWeight: 800, color: s.clr, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>{s.v}</div>
              <div style={{ fontSize: 9.5, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>{s.l}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Segmented tabs */}
      <div style={{ padding: '0 20px 14px' }}>
        <div className="row" style={{ gap: 6, padding: 4, background: 'var(--n50)', borderRadius: 12 }}>
          {[
            { id: 'assigned', lab: 'Assigned', count: assigned.length },
            { id: 'history', lab: 'History', count: history.length },
          ].map(t => (
            <button key={t.id} onClick={() => setTab(t.id)} style={{
              flex: 1, height: 36, borderRadius: 9, fontSize: 12, fontWeight: 700,
              background: tab === t.id ? '#fff' : 'transparent',
              color: tab === t.id ? 'var(--n900)' : 'var(--n600)',
              boxShadow: tab === t.id ? 'var(--el-1)' : 'none',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
            }}>
              {t.lab}
              {t.count != null && <span style={{
                display: 'inline-grid', placeItems: 'center', minWidth: 18, height: 18, padding: '0 5px',
                borderRadius: 99, fontSize: 10, fontWeight: 800,
                background: tab === t.id ? 'var(--n900)' : 'var(--n200)',
                color: tab === t.id ? '#fff' : 'var(--n600)',
              }}>{t.count}</span>}
            </button>
          ))}
        </div>
      </div>

      <div className="app-body" style={{ paddingTop: 0 }}>
        {tab === 'assigned' && <AssignedList nav={nav} items={assigned}/>}
        {tab === 'history'  && <HistoryList nav={nav} awaiting={awaiting} completed={completed}/>}
      </div>
    </div>
  );
}

function AssignedList({ nav, items }) {
  if (items.length === 0) {
    return (
      <div className="card" style={{ padding: 28, textAlign: 'center' }}>
        <div style={{ fontSize: 28 }}>🎉</div>
        <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 8 }}>You're all caught up</div>
        <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 4 }}>No pending assessments for Class {STUDENT_CONTEXT.cls}</div>
      </div>
    );
  }
  return (
    <div className="col" style={{ gap: 10 }}>
      {items.map(a => (
        <button key={a.id} onClick={() => nav.push(a.state === 'in_progress' ? 'assessmentAttempt' : 'assessmentIntro', { id: a.id })}
          className="card" style={{ padding: 14, textAlign: 'left', borderLeft: `3px solid ${a.urgency === 'late' ? 'var(--c500)' : a.urgency === 'soon' ? 'var(--warning)' : 'var(--n200)'}` }}>
          <div className="spread" style={{ marginBottom: 8 }}>
            <div className="row" style={{ gap: 10 }}>
              <div style={{ width: 36, height: 36, borderRadius: 10, background: a.bg, color: a.clr, display: 'grid', placeItems: 'center' }}><Icon name={a.icon} size={18}/></div>
              <div>
                <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.06em', fontFamily: 'var(--mono)' }}>{a.sub.toUpperCase()}</div>
                <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--n900)', marginTop: 1 }}>{a.title}</div>
              </div>
            </div>
            {a.state === 'in_progress' ? (
              <span className="pill pill-p">In progress</span>
            ) : a.urgency === 'late' ? (
              <span className="pill pill-c">⏰ Due soon</span>
            ) : a.urgency === 'soon' ? (
              <span className="pill pill-w">Tomorrow</span>
            ) : (
              <span className="pill">{a.dueOn.split(' ').slice(0, 2).join(' ')}</span>
            )}
          </div>
          <div className="row" style={{ gap: 14, paddingLeft: 46, flexWrap: 'wrap', rowGap: 6 }}>
            <MetaItem icon="clipboard" lab={`${a.qCount} questions`}/>
            <MetaItem icon="clock" lab={`${a.durationMin} min`}/>
            <ResultModeChip mode={a.resultsMode}/>
          </div>
          {a.state === 'in_progress' && (
            <div style={{ marginTop: 10, paddingLeft: 46 }}>
              <div className="spread" style={{ marginBottom: 4 }}>
                <div style={{ fontSize: 10, color: 'var(--n500)', fontWeight: 600 }}>Resume — {a.progress} of {a.qCount} answered</div>
                <div style={{ fontSize: 10, color: 'var(--p600)', fontFamily: 'var(--mono)', fontWeight: 700 }}>{Math.round(a.progress / a.qCount * 100)}%</div>
              </div>
              <div style={{ height: 4, background: 'var(--n100)', borderRadius: 99, overflow: 'hidden' }}>
                <div style={{ width: `${a.progress / a.qCount * 100}%`, height: '100%', background: 'var(--p600)', borderRadius: 99 }}></div>
              </div>
            </div>
          )}
        </button>
      ))}
    </div>
  );
}

function HistoryList({ nav, awaiting, completed }) {
  const [subj, setSubj] = useStateA('all');
  const [query, setQuery] = useStateA('');

  // Build subject chip list from the history's actual subjects
  const subjects = useMemoA(() => {
    const seen = new Map();
    [...awaiting, ...completed].forEach(a => {
      if (!seen.has(a.sub)) seen.set(a.sub, { id: a.sub, lab: a.sub, n: 0 });
      seen.get(a.sub).n += 1;
    });
    return [{ id: 'all', lab: 'All', n: awaiting.length + completed.length }, ...Array.from(seen.values())];
  }, [awaiting, completed]);

  const matches = (a) => {
    if (subj !== 'all' && a.sub !== subj) return false;
    if (!query.trim()) return true;
    const q = query.trim().toLowerCase();
    return (
      a.title.toLowerCase().includes(q) ||
      a.sub.toLowerCase().includes(q) ||
      (a.by || '').toLowerCase().includes(q)
    );
  };
  const aw = awaiting.filter(matches);
  const co = completed.filter(matches);
  const totalShown = aw.length + co.length;

  if (awaiting.length === 0 && completed.length === 0) {
    return (
      <div className="card" style={{ padding: 28, textAlign: 'center' }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>No history yet</div>
        <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 4 }}>Submitted assessments will show up here.</div>
      </div>
    );
  }
  return (
    <div className="col" style={{ gap: 14 }}>
      {/* Filter chips + search (#7) */}
      <div className="col" style={{ gap: 10 }}>
        <div className="row" style={{
          gap: 10, padding: '10px 12px', background: '#fff',
          border: '1px solid var(--n100)', borderRadius: 12,
        }}>
          <Icon name="search" size={16} style={{ color: 'var(--n400)', flexShrink: 0 }}/>
          <input
            value={query}
            onChange={e => setQuery(e.target.value)}
            placeholder="Search by title, subject, or teacher"
            style={{
              flex: 1, border: 0, outline: 'none', background: 'transparent',
              fontSize: 13, fontWeight: 500, color: 'var(--n900)', fontFamily: 'inherit',
            }}
          />
          {query && (
            <button onClick={() => setQuery('')} style={{ width: 22, height: 22, borderRadius: 99, background: 'var(--n100)', color: 'var(--n600)', display: 'grid', placeItems: 'center' }}>
              <Icon name="x" size={11}/>
            </button>
          )}
        </div>
        <div style={{ display: 'flex', gap: 8, overflowX: 'auto', margin: '0 -20px', padding: '0 20px 4px' }}>
          {subjects.map(s => (
            <button key={s.id} onClick={() => setSubj(s.id)} style={{
              flexShrink: 0, padding: '7px 12px', borderRadius: 99,
              fontSize: 11.5, fontWeight: 700,
              background: subj === s.id ? 'var(--n900)' : 'var(--n50)',
              color: subj === s.id ? '#fff' : 'var(--n700)',
              display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
              {s.lab}
              <span style={{
                display: 'inline-grid', placeItems: 'center', minWidth: 16, height: 16, padding: '0 4px',
                borderRadius: 99, fontSize: 9.5, fontWeight: 800,
                background: subj === s.id ? 'rgba(255,255,255,.22)' : 'var(--n200)',
                color: subj === s.id ? '#fff' : 'var(--n600)',
                fontFamily: 'var(--mono)',
              }}>{s.n}</span>
            </button>
          ))}
        </div>
        {(subj !== 'all' || query) && (
          <div className="spread" style={{ padding: '0 4px' }}>
            <div style={{ fontSize: 11, color: 'var(--n500)' }}>
              {totalShown === 0
                ? 'No matches'
                : `${totalShown} of ${awaiting.length + completed.length}`}
            </div>
            <button onClick={() => { setSubj('all'); setQuery(''); }} style={{ fontSize: 11, fontWeight: 700, color: 'var(--p600)', background: 'transparent' }}>
              Clear filters
            </button>
          </div>
        )}
      </div>

      {totalShown === 0 ? (
        <div className="card" style={{ padding: 28, textAlign: 'center' }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>Nothing matches</div>
          <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 4 }}>Try a different subject or search term.</div>
        </div>
      ) : null}

      {aw.length > 0 && (
        <div className="col" style={{ gap: 8 }}>
          <div className="spread" style={{ padding: '0 4px' }}>
            <div style={{ fontSize: 10.5, fontWeight: 800, color: 'var(--warning)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>AWAITING RESULTS</div>
            <div style={{ fontSize: 10, color: 'var(--n500)' }}>Teacher publishes</div>
          </div>
          {aw.map(a => (
            <button key={a.id} onClick={() => nav.push('assessmentResult', { id: a.id })}
              className="card row" style={{ padding: 14, gap: 12, textAlign: 'left', borderLeft: '3px solid var(--warning)' }}>
              <div style={{ width: 48, height: 48, borderRadius: 12, background: 'var(--warning-50)', color: 'var(--warning)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                <Icon name="clock" size={20}/>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="spread">
                  <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.06em', fontFamily: 'var(--mono)' }}>{a.sub.toUpperCase()}</div>
                  <span className="pill pill-w" style={{ fontSize: 9.5 }}>Pending</span>
                </div>
                <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 2 }}>{a.title}</div>
                <div className="row" style={{ gap: 10, marginTop: 6, flexWrap: 'wrap', rowGap: 4 }}>
                  <span style={{ fontSize: 10.5, color: 'var(--n500)' }}>Submitted {a.submittedOn?.split(' ').slice(0, 3).join(' ')}</span>
                  <span style={{ fontSize: 10.5, color: 'var(--n500)' }}>·</span>
                  <span style={{ fontSize: 10.5, color: 'var(--warning)', fontWeight: 700 }}>Results {a.willPublishOn}</span>
                </div>
              </div>
              <Icon name="chev-r" size={16} style={{ color: 'var(--n400)' }}/>
            </button>
          ))}
        </div>
      )}

      {co.length > 0 && (
        <div className="col" style={{ gap: 8 }}>
          {aw.length > 0 && (
            <div style={{ padding: '0 4px', fontSize: 10.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>RESULTS PUBLISHED</div>
          )}
          {co.map(a => (
            <button key={a.id} onClick={() => nav.push('assessmentResult', { id: a.id })}
              className="card row" style={{ padding: 14, gap: 12, textAlign: 'left' }}>
              <div style={{ width: 48, height: 48, borderRadius: 12, background: 'var(--n50)', color: a.clrGrade, display: 'grid', placeItems: 'center', fontSize: 14, fontWeight: 800, letterSpacing: '-.01em', flexShrink: 0 }}>{a.grade}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="spread">
                  <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.06em', fontFamily: 'var(--mono)' }}>{a.sub.toUpperCase()}</div>
                  <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--n900)', fontVariantNumeric: 'tabular-nums' }}>{a.score}/{a.scoreMax}</div>
                </div>
                <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 2 }}>{a.title}</div>
                <div className="row" style={{ gap: 10, marginTop: 6, flexWrap: 'wrap', rowGap: 4 }}>
                  <span style={{ fontSize: 10.5, color: 'var(--n500)' }}>Rank {a.classRank}</span>
                  <span style={{ fontSize: 10.5, color: 'var(--n500)' }}>·</span>
                  <span style={{ fontSize: 10.5, color: 'var(--n500)' }}>{a.timeTaken}</span>
                  {a.publishedOn && <>
                    <span style={{ fontSize: 10.5, color: 'var(--n500)' }}>·</span>
                    <span style={{ fontSize: 10.5, color: 'var(--n500)' }}>Published {a.publishedOn.split(' ').slice(0, 3).join(' ')}</span>
                  </>}
                </div>
              </div>
              <Icon name="chev-r" size={16} style={{ color: 'var(--n400)' }}/>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

function ResultModeChip({ mode }) {
  if (mode === 'instant') {
    return (
      <div className="row" style={{ gap: 4, color: 'var(--success)' }}>
        <Icon name="check" size={11}/>
        <span style={{ fontSize: 10.5, fontWeight: 700 }}>Instant results</span>
      </div>
    );
  }
  return (
    <div className="row" style={{ gap: 4, color: 'var(--warning)' }}>
      <Icon name="clock" size={11}/>
      <span style={{ fontSize: 10.5, fontWeight: 700 }}>Teacher publishes</span>
    </div>
  );
}

function MetaItem({ icon, lab }) {
  return (
    <div className="row" style={{ gap: 4, color: 'var(--n500)' }}>
      <Icon name={icon} size={12}/>
      <span style={{ fontSize: 10.5, fontWeight: 600 }}>{lab}</span>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// LEADERBOARD — inside hub + standalone
// ─────────────────────────────────────────────────────────────
function LeaderboardPanel({ nav }) {
  const [scope, setScope] = useStateA('class');
  const [period, setPeriod] = useStateA('month');
  const me = LEADERBOARD.find(r => r.isMe);
  const top3 = LEADERBOARD.slice(0, 3);
  const rest = LEADERBOARD.slice(3);

  return (
    <>
      {/* Filter chips */}
      <div className="row" style={{ gap: 8, marginBottom: 14, overflowX: 'auto', margin: '0 -20px 14px', padding: '0 20px' }}>
        {[
          { id: 'class', lab: 'Class 8-B' },
          { id: 'grade', lab: 'Grade 8' },
          { id: 'school', lab: 'DPS Hyderabad' },
        ].map(s => (
          <button key={s.id} onClick={() => setScope(s.id)} style={{
            flexShrink: 0, padding: '7px 12px', borderRadius: 99, fontSize: 11.5, fontWeight: 700,
            background: scope === s.id ? 'var(--n900)' : 'var(--n50)',
            color: scope === s.id ? '#fff' : 'var(--n700)',
          }}>{s.lab}</button>
        ))}
        <div style={{ width: 1, background: 'var(--n200)', flexShrink: 0, margin: '4px 4px' }}></div>
        {[
          { id: 'week', lab: 'This week' },
          { id: 'month', lab: 'This month' },
          { id: 'year', lab: 'This year' },
        ].map(p => (
          <button key={p.id} onClick={() => setPeriod(p.id)} style={{
            flexShrink: 0, padding: '7px 12px', borderRadius: 99, fontSize: 11.5, fontWeight: 700,
            background: period === p.id ? 'var(--p600)' : 'var(--n50)',
            color: period === p.id ? '#fff' : 'var(--n700)',
          }}>{p.lab}</button>
        ))}
      </div>

      {/* Top 3 podium */}
      <div className="card" style={{ padding: '20px 14px 14px', background: 'linear-gradient(180deg, var(--p50) 0%, #fff 70%)', marginBottom: 12 }}>
        <div className="row" style={{ gap: 8, alignItems: 'flex-end', justifyContent: 'center' }}>
          <PodiumStep r={top3[1]} h={86}/>
          <PodiumStep r={top3[0]} h={106} winner/>
          <PodiumStep r={top3[2]} h={70}/>
        </div>
      </div>

      {/* Your rank highlight */}
      {me && (
        <div className="card-tinted" style={{ padding: 12, marginBottom: 12, display: 'flex', alignItems: 'center', gap: 12 }}>
          <div style={{ width: 38, height: 38, borderRadius: 10, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center', fontSize: 13, fontWeight: 800 }}>#{me.rank}</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--p700)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>YOUR RANK</div>
            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 1 }}>{me.name} · {me.avg}% avg</div>
          </div>
          <div style={{ fontSize: 10.5, color: 'var(--p700)', fontWeight: 700 }}>↑ 2 this week</div>
        </div>
      )}

      {/* Full list */}
      <div className="card" style={{ padding: 0 }}>
        {rest.map((r, i, arr) => (
          <div key={r.rank} className="row" style={{
            padding: '11px 14px', gap: 12,
            borderBottom: i < arr.length - 1 ? '1px solid var(--n100)' : 'none',
            background: r.isMe ? 'var(--p50)' : '#fff',
          }}>
            <div style={{ width: 28, fontSize: 12, fontWeight: 700, color: r.isMe ? 'var(--p600)' : 'var(--n400)', fontFamily: 'var(--mono)', textAlign: 'center' }}>
              {r.rank}
            </div>
            <div className={`av av-32 ${r.rank % 4 === 1 ? '' : r.rank % 4 === 2 ? 'coral' : r.rank % 4 === 3 ? 'green' : 'sky'}`} style={{ width: 32, height: 32, fontSize: 12 }}>
              {r.name.charAt(0)}
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--n900)' }}>
                {r.name}
                {r.isMe && <span className="pill pill-p" style={{ marginLeft: 6, fontSize: 9 }}>YOU</span>}
              </div>
              <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 1 }}>{r.tests} tests · {r.cls}</div>
            </div>
            <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--n900)', fontVariantNumeric: 'tabular-nums' }}>{r.avg}%</div>
          </div>
        ))}
      </div>
    </>
  );
}

function PodiumStep({ r, h, winner }) {
  if (!r) return null;
  return (
    <div style={{ width: 92, textAlign: 'center' }}>
      <div style={{ fontSize: 22 }}>{r.badge}</div>
      <div className={`av av-44 ${winner ? '' : 'coral'}`} style={{ margin: '4px auto 6px', border: winner ? '3px solid var(--p600)' : '0' }}>{r.name.charAt(0)}</div>
      <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--n900)' }}>{r.name.split(' ')[0]}</div>
      <div style={{ fontSize: 10, color: 'var(--n500)', fontFamily: 'var(--mono)' }}>{r.avg}%</div>
      <div style={{ marginTop: 6, height: h, background: winner ? 'var(--p600)' : 'var(--n100)', color: winner ? '#fff' : 'var(--n700)', borderRadius: '8px 8px 0 0', display: 'grid', placeItems: 'center', fontSize: 22, fontWeight: 800, fontVariantNumeric: 'tabular-nums' }}>
        {r.rank}
      </div>
    </div>
  );
}

function LeaderboardScreen({ nav }) {
  return (
    <div className="app screen-in">
      <StatusBar/>
      <NavHeader title="Leaderboard" onBack={() => nav.pop()}/>
      <div className="app-body" style={{ paddingTop: 8 }}>
        <LeaderboardPanel nav={nav}/>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// PER-ASSESSMENT LEADERBOARD — ranked results for a single test
// ─────────────────────────────────────────────────────────────
function buildAssessmentLeaderboard(a) {
  if (!a) return [];
  const baseAvg = typeof a.classAvgPct === 'number' ? a.classAvgPct : (typeof a.scorePct === 'number' ? a.scorePct - 6 : 75);
  const myScore = typeof a.scorePct === 'number' ? a.scorePct : null;
  const totalSec = (a.durationMin || 20) * 60;
  const seed = (a.id || '').split('').reduce((s, c) => s + c.charCodeAt(0), 0) || 1;
  const rand = (i) => {
    const x = Math.sin(seed + i * 37) * 10000;
    return x - Math.floor(x);
  };
  const peers = LEADERBOARD.map((r, i) => {
    if (r.isMe) {
      return {
        ...r,
        score: myScore != null ? myScore : r.avg,
        timeSec: Math.round(totalSec * (0.55 + rand(i + 100) * 0.30)),
      };
    }
    const skill = (r.avg - 85) * 0.45;
    const noise = (rand(i) - 0.5) * 16;
    let score = Math.round(baseAvg + skill + noise);
    score = Math.max(38, Math.min(100, score));
    return {
      ...r,
      score,
      timeSec: Math.round(totalSec * (0.45 + rand(i + 50) * 0.45)),
    };
  });
  peers.sort((p, q) => (q.score - p.score) || (p.timeSec - q.timeSec));
  return peers.map((p, i) => ({ ...p, rank: i + 1, badge: i === 0 ? '🥇' : i === 1 ? '🥈' : i === 2 ? '🥉' : '' }));
}

function fmtMmSs(sec) {
  const m = Math.floor(sec / 60);
  const s = sec % 60;
  return `${m}:${String(s).padStart(2, '0')}`;
}

function AssessmentLeaderboardScreen({ nav, params }) {
  const a = ASSESSMENTS.find(x => x.id === (params && params.id)) || ASSESSMENTS.find(x => x.state === 'completed');
  const [sort, setSort] = useStateA('score');

  if (!a) {
    return (
      <div className="app screen-in">
        <StatusBar/>
        <NavHeader title="Leaderboard" onBack={() => nav.pop()}/>
        <div className="app-body">
          <div className="card" style={{ padding: 24, textAlign: 'center' }}>
            <div style={{ fontSize: 13, color: 'var(--n600)' }}>Assessment not found.</div>
          </div>
        </div>
      </div>
    );
  }

  const isPublished = a.state === 'completed';
  const baseList = buildAssessmentLeaderboard(a);
  const list = sort === 'time'
    ? [...baseList].sort((p, q) => p.timeSec - q.timeSec).map((p, i) => ({ ...p, rank: i + 1 }))
    : baseList;

  const me = baseList.find(r => r.isMe);
  const top3 = list.slice(0, 3);
  const rest = list.slice(3);
  const top = list[0];
  const classAvg = Math.round(baseList.reduce((s, r) => s + r.score, 0) / baseList.length);

  if (!isPublished) {
    return (
      <div className="app screen-in">
        <StatusBar/>
        <NavHeader title="Leaderboard" onBack={() => nav.pop()}/>
        <div className="app-body" style={{ paddingTop: 4 }}>
          <div style={{ padding: '0 0 14px' }}>
            <div className="card-flat" style={{ padding: 14 }}>
              <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>{a.subject?.toUpperCase()}</div>
              <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)', marginTop: 2 }}>{a.title}</div>
              <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 2 }}>Class {STUDENT_CONTEXT.cls} · {STUDENT_CONTEXT.school}</div>
            </div>
          </div>
          <div className="card" style={{ padding: 24, textAlign: 'center' }}>
            <div style={{ width: 56, height: 56, borderRadius: 16, background: 'var(--warning-50)', color: 'var(--warning)', display: 'grid', placeItems: 'center', margin: '0 auto 12px' }}><Icon name="clock" size={24}/></div>
            <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)' }}>Leaderboard not available yet</div>
            <div style={{ fontSize: 12, color: 'var(--n600)', marginTop: 6, lineHeight: 1.5 }}>
              Results for this assessment haven't been published.
              {a.state === 'awaiting' ? ' You\'ve submitted — your teacher is grading.' : ' Once results are out, the class leaderboard will appear here.'}
            </div>
            <button onClick={() => nav.pop()} className="btn btn-outline" style={{ marginTop: 14, height: 42 }}>Back</button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="app screen-in">
      <StatusBar/>
      <NavHeader title="Leaderboard" onBack={() => nav.pop()}/>
      <div className="app-body" style={{ paddingTop: 4 }}>
        {/* Assessment context strip */}
        <div style={{ padding: '0 0 12px' }}>
          <div className="card-flat" style={{ padding: 14 }}>
            <div className="row" style={{ gap: 10 }}>
              <div style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--p50)', color: 'var(--p600)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                <Icon name="trophy" size={16}/>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>{(a.subject || '').toUpperCase()}</div>
                <div style={{ fontSize: 13.5, fontWeight: 800, color: 'var(--n900)', marginTop: 1 }}>{a.title}</div>
                <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 2 }}>Class {STUDENT_CONTEXT.cls} · {LEADERBOARD.length} students · {a.questions || (BANKS[a.bank] || []).length} questions</div>
              </div>
            </div>
          </div>
        </div>

        {/* Snapshot stats */}
        <div style={{ padding: '0 0 12px' }}>
          <div className="card-flat" style={{ padding: 12, display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 8 }}>
            {[
              { l: 'Top score', v: `${top ? top.score : '—'}%`, sub: top ? top.name.split(' ')[0] : '', clr: 'var(--success)' },
              { l: 'Class avg', v: `${classAvg}%`, sub: 'across all', clr: 'var(--n900)' },
              { l: 'Your rank', v: me ? `#${me.rank}` : '—', sub: me ? `${me.score}%` : '', clr: 'var(--p600)' },
            ].map((s, i) => (
              <div key={i} style={{ textAlign: 'center', borderRight: i < 2 ? '1px solid var(--n200)' : 'none' }}>
                <div style={{ fontSize: 9.5, color: 'var(--n500)', fontWeight: 700, letterSpacing: '.06em', fontFamily: 'var(--mono)' }}>{s.l.toUpperCase()}</div>
                <div style={{ fontSize: 17, fontWeight: 800, color: s.clr, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em', marginTop: 4 }}>{s.v}</div>
                {s.sub && <div style={{ fontSize: 10, color: 'var(--n500)', marginTop: 1 }}>{s.sub}</div>}
              </div>
            ))}
          </div>
        </div>

        {/* Sort toggle */}
        <div style={{ padding: '0 0 12px' }}>
          <div className="row" style={{ gap: 6, padding: 4, background: 'var(--n50)', borderRadius: 11 }}>
            {[
              { id: 'score', lab: 'Highest score' },
              { id: 'time', lab: 'Fastest finish' },
            ].map(s => (
              <button key={s.id} onClick={() => setSort(s.id)} style={{
                flex: 1, height: 32, borderRadius: 8, fontSize: 11.5, fontWeight: 700,
                background: sort === s.id ? '#fff' : 'transparent',
                color: sort === s.id ? 'var(--n900)' : 'var(--n600)',
                boxShadow: sort === s.id ? 'var(--el-1)' : 'none',
              }}>{s.lab}</button>
            ))}
          </div>
        </div>

        {/* Top 3 podium */}
        <div className="card" style={{ padding: '20px 14px 14px', background: 'linear-gradient(180deg, var(--p50) 0%, #fff 70%)', marginBottom: 12 }}>
          <div className="row" style={{ gap: 8, alignItems: 'flex-end', justifyContent: 'center' }}>
            <AsmtPodium r={top3[1]} h={86} sort={sort}/>
            <AsmtPodium r={top3[0]} h={106} winner sort={sort}/>
            <AsmtPodium r={top3[2]} h={70} sort={sort}/>
          </div>
        </div>

        {/* Your rank highlight */}
        {me && (
          <div className="card-tinted" style={{ padding: 12, marginBottom: 12, display: 'flex', alignItems: 'center', gap: 12 }}>
            <div style={{ width: 38, height: 38, borderRadius: 10, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center', fontSize: 13, fontWeight: 800 }}>#{me.rank}</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--p700)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>YOUR RESULT</div>
              <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 1 }}>{me.score}% · {fmtMmSs(me.timeSec)} taken</div>
            </div>
            <div style={{ fontSize: 10.5, color: me.score >= classAvg ? 'var(--success)' : 'var(--c600)', fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>
              {me.score >= classAvg ? '↑' : '↓'} {Math.abs(me.score - classAvg)} pts vs avg
            </div>
          </div>
        )}

        {/* Full ranked list */}
        <div className="card" style={{ padding: 0 }}>
          {rest.map((r, i, arr) => (
            <div key={r.name} className="row" style={{
              padding: '11px 14px', gap: 12,
              borderBottom: i < arr.length - 1 ? '1px solid var(--n100)' : 'none',
              background: r.isMe ? 'var(--p50)' : '#fff',
            }}>
              <div style={{ width: 28, fontSize: 12, fontWeight: 700, color: r.isMe ? 'var(--p600)' : 'var(--n400)', fontFamily: 'var(--mono)', textAlign: 'center' }}>
                {r.rank}
              </div>
              <div className={`av av-32 ${r.rank % 4 === 1 ? '' : r.rank % 4 === 2 ? 'coral' : r.rank % 4 === 3 ? 'green' : 'sky'}`} style={{ width: 32, height: 32, fontSize: 12 }}>
                {r.name.charAt(0)}
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--n900)' }}>
                  {r.name}
                  {r.isMe && <span className="pill pill-p" style={{ marginLeft: 6, fontSize: 9 }}>YOU</span>}
                </div>
                <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 1, fontFamily: 'var(--mono)' }}>{fmtMmSs(r.timeSec)} · {r.cls}</div>
              </div>
              <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--n900)', fontVariantNumeric: 'tabular-nums' }}>{r.score}%</div>
            </div>
          ))}
        </div>

        {/* Cross-link to class-wide */}
        <button onClick={() => nav.push('leaderboard')} className="card row" style={{ padding: 14, gap: 12, width: '100%', textAlign: 'left', marginTop: 12 }}>
          <div style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--n50)', color: 'var(--n700)', display: 'grid', placeItems: 'center' }}><Icon name="bar-chart" size={16}/></div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 12.5, fontWeight: 800, color: 'var(--n900)' }}>Class-wide leaderboard</div>
            <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 1 }}>Average across all assessments this term</div>
          </div>
          <Icon name="chev-r" size={14} style={{ color: 'var(--n400)' }}/>
        </button>
      </div>
    </div>
  );
}

function AsmtPodium({ r, h, winner, sort }) {
  if (!r) return null;
  const headline = sort === 'time' ? fmtMmSs(r.timeSec) : `${r.score}%`;
  return (
    <div style={{ width: 92, textAlign: 'center' }}>
      <div style={{ fontSize: 22 }}>{r.badge}</div>
      <div className={`av av-44 ${winner ? '' : 'coral'}`} style={{ margin: '4px auto 6px', border: winner ? '3px solid var(--p600)' : '0' }}>{r.name.charAt(0)}</div>
      <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--n900)' }}>{r.name.split(' ')[0]}</div>
      <div style={{ fontSize: 10, color: 'var(--n500)', fontFamily: 'var(--mono)' }}>{headline}</div>
      <div style={{ marginTop: 6, height: h, background: winner ? 'var(--p600)' : 'var(--n100)', color: winner ? '#fff' : 'var(--n700)', borderRadius: '8px 8px 0 0', display: 'grid', placeItems: 'center', fontSize: 22, fontWeight: 800, fontVariantNumeric: 'tabular-nums' }}>
        {r.rank}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// INTRO — assessment cover before starting
// ─────────────────────────────────────────────────────────────
function AssessmentIntroScreen({ nav, params }) {
  const a = ASSESSMENTS.find(x => x.id === (params && params.id)) || ASSESSMENTS[0];
  const isInstant = a.resultsMode === 'instant';
  const types = summarizeTypes(a);
  const rules = [
    'Once you start, the timer cannot be paused.',
    'You can mark questions for review and revisit them.',
    'Submitting before time ends is allowed.',
    isInstant
      ? 'You will see your score and explanations right after submitting.'
      : 'Your teacher will publish results — you\'ll see your score later.',
    'Stay in the app — leaving may auto-submit.',
  ];
  return (
    <div className="app screen-in">
      <StatusBar/>
      <NavHeader title="Quiz" onBack={() => nav.pop()}/>
      <div className="app-body" style={{ paddingTop: 4 }}>
        {/* Cover */}
        <div className="card" style={{ padding: 18 }}>
          <div className="row" style={{ gap: 12, marginBottom: 12 }}>
            <div style={{ width: 44, height: 44, borderRadius: 12, background: a.bg, color: a.clr, display: 'grid', placeItems: 'center' }}><Icon name={a.icon} size={22}/></div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>{a.sub.toUpperCase()} · {a.cls}</div>
              <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--n900)', letterSpacing: '-.01em', marginTop: 2 }}>{a.title}</div>
            </div>
          </div>
          <div style={{ fontSize: 12, color: 'var(--n600)' }}>Set by <b style={{ color: 'var(--n900)' }}>{a.by}</b> · assigned {a.assignedOn}</div>
        </div>

        {/* Result-mode banner */}
        <div className="row" style={{
          gap: 12, padding: 12, borderRadius: 12,
          background: isInstant ? 'var(--success-50)' : 'var(--warning-50)',
          border: `1px solid ${isInstant ? '#A7F3D0' : '#FDE68A'}`,
        }}>
          <div style={{
            width: 36, height: 36, borderRadius: 10,
            background: isInstant ? 'var(--success)' : 'var(--warning)',
            color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0,
          }}>
            <Icon name={isInstant ? 'check' : 'clock'} size={18}/>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.08em', fontFamily: 'var(--mono)', color: isInstant ? 'var(--success)' : 'var(--warning)' }}>
              {isInstant ? 'INSTANT RESULTS' : 'RESULTS PUBLISHED LATER'}
            </div>
            <div style={{ fontSize: 12, color: 'var(--n700)', marginTop: 2, lineHeight: 1.45 }}>
              {isInstant
                ? 'Your score and explanations appear the moment you submit.'
                : `${a.by} will publish results after grading. You'll be notified.`}
            </div>
          </div>
        </div>

        {/* Stats grid */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gap: 10 }}>
          {[
            { ic: 'clipboard', v: `${a.qCount}`, l: 'Questions' },
            { ic: 'clock', v: `${a.durationMin} min`, l: 'Time limit' },
            { ic: 'target', v: `${a.marks}`, l: 'Total marks' },
            { ic: 'history', v: a.attempts, l: 'Attempts' },
          ].map((s, i) => (
            <div key={i} className="card-flat" style={{ padding: 14 }}>
              <div style={{ width: 32, height: 32, borderRadius: 9, background: 'var(--n50)', color: 'var(--n700)', display: 'grid', placeItems: 'center' }}><Icon name={s.ic} size={16}/></div>
              <div style={{ fontSize: 17, fontWeight: 800, color: 'var(--n900)', marginTop: 10, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.01em' }}>{s.v}</div>
              <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>{s.l}</div>
            </div>
          ))}
        </div>

        {/* Question types breakdown */}
        <div>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginBottom: 10 }}>What you'll be answering</div>
          <div className="card" style={{ padding: 4 }}>
            {types.map((t, i, arr) => (
              <div key={t.t} className="row" style={{ padding: '10px 12px', gap: 10, borderBottom: i < arr.length - 1 ? '1px solid var(--n100)' : 'none' }}>
                <div style={{ width: 28, height: 28, borderRadius: 8, background: 'var(--p50)', color: 'var(--p600)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                  <Icon name={TYPE_META[t.t]?.icon || 'circle'} size={14}/>
                </div>
                <div style={{ flex: 1, fontSize: 12.5, color: 'var(--n900)', fontWeight: 600 }}>{t.lab}</div>
                <div style={{ fontSize: 11.5, fontWeight: 800, color: 'var(--n700)', fontVariantNumeric: 'tabular-nums', fontFamily: 'var(--mono)' }}>×{t.n}</div>
              </div>
            ))}
          </div>
        </div>

        {/* Due card */}
        <div className="card-tinted" style={{ padding: 14, display: 'flex', gap: 12 }}>
          <Icon name="clock" size={18} style={{ color: a.urgency === 'late' ? 'var(--c600)' : 'var(--p600)', flexShrink: 0, marginTop: 2 }}/>
          <div>
            <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--p700)', letterSpacing: '.06em', fontFamily: 'var(--mono)' }}>DUE</div>
            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 1 }}>{a.dueOn}</div>
          </div>
        </div>

        {/* Rules */}
        <div>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginBottom: 10 }}>Before you start</div>
          <div className="card" style={{ padding: 0 }}>
            {rules.map((r, i) => (
              <div key={i} className="row" style={{ padding: '11px 14px', gap: 10, borderBottom: i < rules.length - 1 ? '1px solid var(--n100)' : 'none' }}>
                <div style={{ width: 22, height: 22, borderRadius: 99, background: 'var(--p50)', color: 'var(--p600)', display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 800, flexShrink: 0 }}>{i + 1}</div>
                <div style={{ fontSize: 12, color: 'var(--n700)', lineHeight: 1.5 }}>{r}</div>
              </div>
            ))}
          </div>
        </div>

        {/* CTA */}
        <button onClick={() => nav.push('assessmentAttempt', { id: a.id })} className="btn" style={{ marginTop: 8, height: 50 }}>
          Start now <Icon name="arrow-right" size={16}/>
        </button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// ATTEMPT — the live test (type-aware)
// ─────────────────────────────────────────────────────────────
function isAnswered(q, ans) {
  if (ans === null || ans === undefined) return false;
  switch (q.type) {
    case 'multi': return Array.isArray(ans) && ans.length > 0;
    case 'fill':  return Array.isArray(ans) && ans.length === q.blanks && ans.every(s => s && String(s).trim().length > 0);
    case 'match': return Array.isArray(ans) && ans.length === q.pairs.length && ans.every(v => v !== null && v !== undefined);
    case 'numeric':
    case 'short': return typeof ans === 'string' ? ans.trim().length > 0 : ans !== null;
    case 'tf':    return typeof ans === 'boolean';
    case 'mcq':
    default:      return typeof ans === 'number';
  }
}

function emptyAnswer(q) {
  switch (q.type) {
    case 'multi': return [];
    case 'fill':  return Array(q.blanks).fill('');
    case 'match': return q.pairs.map(() => null);
    case 'numeric':
    case 'short': return '';
    default:      return null;
  }
}

function AssessmentAttemptScreen({ nav, params }) {
  const a = ASSESSMENTS.find(x => x.id === (params && params.id)) || ASSESSMENTS[0];
  const Q = banksFor(a);
  const [idx, setIdx] = useStateA(a.state === 'in_progress' ? Math.min(a.progress || 0, Q.length - 1) : 0);
  const [answers, setAnswers] = useStateA(() => Q.map(emptyAnswer));
  const [marked, setMarked] = useStateA(() => new Set());
  const [secondsLeft, setSecondsLeft] = useStateA(a.durationMin * 60);
  const [paletteOpen, setPaletteOpen] = useStateA(false);
  const [confirmSubmit, setConfirmSubmit] = useStateA(false);

  useEffectA(() => {
    if (secondsLeft <= 0) return;
    const t = setInterval(() => setSecondsLeft(s => Math.max(0, s - 1)), 1000);
    return () => clearInterval(t);
  }, [secondsLeft]);

  const mm = String(Math.floor(secondsLeft / 60)).padStart(2, '0');
  const ss = String(secondsLeft % 60).padStart(2, '0');
  const isLow = secondsLeft < 60;

  const answeredCount = answers.reduce((n, ans, i) => n + (isAnswered(Q[i], ans) ? 1 : 0), 0);
  const q = Q[idx];
  const marksPer = +(a.marks / a.qCount).toFixed(2);

  const setAnswer = (val) => setAnswers(prev => prev.map((p, i) => i === idx ? val : p));
  const toggleMark = () => setMarked(prev => {
    const next = new Set(prev);
    if (next.has(idx)) next.delete(idx); else next.add(idx);
    return next;
  });
  const goto = (i) => { setIdx(i); setPaletteOpen(false); };

  const submit = () => {
    if (a.resultsMode === 'instant') {
      nav.replace('assessmentResult', { id: a.id, answers, live: true });
    } else {
      nav.replace('assessmentSubmitted', { id: a.id, answers, answeredCount, total: Q.length });
    }
  };

  return (
    <div className="app screen-in" style={{ background: 'var(--n50)' }}>
      <StatusBar/>

      {/* Top bar — timer + question count + palette */}
      <div style={{ background: '#fff', borderBottom: '1px solid var(--n100)', padding: '10px 16px' }}>
        <div className="spread" style={{ marginBottom: 8 }}>
          <button onClick={() => nav.pop()} className="row" style={{ gap: 6, fontSize: 12, fontWeight: 600, color: 'var(--n600)' }}>
            <Icon name="x" size={14}/> Exit
          </button>
          <div className="row" style={{ gap: 8 }}>
            <div className="row" style={{ gap: 6, padding: '6px 10px', background: isLow ? 'var(--c50)' : 'var(--n50)', borderRadius: 9, color: isLow ? 'var(--c600)' : 'var(--n900)' }}>
              <Icon name="clock" size={14}/>
              <span style={{ fontSize: 13, fontWeight: 800, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.01em' }}>{mm}:{ss}</span>
            </div>
            <button onClick={() => setPaletteOpen(true)} style={{ width: 36, height: 32, borderRadius: 9, background: 'var(--n50)', display: 'grid', placeItems: 'center' }}>
              <Icon name="more" size={16}/>
            </button>
          </div>
        </div>
        {/* Progress bar */}
        <div className="spread" style={{ marginBottom: 6 }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--n700)' }}>Question {idx + 1} of {Q.length}</div>
          <div style={{ fontSize: 10.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 700 }}>{answeredCount}/{Q.length} answered</div>
        </div>
        <div style={{ height: 4, background: 'var(--n100)', borderRadius: 99, overflow: 'hidden' }}>
          <div style={{ width: `${(idx + 1) / Q.length * 100}%`, height: '100%', background: 'var(--p600)', borderRadius: 99, transition: 'width .25s' }}></div>
        </div>
      </div>

      {/* Question body */}
      <div className="app-body" style={{ paddingTop: 16, paddingBottom: 110, gap: 14 }}>
        <div className="card" style={{ padding: 18 }}>
          <div className="spread" style={{ marginBottom: 12 }}>
            <div className="row" style={{ gap: 8 }}>
              <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--p600)', letterSpacing: '.1em', fontFamily: 'var(--mono)' }}>Q{idx + 1} · {marksPer} MARKS</div>
              <span className="pill" style={{ fontSize: 9.5, padding: '2px 7px', background: 'var(--n50)', color: 'var(--n700)', fontWeight: 700 }}>
                {TYPE_META[q.type]?.lab || q.type}
              </span>
            </div>
            <button onClick={toggleMark} className="row" style={{ gap: 4, fontSize: 11, fontWeight: 700, color: marked.has(idx) ? 'var(--warning)' : 'var(--n500)' }}>
              <Icon name={marked.has(idx) ? 'star' : 'circle'} size={14}/>
              {marked.has(idx) ? 'Marked' : 'Mark for review'}
            </button>
          </div>
          {q.type !== 'fill' && (
            <div style={{ fontSize: 16, fontWeight: 700, color: 'var(--n900)', lineHeight: 1.45, letterSpacing: '-.005em' }}>{q.q}</div>
          )}
          {q.type === 'multi' && (
            <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 8, fontStyle: 'italic' }}>Select all that apply</div>
          )}
        </div>

        {/* Type-specific input */}
        <QuestionInput q={q} value={answers[idx]} onChange={setAnswer}/>
      </div>

      {/* Bottom action bar */}
      <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: 14, background: '#fff', borderTop: '1px solid var(--n100)' }}>
        <div className="row" style={{ gap: 8 }}>
          <button onClick={() => setIdx(Math.max(0, idx - 1))} disabled={idx === 0}
            className="btn-sm" style={{ flex: 1, height: 46, background: 'var(--n50)', color: idx === 0 ? 'var(--n400)' : 'var(--n900)', fontWeight: 700, borderRadius: 12 }}>
            <Icon name="chev-l" size={16}/> Previous
          </button>
          {idx < Q.length - 1 ? (
            <button onClick={() => setIdx(idx + 1)} className="btn-sm" style={{ flex: 1.4, height: 46, background: 'var(--n900)', color: '#fff', fontWeight: 700, borderRadius: 12 }}>
              Next <Icon name="chev-r" size={16}/>
            </button>
          ) : (
            <button onClick={() => setConfirmSubmit(true)} className="btn-sm" style={{ flex: 1.4, height: 46, background: 'var(--p600)', color: '#fff', fontWeight: 700, borderRadius: 12 }}>
              Submit <Icon name="check" size={16}/>
            </button>
          )}
        </div>
      </div>

      {/* Question palette overlay */}
      {paletteOpen && (
        <div onClick={() => setPaletteOpen(false)} style={{ position: 'absolute', inset: 0, background: 'rgba(15,18,30,.45)', zIndex: 80, display: 'flex', alignItems: 'flex-end' }}>
          <div onClick={e => e.stopPropagation()} style={{ background: '#fff', width: '100%', borderRadius: '20px 20px 0 0', padding: '16px 18px 24px' }}>
            <div style={{ width: 36, height: 4, background: 'var(--n200)', borderRadius: 99, margin: '0 auto 14px' }}></div>
            <div className="spread" style={{ marginBottom: 14 }}>
              <div>
                <div style={{ fontSize: 16, fontWeight: 800, color: 'var(--n900)' }}>Question palette</div>
                <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 2 }}>Tap any number to jump</div>
              </div>
              <button onClick={() => setPaletteOpen(false)} style={{ width: 32, height: 32, borderRadius: 9, background: 'var(--n50)', display: 'grid', placeItems: 'center' }}>
                <Icon name="x" size={16}/>
              </button>
            </div>
            <div className="row" style={{ gap: 14, marginBottom: 14, fontSize: 10.5, color: 'var(--n600)' }}>
              <div className="row" style={{ gap: 4 }}><span style={{ width: 10, height: 10, borderRadius: 99, background: 'var(--p600)' }}></span> Answered</div>
              <div className="row" style={{ gap: 4 }}><span style={{ width: 10, height: 10, borderRadius: 99, background: 'var(--warning)' }}></span> Marked</div>
              <div className="row" style={{ gap: 4 }}><span style={{ width: 10, height: 10, borderRadius: 99, border: '1.5px solid var(--n300)' }}></span> Unanswered</div>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5,1fr)', gap: 8 }}>
              {Q.map((qq, i) => {
                const isAns = isAnswered(qq, answers[i]);
                const isMarked = marked.has(i);
                const isCur = i === idx;
                let bg = '#fff', col = 'var(--n700)', bd = '1.5px solid var(--n200)';
                if (isAns) { bg = 'var(--p600)'; col = '#fff'; bd = '0'; }
                if (isMarked) { bg = 'var(--warning)'; col = '#fff'; bd = '0'; }
                if (isCur) { bd = '2.5px solid var(--n900)'; }
                return (
                  <button key={i} onClick={() => goto(i)} style={{
                    height: 44, borderRadius: 10, background: bg, color: col, border: bd,
                    fontSize: 13, fontWeight: 800, fontVariantNumeric: 'tabular-nums',
                  }}>{i + 1}</button>
                );
              })}
            </div>
            <button onClick={() => { setPaletteOpen(false); setConfirmSubmit(true); }} className="btn" style={{ marginTop: 16, height: 46 }}>
              Submit assessment
            </button>
          </div>
        </div>
      )}

      {/* Submit confirmation overlay */}
      {confirmSubmit && (
        <div style={{ position: 'absolute', inset: 0, background: 'rgba(15,18,30,.55)', zIndex: 90, display: 'grid', placeItems: 'center', padding: 24 }}>
          <div className="card" style={{ padding: 22, textAlign: 'center', maxWidth: 320 }}>
            <div style={{ width: 56, height: 56, borderRadius: 16, background: a.resultsMode === 'instant' ? 'var(--p50)' : 'var(--warning-50)', color: a.resultsMode === 'instant' ? 'var(--p600)' : 'var(--warning)', display: 'grid', placeItems: 'center', margin: '0 auto 14px' }}>
              <Icon name={a.resultsMode === 'instant' ? 'check' : 'clock'} size={26}/>
            </div>
            <div style={{ fontSize: 17, fontWeight: 800, color: 'var(--n900)' }}>Submit assessment?</div>
            <div style={{ fontSize: 12, color: 'var(--n600)', marginTop: 6, lineHeight: 1.5 }}>
              You've answered <b>{answeredCount} of {Q.length}</b> questions.
              {answeredCount < Q.length && <> Unanswered will be marked wrong.</>}
              <br/>
              <span style={{ color: a.resultsMode === 'instant' ? 'var(--success)' : 'var(--warning)', fontWeight: 700 }}>
                {a.resultsMode === 'instant' ? 'Score appears immediately.' : 'Results will be published by your teacher.'}
              </span>
            </div>
            <div className="row" style={{ gap: 8, marginTop: 16 }}>
              <button onClick={() => setConfirmSubmit(false)} className="btn-sm" style={{ flex: 1, height: 44, background: 'var(--n50)', color: 'var(--n900)', fontWeight: 700, borderRadius: 12 }}>Keep going</button>
              <button onClick={submit} className="btn-sm" style={{ flex: 1, height: 44, background: 'var(--p600)', color: '#fff', fontWeight: 700, borderRadius: 12 }}>Submit</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// QUESTION INPUT — type-aware renderer
// ─────────────────────────────────────────────────────────────
function QuestionInput({ q, value, onChange }) {
  switch (q.type) {
    case 'mcq':     return <MCQInput q={q} value={value} onChange={onChange}/>;
    case 'multi':   return <MultiInput q={q} value={value} onChange={onChange}/>;
    case 'tf':      return <TFInput q={q} value={value} onChange={onChange}/>;
    case 'numeric': return <NumericInput q={q} value={value} onChange={onChange}/>;
    case 'short':   return <ShortInput q={q} value={value} onChange={onChange}/>;
    case 'fill':    return <FillInput q={q} value={value} onChange={onChange}/>;
    case 'match':   return <MatchInput q={q} value={value} onChange={onChange}/>;
    default: return <div className="card" style={{ padding: 14 }}>Unsupported type: {q.type}</div>;
  }
}

function MCQInput({ q, value, onChange }) {
  return (
    <div className="col" style={{ gap: 10 }}>
      {q.opts.map((opt, i) => {
        const sel = value === i;
        return (
          <button key={i} onClick={() => onChange(i)} className="row" style={{
            padding: 14, gap: 12, textAlign: 'left',
            background: sel ? 'var(--p50)' : '#fff',
            border: sel ? '2px solid var(--p600)' : '1px solid var(--n100)',
            borderRadius: 12,
          }}>
            <div style={{ width: 26, height: 26, borderRadius: 99, background: sel ? 'var(--p600)' : 'var(--n50)', color: sel ? '#fff' : 'var(--n700)', display: 'grid', placeItems: 'center', fontSize: 12, fontWeight: 800, flexShrink: 0 }}>{String.fromCharCode(65 + i)}</div>
            <div style={{ flex: 1, fontSize: 14, fontWeight: sel ? 700 : 600, color: sel ? 'var(--p700)' : 'var(--n900)' }}>{opt}</div>
            {sel && <Icon name="check" size={16} style={{ color: 'var(--p600)' }}/>}
          </button>
        );
      })}
    </div>
  );
}

function MultiInput({ q, value, onChange }) {
  const v = Array.isArray(value) ? value : [];
  const toggle = (i) => onChange(v.includes(i) ? v.filter(x => x !== i) : [...v, i].sort((x, y) => x - y));
  return (
    <div className="col" style={{ gap: 10 }}>
      {q.opts.map((opt, i) => {
        const sel = v.includes(i);
        return (
          <button key={i} onClick={() => toggle(i)} className="row" style={{
            padding: 14, gap: 12, textAlign: 'left',
            background: sel ? 'var(--p50)' : '#fff',
            border: sel ? '2px solid var(--p600)' : '1px solid var(--n100)',
            borderRadius: 12,
          }}>
            <div style={{ width: 26, height: 26, borderRadius: 7, background: sel ? 'var(--p600)' : '#fff', color: '#fff', border: sel ? '0' : '2px solid var(--n300)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
              {sel && <Icon name="check" size={14}/>}
            </div>
            <div style={{ flex: 1, fontSize: 14, fontWeight: sel ? 700 : 600, color: sel ? 'var(--p700)' : 'var(--n900)' }}>{opt}</div>
          </button>
        );
      })}
    </div>
  );
}

function TFInput({ q, value, onChange }) {
  return (
    <div className="row" style={{ gap: 12 }}>
      {[
        { v: true, lab: 'True', icon: 'check', clr: 'var(--success)', bg: 'var(--success-50)', bd: '#A7F3D0' },
        { v: false, lab: 'False', icon: 'x', clr: 'var(--c600)', bg: 'var(--c50)', bd: '#FCA5A5' },
      ].map(opt => {
        const sel = value === opt.v;
        return (
          <button key={opt.lab} onClick={() => onChange(opt.v)} className="col" style={{
            flex: 1, padding: '22px 10px', alignItems: 'center', gap: 10,
            background: sel ? opt.bg : '#fff',
            border: sel ? `2px solid ${opt.clr}` : '1px solid var(--n100)',
            borderRadius: 14,
          }}>
            <div style={{ width: 56, height: 56, borderRadius: 99, background: sel ? opt.clr : 'var(--n50)', color: sel ? '#fff' : 'var(--n400)', display: 'grid', placeItems: 'center' }}>
              <Icon name={opt.icon} size={28}/>
            </div>
            <div style={{ fontSize: 16, fontWeight: 800, color: sel ? opt.clr : 'var(--n900)', letterSpacing: '-.01em' }}>{opt.lab}</div>
          </button>
        );
      })}
    </div>
  );
}

function NumericInput({ q, value, onChange }) {
  return (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 10 }}>YOUR ANSWER</div>
      <div className="row" style={{ gap: 10, alignItems: 'baseline' }}>
        <input
          type="number"
          inputMode="decimal"
          value={value || ''}
          onChange={e => onChange(e.target.value)}
          placeholder="Enter a number"
          style={{
            flex: 1, height: 60, padding: '0 16px', borderRadius: 12,
            border: '2px solid var(--n200)', background: 'var(--n50)',
            fontSize: 28, fontWeight: 800, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em',
            color: 'var(--n900)', fontFamily: 'var(--mono)', textAlign: 'center', outline: 'none',
          }}
          onFocus={e => e.target.style.borderColor = 'var(--p600)'}
          onBlur={e => e.target.style.borderColor = 'var(--n200)'}
        />
        {q.unit && <div style={{ fontSize: 14, color: 'var(--n600)', fontWeight: 700 }}>{q.unit}</div>}
      </div>
      {q.tolerance > 0 && (
        <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 8, fontStyle: 'italic' }}>
          Accepts answers within ±{q.tolerance} of the expected value.
        </div>
      )}
    </div>
  );
}

function ShortInput({ q, value, onChange }) {
  return (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 10 }}>YOUR ANSWER</div>
      <textarea
        value={value || ''}
        onChange={e => onChange(e.target.value)}
        placeholder={q.teacherGraded ? 'Write your response — teacher will grade…' : 'Type your answer…'}
        rows={q.teacherGraded ? 4 : 2}
        style={{
          width: '100%', padding: 14, borderRadius: 12,
          border: '2px solid var(--n200)', background: 'var(--n50)',
          fontSize: 15, fontWeight: 600, color: 'var(--n900)',
          fontFamily: 'inherit', resize: 'none', outline: 'none', boxSizing: 'border-box',
        }}
        onFocus={e => e.target.style.borderColor = 'var(--p600)'}
        onBlur={e => e.target.style.borderColor = 'var(--n200)'}
      />
      {q.teacherGraded && (
        <div className="row" style={{ gap: 6, marginTop: 8, color: 'var(--warning)' }}>
          <Icon name="info" size={12}/>
          <div style={{ fontSize: 10.5, fontWeight: 600 }}>Open-ended — graded by your teacher</div>
        </div>
      )}
    </div>
  );
}

function FillInput({ q, value, onChange }) {
  const v = Array.isArray(value) ? value : Array(q.blanks).fill('');
  const setBlank = (i, txt) => onChange(v.map((s, ix) => ix === i ? txt : s));
  // Split q.q on '___' → text segments interleaved with blanks
  const segments = q.q.split('___');
  let blankIdx = 0;
  return (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 12 }}>FILL IN THE BLANKS</div>
      <div style={{ fontSize: 16, lineHeight: 2.2, color: 'var(--n900)', fontWeight: 600, letterSpacing: '-.005em' }}>
        {segments.map((seg, i) => (
          <React.Fragment key={i}>
            <span>{seg}</span>
            {i < segments.length - 1 && (() => {
              const bi = blankIdx++;
              const filled = v[bi] && v[bi].trim().length > 0;
              return (
                <input
                  type="text"
                  value={v[bi] || ''}
                  onChange={e => setBlank(bi, e.target.value)}
                  placeholder={`Blank ${bi + 1}`}
                  style={{
                    display: 'inline-block', minWidth: 110, maxWidth: 200, padding: '4px 10px', margin: '0 4px',
                    borderRadius: 8, border: 0, borderBottom: `2px solid ${filled ? 'var(--p600)' : 'var(--n300)'}`,
                    background: filled ? 'var(--p50)' : 'var(--n50)',
                    fontSize: 15, fontWeight: 700, color: filled ? 'var(--p700)' : 'var(--n900)',
                    fontFamily: 'inherit', textAlign: 'center', outline: 'none',
                  }}
                />
              );
            })()}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

function MatchInput({ q, value, onChange }) {
  // value is an array of right-side indices, indexed by left-side position.
  // Tap a left row to cycle through the available right options.
  const v = Array.isArray(value) && value.length === q.pairs.length ? value : q.pairs.map(() => null);
  const cycleAt = (leftIdx) => {
    const cur = v[leftIdx];
    const next = cur === null ? 0 : cur === q.pairs.length - 1 ? null : cur + 1;
    onChange(v.map((x, i) => i === leftIdx ? next : x));
  };
  return (
    <div className="card" style={{ padding: 14 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 10 }}>TAP THE RIGHT-SIDE PILL TO CYCLE PAIRS</div>
      <div className="col" style={{ gap: 8 }}>
        {q.pairs.map((p, i) => {
          const picked = v[i];
          const right = picked === null ? null : q.pairs[picked].right;
          return (
            <div key={i} className="row" style={{ gap: 10, padding: 10, background: 'var(--n50)', borderRadius: 11 }}>
              <div style={{ width: 28, height: 28, borderRadius: 8, background: '#fff', color: 'var(--n700)', display: 'grid', placeItems: 'center', fontSize: 12, fontWeight: 800, fontFamily: 'var(--mono)', flexShrink: 0 }}>{i + 1}</div>
              <div style={{ flex: 1, fontSize: 13.5, fontWeight: 700, color: 'var(--n900)' }}>{p.left}</div>
              <Icon name="chev-r" size={14} style={{ color: 'var(--n400)' }}/>
              <button onClick={() => cycleAt(i)} className="row" style={{
                gap: 6, padding: '8px 12px', borderRadius: 9,
                background: picked === null ? '#fff' : 'var(--p600)',
                color: picked === null ? 'var(--n500)' : '#fff',
                border: picked === null ? '1.5px dashed var(--n300)' : '0',
                fontSize: 12, fontWeight: 700, minWidth: 130, justifyContent: 'space-between',
              }}>
                <span style={{ flex: 1, textAlign: 'left' }}>{right || 'Pick a match'}</span>
                <Icon name="chev-d" size={12}/>
              </button>
            </div>
          );
        })}
      </div>
      <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 10, fontStyle: 'italic', lineHeight: 1.5 }}>
        All rights: {q.pairs.map(p => p.right).join(' · ')}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// SUBMITTED — confirmation for delayed-mode submissions
// ─────────────────────────────────────────────────────────────
function AssessmentSubmittedScreen({ nav, params }) {
  const a = ASSESSMENTS.find(x => x.id === (params && params.id)) || ASSESSMENTS[0];
  const answeredCount = (params && params.answeredCount) ?? 0;
  const total = (params && params.total) ?? a.qCount;
  const [notify, setNotify] = useStateA(true);
  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingTop: 60, gap: 16 }}>
        {/* Confirmation hero */}
        <div className="card" style={{ padding: 24, textAlign: 'center', background: 'linear-gradient(180deg, var(--warning-50) 0%, #fff 80%)' }}>
          <div style={{ width: 76, height: 76, borderRadius: 22, background: 'var(--warning)', color: '#fff', display: 'grid', placeItems: 'center', margin: '0 auto 16px' }}>
            <Icon name="check" size={36}/>
          </div>
          <div style={{ fontSize: 22, fontWeight: 800, color: 'var(--n900)', letterSpacing: '-.02em' }}>Submitted</div>
          <div style={{ fontSize: 13, color: 'var(--n600)', marginTop: 6, lineHeight: 1.5 }}>
            Your responses have been sent to <b style={{ color: 'var(--n900)' }}>{a.by}</b>.<br/>
            Results will be published after grading.
          </div>
        </div>

        {/* Snapshot */}
        <div className="card" style={{ padding: 14 }}>
          <div className="row" style={{ gap: 10, marginBottom: 12 }}>
            <div style={{ width: 36, height: 36, borderRadius: 10, background: a.bg, color: a.clr, display: 'grid', placeItems: 'center' }}><Icon name={a.icon} size={18}/></div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>{a.sub.toUpperCase()} · {a.cls}</div>
              <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--n900)', marginTop: 1 }}>{a.title}</div>
            </div>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gap: 10 }}>
            {[
              { l: 'Submitted', v: 'Just now', clr: 'var(--n900)' },
              { l: 'Answered', v: `${answeredCount}/${total}`, clr: 'var(--p600)' },
              { l: 'Mode', v: 'Teacher publishes', clr: 'var(--warning)' },
              { l: 'Expected', v: a.willPublishOn || 'Within 3 days', clr: 'var(--n900)' },
            ].map((s, i) => (
              <div key={i} className="card-flat" style={{ padding: 10 }}>
                <div style={{ fontSize: 9, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>{s.l.toUpperCase()}</div>
                <div style={{ fontSize: 13, fontWeight: 800, color: s.clr, marginTop: 4, fontVariantNumeric: 'tabular-nums' }}>{s.v}</div>
              </div>
            ))}
          </div>
        </div>

        {/* Notify toggle */}
        <button onClick={() => setNotify(n => !n)} className="row" style={{ width: '100%', padding: 14, gap: 12, background: '#fff', border: '1px solid var(--n100)', borderRadius: 12 }}>
          <div style={{ width: 38, height: 38, borderRadius: 10, background: notify ? 'var(--p50)' : 'var(--n50)', color: notify ? 'var(--p600)' : 'var(--n400)', display: 'grid', placeItems: 'center' }}>
            <Icon name="bell" size={18}/>
          </div>
          <div style={{ flex: 1, textAlign: 'left' }}>
            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>Notify me when results are out</div>
            <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 1 }}>{notify ? 'On' : 'Off'} — push + email</div>
          </div>
          <div style={{
            width: 38, height: 22, borderRadius: 99, background: notify ? 'var(--p600)' : 'var(--n200)',
            position: 'relative', transition: 'background .18s',
          }}>
            <div style={{
              position: 'absolute', top: 2, left: notify ? 18 : 2,
              width: 18, height: 18, borderRadius: 99, background: '#fff', boxShadow: '0 1px 2px rgba(0,0,0,.2)',
              transition: 'left .18s',
            }}/>
          </div>
        </button>

        {/* What's next */}
        <div className="card-tinted" style={{ padding: 14, display: 'flex', gap: 10 }}>
          <Icon name="info" size={16} style={{ color: 'var(--p700)', marginTop: 1, flexShrink: 0 }}/>
          <div style={{ fontSize: 12, color: 'var(--n700)', lineHeight: 1.5 }}>
            You'll see this assessment under <b>History → Awaiting results</b>. Once your teacher publishes, your score and review will appear automatically.
          </div>
        </div>

        {/* Actions */}
        <div className="row" style={{ gap: 10, marginTop: 'auto' }}>
          <button onClick={() => nav.replace('home')} className="btn btn-outline" style={{ flex: 1, height: 48 }}>Home</button>
          <button onClick={() => nav.replace('assessments', { tab: 'history' })} className="btn" style={{ flex: 1.2, height: 48 }}>View history</button>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// RESULT — score + per-question review (or awaiting state)
// ─────────────────────────────────────────────────────────────
function AssessmentResultScreen({ nav, params }) {
  const a = ASSESSMENTS.find(x => x.id === (params && params.id)) || ASSESSMENTS.find(x => x.state === 'completed') || ASSESSMENTS[0];
  const userAnswers = (params && params.answers) || null;
  const Q = banksFor(a);
  const live = !!userAnswers;

  // Awaiting state — submitted but teacher hasn't published yet
  if (a.state === 'awaiting' && !live) {
    return <AwaitingResultScreen nav={nav} a={a}/>;
  }

  const computed = useMemoA(() => {
    if (!userAnswers) return null;
    const correct = userAnswers.reduce((n, ans, i) => n + (isCorrectAnswer(Q[i], ans) ? 1 : 0), 0);
    const skipped = userAnswers.reduce((n, ans, i) => n + (!isAnswered(Q[i], ans) ? 1 : 0), 0);
    const incorrect = Q.length - correct - skipped;
    const marksPer = a.marks / a.qCount;
    const score = +(correct * marksPer).toFixed(1);
    return { correct, incorrect, skipped, score, scoreMax: a.marks, scorePct: Math.round(correct / Q.length * 100) };
  }, [userAnswers]);

  const scoreData = live ? computed : {
    correct: Math.round(a.score / (a.scoreMax / a.qCount)),
    incorrect: a.qCount - Math.round(a.score / (a.scoreMax / a.qCount)),
    skipped: 0,
    score: a.score, scoreMax: a.scoreMax, scorePct: a.scorePct,
  };

  const grade = scoreData.scorePct >= 90 ? 'A1' : scoreData.scorePct >= 80 ? 'A' : scoreData.scorePct >= 70 ? 'B1' : scoreData.scorePct >= 60 ? 'B' : 'C';
  const isPass = scoreData.scorePct >= 60;
  const marksPer = +(a.marks / a.qCount).toFixed(2);

  // Bucket questions by type for "by question type" breakdown.
  // Each bucket carries class-average %, so each bar can compare your-vs-class.
  const typeBreakdown = useMemoA(() => {
    const buckets = {};
    Q.forEach((q, i) => {
      const ans = live ? userAnswers[i] : (i < scoreData.correct ? q.correct : null);
      const ok = live ? isCorrectAnswer(q, ans) : i < scoreData.correct;
      if (!buckets[q.type]) buckets[q.type] = { n: 0, correct: 0, type: q.type };
      buckets[q.type].n += 1;
      if (ok) buckets[q.type].correct += 1;
    });
    return Object.entries(buckets).map(([t, v]) => ({
      topic: TYPE_META[t]?.lab || t,
      type: t,
      ...v,
      pct: Math.round(v.correct / v.n * 100),
      classAvgPct: CLASS_TYPE_AVG_PCT[t] ?? 65,
    }));
  }, [Q, userAnswers, scoreData.correct, live]);

  // Weak topics: types where the student < 60%. Drives the practice CTA.
  const weakTopics = useMemoA(
    () => typeBreakdown.filter(t => t.pct < 60).map(t => t.type),
    [typeBreakdown]
  );

  const [showReview, setShowReview] = useStateA(false);

  return (
    <div className="app screen-in">
      <div style={{ position: 'absolute', top: 0, left: 0, right: 0, zIndex: 60 }}><StatusBar dark/></div>
      <div className="app-body no-pad" style={{ paddingBottom: 24 }}>
        {/* Hero */}
        <div className="head-grad" style={{ paddingTop: 56, paddingBottom: 26 }}>
          <button onClick={() => nav.replace('assessments', { tab: 'history' })} style={{ width: 38, height: 38, borderRadius: 12, background: 'rgba(255,255,255,.18)', display: 'grid', placeItems: 'center', color: '#fff', marginBottom: 16 }}><Icon name="chev-l" size={18}/></button>
          <div style={{ fontSize: 11, opacity: .85, fontFamily: 'var(--mono)', letterSpacing: '.08em', fontWeight: 700 }}>{a.sub.toUpperCase()} · {a.cls}</div>
          <div style={{ fontSize: 22, fontWeight: 800, marginTop: 4, letterSpacing: '-.02em' }}>{a.title}</div>

          <div style={{ marginTop: 18, display: 'flex', alignItems: 'baseline', gap: 14 }}>
            <div style={{ fontSize: 56, fontWeight: 800, fontVariantNumeric: 'tabular-nums', lineHeight: 1, letterSpacing: '-.04em' }}>{scoreData.score}</div>
            <div style={{ fontSize: 22, opacity: .8, fontWeight: 700 }}>/ {scoreData.scoreMax}</div>
            <div style={{ marginLeft: 'auto', textAlign: 'right' }}>
              <div style={{ fontSize: 30, fontWeight: 800, lineHeight: 1 }}>{grade}</div>
              <div style={{ fontSize: 11, opacity: .85, marginTop: 4 }}>{scoreData.scorePct}% · {isPass ? 'Passed' : 'Try again'}</div>
            </div>
          </div>
        </div>

        {/* Stats */}
        <div style={{ padding: '18px 20px 0' }}>
          <div className="card-flat" style={{ padding: 14, display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 8 }}>
            {[
              { v: scoreData.correct, l: 'Correct', clr: 'var(--success)' },
              { v: scoreData.incorrect, l: 'Wrong', clr: 'var(--c600)' },
              { v: scoreData.skipped, l: 'Skipped', clr: 'var(--n500)' },
              { v: live ? '—' : (a.timeTaken || '—'), l: 'Time', clr: 'var(--n900)' },
            ].map((s, i) => (
              <div key={i} style={{ textAlign: 'center', borderRight: i < 3 ? '1px solid var(--n200)' : 'none' }}>
                <div style={{ fontSize: 18, fontWeight: 800, color: s.clr, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>{s.v}</div>
                <div style={{ fontSize: 10, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>{s.l}</div>
              </div>
            ))}
          </div>
        </div>

        {/* Class rank card → per-assessment leaderboard */}
        {!live && a.classRank && (
          <div style={{ padding: '14px 20px 0' }}>
            <button onClick={() => nav.push('assessmentLeaderboard', { id: a.id })} className="card row" style={{ padding: 14, gap: 12, width: '100%', textAlign: 'left' }}>
              <div style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--p50)', color: 'var(--p600)', display: 'grid', placeItems: 'center' }}><Icon name="trophy" size={18}/></div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.06em', fontFamily: 'var(--mono)' }}>CLASS RANK · THIS TEST</div>
                <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)', marginTop: 1 }}>{a.classRank}</div>
              </div>
              <div className="row" style={{ gap: 6, color: 'var(--p600)' }}>
                <span style={{ fontSize: 11, fontWeight: 700 }}>See ranks</span>
                <Icon name="chev-r" size={14}/>
              </div>
            </button>
          </div>
        )}

        {/* By question type — with class-average comparison */}
        <div style={{ padding: '20px 20px 0' }}>
          <div className="spread" style={{ marginBottom: 10 }}>
            <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)' }}>By question type</div>
            <div className="row" style={{ gap: 10, fontSize: 10 }}>
              <div className="row" style={{ gap: 4, color: 'var(--n600)' }}>
                <span style={{ width: 10, height: 4, background: 'var(--p600)', borderRadius: 2 }}></span> You
              </div>
              <div className="row" style={{ gap: 4, color: 'var(--n600)' }}>
                <span style={{ width: 10, height: 10, borderLeft: '2px dashed var(--n500)', display: 'inline-block' }}></span> Class avg
              </div>
            </div>
          </div>
          <div className="card" style={{ padding: 14 }}>
            {typeBreakdown.map((t, i, arr) => {
              const pct = t.pct;
              const cls = t.classAvgPct;
              const beats = pct >= cls;
              const clr = pct >= 80 ? 'var(--success)' : pct >= 50 ? 'var(--warning)' : 'var(--c600)';
              const delta = pct - cls;
              return (
                <div key={i} style={{ paddingTop: i === 0 ? 0 : 12, paddingBottom: i === arr.length - 1 ? 0 : 12, borderBottom: i < arr.length - 1 ? '1px solid var(--n100)' : 'none' }}>
                  <div className="spread" style={{ marginBottom: 6 }}>
                    <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--n900)' }}>{t.topic}</div>
                    <div className="row" style={{ gap: 8 }}>
                      <div style={{ fontSize: 11, fontWeight: 700, color: beats ? 'var(--success)' : 'var(--c600)', fontFamily: 'var(--mono)', fontVariantNumeric: 'tabular-nums' }}>
                        {beats ? '+' : ''}{delta} pts
                      </div>
                      <div style={{ fontSize: 12, fontWeight: 800, color: clr, fontVariantNumeric: 'tabular-nums' }}>{t.correct}/{t.n}</div>
                    </div>
                  </div>
                  {/* Bar with class-average tick + label */}
                  <div style={{ position: 'relative', height: 16 }}>
                    <div style={{ position: 'absolute', top: 6, left: 0, right: 0, height: 4, background: 'var(--n100)', borderRadius: 99 }}></div>
                    <div style={{ position: 'absolute', top: 6, left: 0, width: `${pct}%`, height: 4, background: clr, borderRadius: 99 }}></div>
                    {/* Class-average tick */}
                    <div title={`Class avg ${cls}%`} style={{
                      position: 'absolute', top: 0, left: `calc(${cls}% - 1px)`, width: 2, height: 16,
                      borderLeft: '2px dashed var(--n500)',
                    }}/>
                    <div style={{
                      position: 'absolute', top: -2, left: `calc(${cls}% - 14px)`,
                      fontSize: 8.5, fontWeight: 800, color: 'var(--n500)', fontFamily: 'var(--mono)',
                      letterSpacing: '.04em', whiteSpace: 'nowrap',
                    }}>
                      {cls}%
                    </div>
                  </div>
                  <div className="row" style={{ marginTop: 4, gap: 8 }}>
                    <div style={{ fontSize: 10, color: 'var(--n500)', fontWeight: 700, fontFamily: 'var(--mono)' }}>YOU {pct}%</div>
                    <div style={{ fontSize: 10, color: beats ? 'var(--success)' : 'var(--c600)', fontWeight: 700 }}>
                      {beats ? '↑ above class' : '↓ below class'}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* Weakness → practice CTA (#3) — only if at least one weak topic */}
        {weakTopics.length > 0 && (
          <div style={{ padding: '14px 20px 0' }}>
            <button
              onClick={() => nav.push('practiceIntro', { aid: a.id, types: weakTopics })}
              className="card row" style={{ width: '100%', padding: 14, gap: 12, textAlign: 'left',
                border: '1px solid var(--warning)', background: 'linear-gradient(180deg, var(--warning-50) 0%, #fff 70%)' }}>
              <div style={{ width: 44, height: 44, borderRadius: 12, background: 'var(--warning)', color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                <Icon name="zap" size={22}/>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--warning)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>BOOST WEAK TOPICS</div>
                <div style={{ fontSize: 13.5, fontWeight: 800, color: 'var(--n900)', marginTop: 2 }}>
                  {weakTopics.length === 1
                    ? `Practice ${weakTopics.length} topic you missed`
                    : `Practice ${weakTopics.length} topics you missed`}
                </div>
                <div style={{ fontSize: 11, color: 'var(--n600)', marginTop: 3, lineHeight: 1.5 }}>
                  {weakTopics.map(t => TYPE_META[t]?.lab || t).join(' · ')} · 3 quick questions, no marks
                </div>
              </div>
              <Icon name="chev-r" size={16} style={{ color: 'var(--n400)' }}/>
            </button>
          </div>
        )}

        {/* Review toggle */}
        <div style={{ padding: '20px 20px 0' }}>
          <button onClick={() => setShowReview(s => !s)} className="row" style={{ width: '100%', padding: 14, gap: 10, background: '#fff', border: '1px solid var(--n100)', borderRadius: 12, boxShadow: 'var(--el-1)' }}>
            <div style={{ width: 36, height: 36, borderRadius: 10, background: 'var(--p50)', color: 'var(--p600)', display: 'grid', placeItems: 'center' }}><Icon name="eye" size={16}/></div>
            <div style={{ flex: 1, textAlign: 'left' }}>
              <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>Review answers</div>
              <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 1 }}>See correct answers & explanations</div>
            </div>
            <Icon name={showReview ? 'chev-d' : 'chev-r'} size={16} style={{ color: 'var(--n400)' }}/>
          </button>
        </div>

        {showReview && (
          <div style={{ padding: '14px 20px 0' }} className="col">
            {Q.map((q, i) => {
              const userAns = live ? userAnswers[i] : (i < scoreData.correct ? q.correct : null);
              const answered = isAnswered(q, userAns);
              const isCorrect = answered && isCorrectAnswer(q, userAns);
              const wasSkipped = !answered;
              return (
                <div key={i} className="card" style={{ padding: 14 }}>
                  <div className="spread" style={{ marginBottom: 10 }}>
                    <div className="row" style={{ gap: 8 }}>
                      <div style={{ width: 24, height: 24, borderRadius: 7, background: isCorrect ? 'var(--success-50)' : wasSkipped ? 'var(--n50)' : 'var(--c50)', color: isCorrect ? 'var(--success)' : wasSkipped ? 'var(--n500)' : 'var(--c600)', display: 'grid', placeItems: 'center' }}>
                        <Icon name={isCorrect ? 'check' : wasSkipped ? 'circle' : 'x'} size={13}/>
                      </div>
                      <div style={{ fontSize: 9.5, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>Q{i + 1} · {TYPE_META[q.type]?.lab || q.type}</div>
                    </div>
                    <span className="pill" style={{
                      background: isCorrect ? 'var(--success-50)' : wasSkipped ? 'var(--n50)' : 'var(--c50)',
                      color: isCorrect ? 'var(--success)' : wasSkipped ? 'var(--n600)' : 'var(--c600)',
                    }}>{isCorrect ? `+${marksPer} mark` : wasSkipped ? 'Skipped' : '0 marks'}</span>
                  </div>
                  {q.type !== 'fill' && (
                    <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginBottom: 10, lineHeight: 1.45 }}>{q.q}</div>
                  )}
                  <ReviewAnswer q={q} userAns={userAns} isCorrect={isCorrect} wasSkipped={wasSkipped}/>
                  <div style={{ marginTop: 10, padding: 10, background: 'var(--n50)', borderRadius: 9, display: 'flex', gap: 8 }}>
                    <Icon name="info" size={14} style={{ color: 'var(--n600)', flexShrink: 0, marginTop: 1 }}/>
                    <div style={{ fontSize: 11.5, color: 'var(--n700)', lineHeight: 1.5 }}>{q.expl}</div>
                  </div>
                  {/* Teacher comment block (#6) — for delayed-mode subjective answers */}
                  {a.teacherComments && a.teacherComments[i] && (
                    <div style={{ marginTop: 8, padding: 12, background: 'var(--p50)', borderRadius: 10, border: '1px solid var(--p100)', display: 'flex', gap: 10 }}>
                      <div style={{ width: 32, height: 32, borderRadius: 99, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0, fontSize: 11, fontWeight: 800 }}>
                        {(a.by || 'T').split(' ').map(s => s[0]).join('').slice(0, 2)}
                      </div>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div className="row" style={{ gap: 6, marginBottom: 4 }}>
                          <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--p700)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>TEACHER COMMENT</div>
                          <div style={{ fontSize: 10, color: 'var(--n500)' }}>· {a.by}</div>
                        </div>
                        <div style={{ fontSize: 12, color: 'var(--n800)', lineHeight: 1.5 }}>{a.teacherComments[i].text}</div>
                      </div>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        )}

        {/* Footer actions — retake / practice / leaderboard / done (#8) */}
        <div style={{ padding: '20px 20px 0' }}>
          {(() => {
            const m = /(\d+)\s*of\s*(\d+)/i.exec(a.attempts || '');
            const used = m ? +m[1] : 1;
            const max = m ? +m[2] : 1;
            const canRetake = a.resultsMode === 'instant' && (a.attempts === 'unlimited' || used < max);
            return (
              <div className="col" style={{ gap: 10 }}>
                {canRetake && (
                  <button
                    onClick={() => nav.replace('assessmentAttempt', { id: a.id, retake: true })}
                    className="row" style={{
                      width: '100%', padding: 14, gap: 12, textAlign: 'left',
                      background: 'var(--p50)', border: '1px solid var(--p100)', borderRadius: 12,
                    }}>
                    <div style={{ width: 38, height: 38, borderRadius: 11, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                      <Icon name="zap" size={18}/>
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--p700)' }}>Retake assessment</div>
                      <div style={{ fontSize: 10.5, color: 'var(--p700)', opacity: .8, marginTop: 1 }}>
                        {a.attempts === 'unlimited' ? 'Unlimited attempts · timer + marks' : `Attempt ${used + 1} of ${max} · timer + marks`}
                      </div>
                    </div>
                    <Icon name="chev-r" size={14} style={{ color: 'var(--p600)' }}/>
                  </button>
                )}
                <button
                  onClick={() => nav.push('practiceIntro', { aid: a.id, types: weakTopics.length ? weakTopics : typeBreakdown.map(t => t.type) })}
                  className="row" style={{
                    width: '100%', padding: 14, gap: 12, textAlign: 'left',
                    background: '#fff', border: '1px solid var(--n100)', borderRadius: 12,
                  }}>
                  <div style={{ width: 38, height: 38, borderRadius: 11, background: 'var(--n50)', color: 'var(--n700)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                    <Icon name="edit" size={18}/>
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--n900)' }}>Practice mode</div>
                    <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 1 }}>No timer · no marks · explanations after each question</div>
                  </div>
                  <Icon name="chev-r" size={14} style={{ color: 'var(--n400)' }}/>
                </button>
                <div className="row" style={{ gap: 10 }}>
                  <button onClick={() => nav.push('assessmentLeaderboard', { id: a.id })} className="btn btn-outline" style={{ flex: 1, height: 46 }}><Icon name="trophy" size={16}/> Leaderboard</button>
                  <button onClick={() => nav.replace('assessments', { tab: 'history' })} className="btn" style={{ flex: 1, height: 46 }}>Done</button>
                </div>
              </div>
            );
          })()}
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// REVIEW ANSWER — type-aware comparison ("you said vs correct")
// ─────────────────────────────────────────────────────────────
function ReviewAnswer({ q, userAns, isCorrect, wasSkipped }) {
  if (q.type === 'mcq') {
    return (
      <div className="col" style={{ gap: 6 }}>
        {q.opts.map((opt, oi) => {
          const isUser = oi === userAns;
          const isAns = oi === q.correct;
          let bg = 'var(--n50)', bd = '1px solid var(--n100)', col = 'var(--n700)', icon = null;
          if (isAns) { bg = 'var(--success-50)'; bd = '1px solid #A7F3D0'; col = 'var(--success)'; icon = 'check'; }
          if (isUser && !isAns) { bg = 'var(--c50)'; bd = '1px solid #FCA5A5'; col = 'var(--c600)'; icon = 'x'; }
          return (
            <div key={oi} className="row" style={{ padding: '9px 12px', gap: 10, background: bg, border: bd, borderRadius: 9 }}>
              <div style={{ width: 20, height: 20, borderRadius: 99, background: '#fff', color: 'var(--n700)', display: 'grid', placeItems: 'center', fontSize: 10, fontWeight: 800, flexShrink: 0 }}>{String.fromCharCode(65 + oi)}</div>
              <div style={{ flex: 1, fontSize: 12.5, fontWeight: isAns || isUser ? 700 : 500, color: col }}>{opt}</div>
              {icon && <Icon name={icon} size={14} style={{ color: col }}/>}
              {isUser && <span style={{ fontSize: 9.5, fontWeight: 800, color: col, fontFamily: 'var(--mono)', letterSpacing: '.06em' }}>YOUR PICK</span>}
            </div>
          );
        })}
      </div>
    );
  }

  if (q.type === 'multi') {
    const userSet = new Set(Array.isArray(userAns) ? userAns : []);
    const correctSet = new Set(q.correct);
    return (
      <div className="col" style={{ gap: 6 }}>
        {q.opts.map((opt, oi) => {
          const isUser = userSet.has(oi);
          const isAns = correctSet.has(oi);
          let bg = 'var(--n50)', bd = '1px solid var(--n100)', col = 'var(--n700)', icon = null;
          if (isAns && isUser) { bg = 'var(--success-50)'; bd = '1px solid #A7F3D0'; col = 'var(--success)'; icon = 'check'; }
          else if (isAns)      { bg = 'var(--success-50)'; bd = '1px dashed var(--success)'; col = 'var(--success)'; icon = 'check'; }
          else if (isUser)     { bg = 'var(--c50)';        bd = '1px solid #FCA5A5'; col = 'var(--c600)'; icon = 'x'; }
          return (
            <div key={oi} className="row" style={{ padding: '9px 12px', gap: 10, background: bg, border: bd, borderRadius: 9 }}>
              <div style={{ width: 20, height: 20, borderRadius: 5, background: isAns ? 'var(--success)' : '#fff', color: '#fff', border: isAns ? '0' : '1.5px solid var(--n300)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                {isAns && <Icon name="check" size={11}/>}
              </div>
              <div style={{ flex: 1, fontSize: 12.5, fontWeight: isAns || isUser ? 700 : 500, color: col }}>{opt}</div>
              {icon && <Icon name={icon} size={14} style={{ color: col }}/>}
            </div>
          );
        })}
      </div>
    );
  }

  if (q.type === 'tf') {
    return (
      <div className="row" style={{ gap: 8 }}>
        {[true, false].map(v => {
          const isUser = userAns === v;
          const isAns = q.correct === v;
          const lab = v ? 'True' : 'False';
          let bg = 'var(--n50)', bd = '1px solid var(--n100)', col = 'var(--n700)';
          if (isAns) { bg = 'var(--success-50)'; bd = '1px solid #A7F3D0'; col = 'var(--success)'; }
          if (isUser && !isAns) { bg = 'var(--c50)'; bd = '1px solid #FCA5A5'; col = 'var(--c600)'; }
          return (
            <div key={lab} className="row" style={{ flex: 1, padding: '10px 12px', gap: 8, background: bg, border: bd, borderRadius: 9, justifyContent: 'center' }}>
              <Icon name={v ? 'check' : 'x'} size={14} style={{ color: col }}/>
              <span style={{ fontSize: 12.5, fontWeight: 700, color: col }}>{lab}</span>
              {isUser && <span style={{ fontSize: 9.5, fontWeight: 800, color: col, fontFamily: 'var(--mono)' }}>YOU</span>}
            </div>
          );
        })}
      </div>
    );
  }

  if (q.type === 'numeric' || q.type === 'short') {
    const accepted = q.type === 'numeric' ? `${q.correct}${q.unit ? ' ' + q.unit : ''}${q.tolerance > 0 ? ` (±${q.tolerance})` : ''}` : (q.correct.length ? q.correct.join(' / ') : '— teacher graded —');
    return (
      <div className="col" style={{ gap: 6 }}>
        <div style={{ padding: '10px 12px', borderRadius: 9, background: wasSkipped ? 'var(--n50)' : (isCorrect ? 'var(--success-50)' : 'var(--c50)'), border: `1px solid ${wasSkipped ? 'var(--n100)' : (isCorrect ? '#A7F3D0' : '#FCA5A5')}` }}>
          <div style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.08em', fontFamily: 'var(--mono)', color: wasSkipped ? 'var(--n500)' : (isCorrect ? 'var(--success)' : 'var(--c600)') }}>YOUR ANSWER</div>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginTop: 3, fontFamily: q.type === 'numeric' ? 'var(--mono)' : 'inherit' }}>
            {wasSkipped ? '— skipped —' : (userAns || '—')}
          </div>
        </div>
        {!q.teacherGraded && (
          <div style={{ padding: '10px 12px', borderRadius: 9, background: 'var(--success-50)', border: '1px solid #A7F3D0' }}>
            <div style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.08em', fontFamily: 'var(--mono)', color: 'var(--success)' }}>ACCEPTED</div>
            <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginTop: 3, fontFamily: q.type === 'numeric' ? 'var(--mono)' : 'inherit' }}>{accepted}</div>
          </div>
        )}
      </div>
    );
  }

  if (q.type === 'fill') {
    const v = Array.isArray(userAns) ? userAns : Array(q.blanks).fill('');
    const segments = q.q.split('___');
    let bi = -1;
    return (
      <div style={{ padding: '12px 14px', borderRadius: 10, background: 'var(--n50)', border: '1px solid var(--n100)', fontSize: 14, lineHeight: 2.1, fontWeight: 600, color: 'var(--n900)' }}>
        {segments.map((seg, si) => (
          <React.Fragment key={si}>
            <span>{seg}</span>
            {si < segments.length - 1 && (() => {
              bi += 1;
              const accepted = q.correct[bi];
              const acceptedText = Array.isArray(accepted) ? accepted[0] : accepted;
              const userPick = v[bi];
              const isThisOk = userPick && (Array.isArray(accepted)
                ? accepted.some(c => String(c).toLowerCase() === String(userPick).trim().toLowerCase())
                : String(accepted).toLowerCase() === String(userPick).trim().toLowerCase());
              return (
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, margin: '0 4px' }}>
                  <span style={{
                    padding: '2px 8px', borderRadius: 6, fontWeight: 800,
                    background: isThisOk ? 'var(--success-50)' : userPick ? 'var(--c50)' : 'var(--n100)',
                    color: isThisOk ? 'var(--success)' : userPick ? 'var(--c600)' : 'var(--n500)',
                    textDecoration: !isThisOk && userPick ? 'line-through' : 'none',
                  }}>{userPick || '—'}</span>
                  {!isThisOk && (
                    <span style={{ padding: '2px 8px', borderRadius: 6, fontWeight: 800, background: 'var(--success-50)', color: 'var(--success)' }}>{acceptedText}</span>
                  )}
                </span>
              );
            })()}
          </React.Fragment>
        ))}
      </div>
    );
  }

  if (q.type === 'match') {
    const v = Array.isArray(userAns) ? userAns : q.pairs.map(() => null);
    return (
      <div className="col" style={{ gap: 6 }}>
        {q.pairs.map((p, i) => {
          const picked = v[i];
          const ok = picked === i;
          const userRight = picked === null ? '— skipped —' : q.pairs[picked].right;
          return (
            <div key={i} className="row" style={{ padding: '9px 12px', gap: 10, borderRadius: 9, background: ok ? 'var(--success-50)' : (picked === null ? 'var(--n50)' : 'var(--c50)'), border: `1px solid ${ok ? '#A7F3D0' : (picked === null ? 'var(--n100)' : '#FCA5A5')}` }}>
              <div style={{ flex: 1, fontSize: 12.5, fontWeight: 700, color: 'var(--n900)' }}>{p.left}</div>
              <Icon name={ok ? 'check' : 'x'} size={13} style={{ color: ok ? 'var(--success)' : 'var(--c600)' }}/>
              <div style={{ fontSize: 12, fontWeight: 700, color: ok ? 'var(--success)' : 'var(--c600)', textDecoration: ok ? 'none' : 'line-through' }}>{userRight}</div>
              {!ok && (
                <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--success)' }}>→ {p.right}</div>
              )}
            </div>
          );
        })}
      </div>
    );
  }

  return null;
}

// ─────────────────────────────────────────────────────────────
// AWAITING — submitted but teacher hasn't published yet
// ─────────────────────────────────────────────────────────────
function AwaitingResultScreen({ nav, a }) {
  return (
    <div className="app screen-in">
      <StatusBar/>
      <NavHeader title="Awaiting results" onBack={() => nav.pop()}/>
      <div className="app-body" style={{ paddingTop: 4, gap: 14 }}>
        {/* Hero */}
        <div className="card" style={{ padding: 22, textAlign: 'center', background: 'linear-gradient(180deg, var(--warning-50) 0%, #fff 80%)' }}>
          <div style={{ width: 68, height: 68, borderRadius: 20, background: 'var(--warning)', color: '#fff', display: 'grid', placeItems: 'center', margin: '0 auto 14px' }}>
            <Icon name="clock" size={32}/>
          </div>
          <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--warning)', letterSpacing: '.1em', fontFamily: 'var(--mono)' }}>RESULTS PENDING</div>
          <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--n900)', marginTop: 6, letterSpacing: '-.02em' }}>{a.title}</div>
          <div style={{ fontSize: 12.5, color: 'var(--n600)', marginTop: 8, lineHeight: 1.5 }}>
            Submitted on <b style={{ color: 'var(--n900)' }}>{a.submittedOn}</b>.<br/>
            <b style={{ color: 'var(--n900)' }}>{a.by}</b> will publish your score {a.willPublishOn}.
          </div>
        </div>

        {/* Timeline */}
        <div className="card" style={{ padding: 14 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginBottom: 12 }}>What happens next</div>
          <div className="col" style={{ gap: 0 }}>
            {[
              { lab: 'You submitted', sub: a.submittedOn, state: 'done' },
              { lab: 'Teacher grading', sub: 'In progress', state: 'cur' },
              { lab: 'Results published', sub: a.willPublishOn || 'Within 3 days', state: 'todo' },
              { lab: 'You\'ll be notified', sub: 'Push + email', state: 'todo' },
            ].map((s, i, arr) => (
              <div key={i} className="row" style={{ gap: 12, alignItems: 'flex-start', paddingBottom: i < arr.length - 1 ? 12 : 0 }}>
                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
                  <div style={{
                    width: 22, height: 22, borderRadius: 99,
                    background: s.state === 'done' ? 'var(--success)' : s.state === 'cur' ? 'var(--warning)' : 'var(--n100)',
                    color: s.state === 'todo' ? 'var(--n400)' : '#fff',
                    display: 'grid', placeItems: 'center',
                  }}>
                    <Icon name={s.state === 'done' ? 'check' : s.state === 'cur' ? 'clock' : 'circle'} size={11}/>
                  </div>
                  {i < arr.length - 1 && <div style={{ width: 2, flex: 1, minHeight: 18, background: s.state === 'done' ? 'var(--success)' : 'var(--n100)', marginTop: 2 }}/>}
                </div>
                <div style={{ flex: 1, paddingTop: 1 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--n900)' }}>{s.lab}</div>
                  <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 2 }}>{s.sub}</div>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Snapshot */}
        <div className="card" style={{ padding: 14 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginBottom: 10 }}>What you submitted</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2,1fr)', gap: 10 }}>
            {[
              { l: 'Questions', v: a.qCount, mono: true },
              { l: 'Total marks', v: a.marks, mono: true },
              { l: 'Time limit', v: `${a.durationMin} min`, mono: false },
              { l: 'Set by', v: a.by, mono: false },
            ].map((s, i) => (
              <div key={i} className="card-flat" style={{ padding: 10 }}>
                <div style={{ fontSize: 9, fontWeight: 700, color: 'var(--n500)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>{s.l.toUpperCase()}</div>
                <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--n900)', marginTop: 4, fontVariantNumeric: 'tabular-nums', fontFamily: s.mono ? 'var(--mono)' : 'inherit' }}>{s.v}</div>
              </div>
            ))}
          </div>
        </div>

        {/* CTA */}
        <button onClick={() => nav.replace('assessments', { tab: 'history' })} className="btn" style={{ height: 46 }}>Back to history</button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// PRACTICE — drill weak topics. No timer, no marks, immediate feedback.
// Pulls 3 questions per weak type from PRACTICE_POOL[bank], falling back
// to the assessment's main bank when a topic-pool is sparse.
// ─────────────────────────────────────────────────────────────
function buildPracticeSet(aid, types) {
  const a = ASSESSMENTS.find(x => x.id === aid);
  if (!a) return [];
  const pool = PRACTICE_POOL[a.bank] || [];
  const fallback = banksFor(a);
  const out = [];
  (types || []).forEach(t => {
    const matchPool = pool.filter(q => q.type === t);
    const matchFallback = fallback.filter(q => q.type === t);
    // Prefer pool questions (easier, designed for practice), then fall back to original bank
    const pick = [...matchPool, ...matchFallback].slice(0, 3);
    out.push(...pick);
  });
  // De-duplicate by question text — the pool may overlap with fallback edge cases
  const seen = new Set();
  return out.filter(q => {
    if (seen.has(q.q)) return false;
    seen.add(q.q);
    return true;
  });
}

function PracticeIntroScreen({ nav, params }) {
  const aid = params && params.aid;
  const types = (params && params.types) || [];
  const a = ASSESSMENTS.find(x => x.id === aid);
  const Q = useMemoA(() => buildPracticeSet(aid, types), [aid, types]);
  if (!a || Q.length === 0) {
    return (
      <div className="app screen-in">
        <StatusBar/>
        <NavHeader title="Practice" onBack={() => nav.pop()}/>
        <div className="app-body" style={{ paddingTop: 8 }}>
          <div className="card" style={{ padding: 28, textAlign: 'center' }}>
            <div style={{ fontSize: 28 }}>👍</div>
            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 8 }}>No practice needed</div>
            <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 4 }}>You did well — nothing weak to drill on this one.</div>
          </div>
        </div>
      </div>
    );
  }
  return (
    <div className="app screen-in">
      <StatusBar/>
      <NavHeader title="Practice mode" onBack={() => nav.pop()}/>
      <div className="app-body" style={{ paddingTop: 4, gap: 14 }}>
        {/* Hero */}
        <div className="card" style={{ padding: 18, background: 'linear-gradient(180deg, var(--p50) 0%, #fff 70%)' }}>
          <div className="row" style={{ gap: 12, marginBottom: 10 }}>
            <div style={{ width: 44, height: 44, borderRadius: 12, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center' }}>
              <Icon name="edit" size={22}/>
            </div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--p700)', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>PRACTICE — NO MARKS</div>
              <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--n900)', marginTop: 2, letterSpacing: '-.01em' }}>
                Drill weak topics from {a.title.split('·')[0].trim()}
              </div>
            </div>
          </div>
          <div style={{ fontSize: 12, color: 'var(--n600)', lineHeight: 1.5 }}>
            {Q.length} question{Q.length === 1 ? '' : 's'} across {types.length} topic{types.length === 1 ? '' : 's'}.
            Take your time — see the explanation right after each answer.
          </div>
        </div>

        {/* Topics list */}
        <div className="card" style={{ padding: 4 }}>
          {types.map((t, i, arr) => {
            const n = Q.filter(q => q.type === t).length;
            return (
              <div key={t} className="row" style={{ padding: '11px 12px', gap: 10, borderBottom: i < arr.length - 1 ? '1px solid var(--n100)' : 'none' }}>
                <div style={{ width: 28, height: 28, borderRadius: 8, background: 'var(--warning-50)', color: 'var(--warning)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                  <Icon name={TYPE_META[t]?.icon || 'circle'} size={14}/>
                </div>
                <div style={{ flex: 1, fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>{TYPE_META[t]?.lab || t}</div>
                <div style={{ fontSize: 11.5, fontWeight: 800, color: 'var(--n700)', fontFamily: 'var(--mono)', fontVariantNumeric: 'tabular-nums' }}>×{n}</div>
              </div>
            );
          })}
        </div>

        {/* Differences from real attempt */}
        <div className="card-tinted" style={{ padding: 14 }}>
          <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--p700)', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginBottom: 8 }}>HOW PRACTICE WORKS</div>
          <div className="col" style={{ gap: 6 }}>
            {[
              'No timer — go at your own pace.',
              'Tap an answer, then "Check" — feedback shows immediately.',
              'You can move on once you\'ve seen the explanation.',
              'Nothing is recorded against your grade.',
            ].map((line, i) => (
              <div key={i} className="row" style={{ gap: 8, alignItems: 'flex-start' }}>
                <Icon name="check" size={12} style={{ color: 'var(--p600)', marginTop: 3, flexShrink: 0 }}/>
                <div style={{ fontSize: 12, color: 'var(--n700)', lineHeight: 1.45 }}>{line}</div>
              </div>
            ))}
          </div>
        </div>

        <button onClick={() => nav.push('practiceAttempt', { aid, types })} className="btn" style={{ marginTop: 4, height: 50 }}>
          Start practice <Icon name="arrow-right" size={16}/>
        </button>
      </div>
    </div>
  );
}

function PracticeAttemptScreen({ nav, params }) {
  const aid = params && params.aid;
  const types = (params && params.types) || [];
  const a = ASSESSMENTS.find(x => x.id === aid);
  const Q = useMemoA(() => buildPracticeSet(aid, types), [aid, types]);
  const [idx, setIdx] = useStateA(0);
  const [answers, setAnswers] = useStateA(() => Q.map(emptyAnswer));
  const [checked, setChecked] = useStateA(() => Q.map(() => false));
  const [done, setDone] = useStateA(false);

  if (!a || Q.length === 0) {
    return <PlaceholderScreen nav={nav} title="Practice unavailable" icon="edit"/>;
  }

  const q = Q[idx];
  const ans = answers[idx];
  const isChecked = checked[idx];
  const isCorrect = isChecked && isCorrectAnswer(q, ans);
  const correctSoFar = checked.reduce((n, c, i) => n + (c && isCorrectAnswer(Q[i], answers[i]) ? 1 : 0), 0);

  const setAnswer = (val) => {
    if (isChecked) return;
    setAnswers(prev => prev.map((p, i) => i === idx ? val : p));
  };

  const check = () => {
    if (!isAnswered(q, ans)) return;
    setChecked(prev => prev.map((c, i) => i === idx ? true : c));
  };

  const next = () => {
    if (idx < Q.length - 1) {
      setIdx(idx + 1);
    } else {
      setDone(true);
    }
  };

  if (done) {
    return <PracticeResultScreen nav={nav} aid={aid} types={types} Q={Q} answers={answers} checked={checked}/>;
  }

  return (
    <div className="app screen-in" style={{ background: 'var(--n50)' }}>
      <StatusBar/>
      {/* Top bar — progress only, no timer */}
      <div style={{ background: '#fff', borderBottom: '1px solid var(--n100)', padding: '10px 16px' }}>
        <div className="spread" style={{ marginBottom: 8 }}>
          <button onClick={() => nav.pop()} className="row" style={{ gap: 6, fontSize: 12, fontWeight: 600, color: 'var(--n600)' }}>
            <Icon name="x" size={14}/> Exit practice
          </button>
          <div className="row" style={{ gap: 6, padding: '6px 10px', background: 'var(--p50)', borderRadius: 9, color: 'var(--p700)' }}>
            <Icon name="edit" size={12}/>
            <span style={{ fontSize: 11, fontWeight: 800 }}>PRACTICE</span>
          </div>
        </div>
        <div className="spread" style={{ marginBottom: 6 }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--n700)' }}>Question {idx + 1} of {Q.length}</div>
          <div style={{ fontSize: 10.5, color: 'var(--success)', fontFamily: 'var(--mono)', fontWeight: 800 }}>{correctSoFar} correct</div>
        </div>
        <div style={{ height: 4, background: 'var(--n100)', borderRadius: 99, overflow: 'hidden' }}>
          <div style={{ width: `${(idx + 1) / Q.length * 100}%`, height: '100%', background: 'var(--p600)', borderRadius: 99, transition: 'width .25s' }}></div>
        </div>
      </div>

      <div className="app-body" style={{ paddingTop: 16, paddingBottom: 110, gap: 14 }}>
        <div className="card" style={{ padding: 18 }}>
          <div className="row" style={{ gap: 8, marginBottom: 12 }}>
            <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--p600)', letterSpacing: '.1em', fontFamily: 'var(--mono)' }}>Q{idx + 1}</div>
            <span className="pill" style={{ fontSize: 9.5, padding: '2px 7px', background: 'var(--n50)', color: 'var(--n700)', fontWeight: 700 }}>
              {TYPE_META[q.type]?.lab || q.type}
            </span>
            {isChecked && (
              <span className="pill" style={{
                fontSize: 9.5, padding: '2px 7px', marginLeft: 'auto',
                background: isCorrect ? 'var(--success-50)' : 'var(--c50)',
                color: isCorrect ? 'var(--success)' : 'var(--c600)', fontWeight: 800,
              }}>{isCorrect ? '✓ CORRECT' : '✗ TRY AGAIN'}</span>
            )}
          </div>
          {q.type !== 'fill' && (
            <div style={{ fontSize: 16, fontWeight: 700, color: 'var(--n900)', lineHeight: 1.45 }}>{q.q}</div>
          )}
          {q.type === 'multi' && (
            <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 8, fontStyle: 'italic' }}>Select all that apply</div>
          )}
        </div>

        {/* Input — disabled visually after check */}
        <div style={{ pointerEvents: isChecked ? 'none' : 'auto', opacity: isChecked ? .92 : 1 }}>
          <QuestionInput q={q} value={ans} onChange={setAnswer}/>
        </div>

        {/* Feedback panel after check */}
        {isChecked && (
          <div className="card" style={{
            padding: 14, gap: 10,
            background: isCorrect ? 'var(--success-50)' : 'var(--c50)',
            border: `1px solid ${isCorrect ? '#A7F3D0' : '#FCA5A5'}`,
          }}>
            <div className="row" style={{ gap: 8, marginBottom: 6 }}>
              <Icon name={isCorrect ? 'check' : 'x'} size={16} style={{ color: isCorrect ? 'var(--success)' : 'var(--c600)' }}/>
              <div style={{ fontSize: 13, fontWeight: 800, color: isCorrect ? 'var(--success)' : 'var(--c600)' }}>
                {isCorrect ? 'Nice — that\'s right.' : 'Not quite.'}
              </div>
            </div>
            <div style={{ fontSize: 12, color: 'var(--n800)', lineHeight: 1.5 }}>{q.expl}</div>
          </div>
        )}
      </div>

      <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: 14, background: '#fff', borderTop: '1px solid var(--n100)' }}>
        {!isChecked ? (
          <button
            onClick={check}
            disabled={!isAnswered(q, ans)}
            className="btn-sm"
            style={{
              width: '100%', height: 50, borderRadius: 12, fontWeight: 800,
              background: isAnswered(q, ans) ? 'var(--n900)' : 'var(--n100)',
              color: isAnswered(q, ans) ? '#fff' : 'var(--n400)',
            }}>
            Check answer
          </button>
        ) : (
          <button onClick={next} className="btn-sm" style={{ width: '100%', height: 50, borderRadius: 12, background: 'var(--p600)', color: '#fff', fontWeight: 800 }}>
            {idx < Q.length - 1 ? <>Next question <Icon name="arrow-right" size={16}/></> : <>Finish <Icon name="check" size={16}/></>}
          </button>
        )}
      </div>
    </div>
  );
}

function PracticeResultScreen({ nav, aid, types, Q, answers, checked }) {
  const a = ASSESSMENTS.find(x => x.id === aid);
  const correct = Q.reduce((n, q, i) => n + (checked[i] && isCorrectAnswer(q, answers[i]) ? 1 : 0), 0);
  const pct = Math.round(correct / Q.length * 100);
  const recovered = pct >= 60;
  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingTop: 50, gap: 16 }}>
        <div className="card" style={{ padding: 24, textAlign: 'center', background: `linear-gradient(180deg, ${recovered ? 'var(--success-50)' : 'var(--warning-50)'} 0%, #fff 80%)` }}>
          <div style={{ width: 76, height: 76, borderRadius: 22, background: recovered ? 'var(--success)' : 'var(--warning)', color: '#fff', display: 'grid', placeItems: 'center', margin: '0 auto 14px' }}>
            <Icon name={recovered ? 'check' : 'edit'} size={36}/>
          </div>
          <div style={{ fontSize: 9.5, fontWeight: 800, color: recovered ? 'var(--success)' : 'var(--warning)', letterSpacing: '.1em', fontFamily: 'var(--mono)' }}>PRACTICE COMPLETE</div>
          <div style={{ fontSize: 22, fontWeight: 800, color: 'var(--n900)', marginTop: 4, letterSpacing: '-.02em' }}>
            {correct} of {Q.length} right
          </div>
          <div style={{ fontSize: 13, color: 'var(--n600)', marginTop: 8, lineHeight: 1.5 }}>
            {recovered
              ? <>Big improvement. Try the real assessment again when you're ready.</>
              : <>Still bumpy on these — go through the explanations once more.</>}
          </div>
        </div>

        {/* Per-topic mini summary */}
        <div className="card" style={{ padding: 14 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginBottom: 10 }}>By topic</div>
          {types.map((t, i, arr) => {
            const subset = Q.map((q, idx) => ({ q, idx })).filter(x => x.q.type === t);
            const sCorrect = subset.reduce((n, x) => n + (checked[x.idx] && isCorrectAnswer(x.q, answers[x.idx]) ? 1 : 0), 0);
            const sPct = subset.length ? Math.round(sCorrect / subset.length * 100) : 0;
            const clr = sPct >= 80 ? 'var(--success)' : sPct >= 50 ? 'var(--warning)' : 'var(--c600)';
            return (
              <div key={t} className="row" style={{ padding: '10px 0', gap: 10, borderBottom: i < arr.length - 1 ? '1px solid var(--n100)' : 'none' }}>
                <div style={{ width: 28, height: 28, borderRadius: 8, background: 'var(--n50)', color: 'var(--n700)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                  <Icon name={TYPE_META[t]?.icon || 'circle'} size={14}/>
                </div>
                <div style={{ flex: 1, fontSize: 12.5, fontWeight: 700, color: 'var(--n900)' }}>{TYPE_META[t]?.lab || t}</div>
                <div style={{ fontSize: 11, fontWeight: 800, color: clr, fontFamily: 'var(--mono)', fontVariantNumeric: 'tabular-nums' }}>
                  {sCorrect}/{subset.length} · {sPct}%
                </div>
              </div>
            );
          })}
        </div>

        {/* CTAs */}
        <div className="col" style={{ gap: 10, marginTop: 'auto' }}>
          {a && a.resultsMode === 'instant' && (
            <button onClick={() => nav.replace('assessmentAttempt', { id: a.id, retake: true })} className="btn" style={{ height: 48 }}>
              <Icon name="zap" size={16}/> Retake the real assessment
            </button>
          )}
          <div className="row" style={{ gap: 10 }}>
            <button onClick={() => nav.replace('practiceIntro', { aid, types })} className="btn btn-outline" style={{ flex: 1, height: 46 }}>
              <Icon name="edit" size={14}/> Practice again
            </button>
            <button onClick={() => nav.replace('assessments', { tab: 'history' })} className="btn btn-outline" style={{ flex: 1, height: 46 }}>
              Done
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ═════════════════════════════════════════════════════════════
// TEACHER SIDE — author, monitor, grade, publish
// ═════════════════════════════════════════════════════════════
// Teacher context: Sneha Reddy (alias "Mrs. Reddy" in author fields).
// She's class-teacher of 8-B and subject teacher for 9-A and 10-C.
// We treat any RAW_ASSESSMENTS row authored by "Mrs. Reddy" as hers,
// and add a draft + a couple of upcoming items so the hub has variety.
// ─────────────────────────────────────────────────────────────
const TEACHER_CONTEXT = {
  name: 'Sneha Reddy', alias: 'Mrs. Reddy',
  school: 'DPS Hyderabad',
  classes: [
    { cls: '8-B', n: 32, role: 'Class teacher · Math' },
    { cls: '9-A', n: 28, role: 'Subject · Math' },
    { cls: '10-C', n: 30, role: 'Subject · Math' },
  ],
};

// 32 students in 8-B — used for submissions matrix.
const CLASS_8B_STUDENTS = [
  'Aarav Reddy','Diya Nair','Kavya Menon','Vihaan Iyer','Riya Shah','Arjun Kapoor',
  'Ananya Verma','Karthik R.','Meera Krishnan','Rohan Mehta','Saanvi Joshi','Aditya Das',
  'Ishaan Pillai','Tara Subramanian','Zoya Khan','Pranav Bhat','Nikhil Gupta','Avni Rao',
  'Myra Singh','Reyansh Gowda','Sai Kiran','Aanya Bose','Ved Patil','Krishna Murthy',
  'Lakshmi Pai','Nivedita C.','Aryan Naidu','Tanvi Rao','Dhruv Sharma','Anika Banerjee',
  'Yuvraj Jain','Siya Hegde',
];

// Per-assessment per-student submissions — derived deterministically.
// state ∈ { 'submitted', 'graded', 'pending', 'absent' }
function buildSubmissions(aid, qCount, scoreMaxIn, autoGrade = true) {
  const seed = aid.split('').reduce((s, c) => s + c.charCodeAt(0), 0);
  const rand = (i, salt = 0) => {
    const x = Math.sin(seed * 91 + i * 13 + salt * 7) * 10000;
    return x - Math.floor(x);
  };
  const scoreMax = scoreMaxIn || 20;
  return CLASS_8B_STUDENTS.map((name, i) => {
    const r = rand(i);
    let state, scoreVal, timeMin;
    if (r < 0.08) { state = 'absent'; scoreVal = null; timeMin = null; }
    else if (!autoGrade && r < 0.85) { state = 'submitted'; scoreVal = null; timeMin = 6 + Math.floor(rand(i,1) * 18); }
    else { state = autoGrade ? 'graded' : 'submitted';
      const pct = 0.42 + rand(i, 2) * 0.55;
      scoreVal = Math.round(pct * scoreMax);
      timeMin = 6 + Math.floor(rand(i, 3) * 18);
    }
    return {
      id: 's' + (i + 1).toString().padStart(2, '0'),
      name,
      initial: name[0],
      clr: ['', 'coral', 'green', 'sky', 'violet'][i % 5],
      state,
      scoreVal,
      timeMin,
      submittedOn: state !== 'absent' ? `${10 + (i % 4)}:${(15 + i * 3) % 60} ${i % 2 ? 'AM' : 'PM'}` : null,
    };
  });
}

// Teacher's own assessments — derived from RAW_ASSESSMENTS + 2 extras.
const TEACHER_OWN_ASSESSMENTS = [
  // Draft — not yet sent to students
  { id: 't_draft_1', sub: 'Mathematics', icon: 'flask', clr: 'var(--p600)', bg: 'var(--p50)',
    title: 'Trigonometry · Ratios & angles',
    by: 'Mrs. Reddy', cls: '9-A', school: 'DPS Hyderabad',
    bank: 'linear', resultsMode: 'instant',
    qCount: 12, marks: 24, durationMin: 25, attempts: '1 of 1',
    state: 'draft', lastEdited: 'Mon 10 Mar · 6:42 PM',
    completion: 0.6,
  },
  // Scheduled — set up but not yet live
  { id: 't_sched_1', sub: 'Mathematics', icon: 'flask', clr: 'var(--p600)', bg: 'var(--p50)',
    title: 'Quadratic equations · Test',
    by: 'Mrs. Reddy', cls: '10-C', school: 'DPS Hyderabad',
    bank: 'linear', resultsMode: 'instant',
    qCount: 15, marks: 30, durationMin: 35, attempts: '1 of 1',
    state: 'scheduled', releasesOn: 'Wed 12 Mar · 10:00 AM', dueOn: 'Sat 15 Mar 11:59 PM',
  },
  // Live — pull a1 (Linear equations · Practice quiz · Mrs. Reddy · 8-B)
  // Live — pull a4 (Mental math · Sprint 4) but reframed as teacher view
];

// Compose: drafts/scheduled (above) + Mrs. Reddy's items from RAW_ASSESSMENTS
const TEACHER_ASSESSMENTS_BASE = (() => {
  const own = RAW_ASSESSMENTS.filter(a => a.by === 'Mrs. Reddy').map(a => {
    const subs = buildSubmissions(a.id, a.qCount, a.scoreMax || a.marks,
      // Auto-grade only happens for non-delayed-mode tests with no teacher-graded short answers
      a.resultsMode === 'instant');
    const submitted = subs.filter(s => s.state !== 'absent').length;
    const graded = subs.filter(s => s.state === 'graded').length;
    const pending = subs.filter(s => s.state === 'submitted').length;
    const total = subs.length;
    // Compute teacher-facing state
    let tState;
    if (a.state === 'completed' && a.publishedOn) tState = 'published';
    else if (a.state === 'completed' && a.resultsMode === 'instant') tState = 'published';
    else if (a.resultsMode === 'delayed' && pending > 0) tState = 'to_grade';
    else if (a.state === 'completed' && !a.publishedOn && a.resultsMode === 'delayed') tState = 'to_grade';
    else if (submitted < total) tState = 'live';
    else tState = 'closed';
    // Average score (graded only)
    const gradedSubs = subs.filter(s => s.state === 'graded' && s.scoreVal != null);
    const avgPct = gradedSubs.length
      ? Math.round((gradedSubs.reduce((s, x) => s + x.scoreVal, 0) / (gradedSubs.length * (a.scoreMax || a.marks))) * 100)
      : null;
    return { ...a, _t: { state: tState, subs, submitted, graded, pending, total, avgPct } };
  });
  return [...TEACHER_OWN_ASSESSMENTS, ...own];
})();

const TEACHER_ASSESSMENTS = TEACHER_ASSESSMENTS_BASE;

// Teacher-side state buckets for the hub
const T_STATE_META = {
  draft:     { lab: 'DRAFT',         tone: 'var(--n500)',   bg: 'var(--n100)',     icon: 'edit' },
  scheduled: { lab: 'SCHEDULED',     tone: '#1E40AF',       bg: 'var(--info-50)',  icon: 'calendar' },
  live:      { lab: 'LIVE',          tone: 'var(--success)', bg: 'var(--success-50)', icon: 'zap' },
  to_grade:  { lab: 'TO GRADE',      tone: 'var(--warning)', bg: 'var(--warning-50)', icon: 'clipboard' },
  published: { lab: 'PUBLISHED',     tone: 'var(--p600)',   bg: 'var(--p50)',      icon: 'check' },
  closed:    { lab: 'CLOSED',        tone: 'var(--n500)',   bg: 'var(--n100)',     icon: 'check' },
};

const findTeacherAssessment = (id) => TEACHER_ASSESSMENTS.find(a => a.id === id);

// ─────────────────────────────────────────────────────────────
// Shared helper — compact metadata pill row
// ─────────────────────────────────────────────────────────────
function TStatePill({ state }) {
  const m = T_STATE_META[state] || T_STATE_META.live;
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4,
      padding: '3px 8px', background: m.bg, color: m.tone,
      borderRadius: 6, fontSize: 9.5, fontWeight: 800,
      letterSpacing: '.06em', fontFamily: 'var(--mono)',
    }}>
      {state === 'live' && <span style={{ width: 6, height: 6, borderRadius: '50%', background: m.tone, animation: 'none' }}/>}
      {m.lab}
    </span>
  );
}

// ─────────────────────────────────────────────────────────────
// 1. Teacher Assessments Hub
// ─────────────────────────────────────────────────────────────
function TeacherAssessmentsHubScreen({ nav }) {
  const [tab, setTab] = useStateA('all');
  const [classFilter, setClassFilter] = useStateA('all');

  const counts = useMemoA(() => {
    const c = { all: TEACHER_ASSESSMENTS.length, draft: 0, scheduled: 0, live: 0, to_grade: 0, published: 0 };
    TEACHER_ASSESSMENTS.forEach(a => {
      const s = a._t ? a._t.state : a.state;
      if (c[s] != null) c[s]++;
    });
    return c;
  }, []);

  const visible = useMemoA(() => {
    return TEACHER_ASSESSMENTS.filter(a => {
      const s = a._t ? a._t.state : a.state;
      if (tab !== 'all' && s !== tab) return false;
      if (classFilter !== 'all' && a.cls !== classFilter) return false;
      return true;
    });
  }, [tab, classFilter]);

  const tabs = [
    { id: 'all', lab: 'All', n: counts.all },
    { id: 'live', lab: 'Live', n: counts.live },
    { id: 'to_grade', lab: 'To grade', n: counts.to_grade },
    { id: 'published', lab: 'Published', n: counts.published },
    { id: 'draft', lab: 'Drafts', n: counts.draft + counts.scheduled },
  ];

  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body">
        {/* Header */}
        <div className="row" style={{ padding: '6px 0 4px', gap: 12, alignItems: 'center' }}>
          <button onClick={() => nav.pop()} title="Back" style={{ width: 40, height: 40, borderRadius: 12, background: 'var(--n50)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name="chev-l" size={20}/></button>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 22, fontWeight: 800, letterSpacing: '-.02em' }}>Assessments</div>
            <div style={{ fontSize: 11.5, color: 'var(--n500)', marginTop: 1 }}>
              {TEACHER_CONTEXT.name} · {TEACHER_CONTEXT.classes.length} classes
            </div>
          </div>
          <button onClick={() => nav.push('teachCreateAssessment')} title="New assessment" style={{ width: 40, height: 40, borderRadius: 12, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name="plus" size={18}/></button>
        </div>

        {/* 4-stat strip */}
        <div className="card-flat" style={{ marginTop: 10, padding: 12, display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 8 }}>
          {[
            { v: counts.live, l: 'Live', clr: 'var(--success)' },
            { v: counts.to_grade, l: 'To grade', clr: 'var(--warning)' },
            { v: counts.draft + counts.scheduled, l: 'Drafts', clr: 'var(--n500)' },
            { v: counts.published, l: 'Published', clr: 'var(--p600)' },
          ].map((s, i) => (
            <div key={i} style={{ textAlign: 'center', borderRight: i < 3 ? '1px solid var(--n200)' : 'none' }}>
              <div style={{ fontSize: 20, fontWeight: 800, color: s.clr, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>{s.v}</div>
              <div style={{ fontSize: 10, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>{s.l}</div>
            </div>
          ))}
        </div>

        {/* Class filter chips */}
        <div style={{ display: 'flex', gap: 8, overflowX: 'auto', margin: '12px -20px 0', padding: '0 20px 4px' }}>
          {[{ cls: 'all', lab: 'All classes' }, ...TEACHER_CONTEXT.classes.map(c => ({ cls: c.cls, lab: `Class ${c.cls}` }))].map(c => {
            const isActive = classFilter === c.cls;
            return (
              <button key={c.cls} onClick={() => setClassFilter(c.cls)} style={{
                flexShrink: 0, padding: '7px 12px',
                background: isActive ? 'var(--n900)' : 'var(--n50)',
                color: isActive ? '#fff' : 'var(--n700)',
                border: '1px solid ' + (isActive ? 'var(--n900)' : 'var(--n100)'),
                borderRadius: 999, fontSize: 12, fontWeight: 700,
                cursor: 'pointer', whiteSpace: 'nowrap',
              }}>{c.lab}</button>
            );
          })}
        </div>

        {/* Tabs */}
        <div style={{ display: 'flex', gap: 4, marginTop: 14, padding: 4, background: 'var(--n50)', borderRadius: 12, overflowX: 'auto' }}>
          {tabs.map(tt => {
            const isActive = tab === tt.id;
            return (
              <button key={tt.id} onClick={() => setTab(tt.id)} style={{
                flexShrink: 0, padding: '8px 12px',
                background: isActive ? '#fff' : 'transparent',
                color: isActive ? 'var(--n900)' : 'var(--n500)',
                border: 'none', borderRadius: 9,
                fontSize: 12, fontWeight: 700,
                cursor: 'pointer', boxShadow: isActive ? 'var(--el-1)' : 'none',
                display: 'inline-flex', alignItems: 'center', gap: 6,
              }}>
                {tt.lab}
                {tt.n > 0 && <span style={{
                  fontSize: 10, fontWeight: 700, padding: '1px 6px',
                  background: isActive ? 'var(--p50)' : 'var(--n100)',
                  color: isActive ? 'var(--p600)' : 'var(--n500)',
                  borderRadius: 999, fontFamily: 'var(--mono)',
                }}>{tt.n}</span>}
              </button>
            );
          })}
        </div>

        {/* Empty state */}
        {visible.length === 0 && (
          <div className="card-flat" style={{ marginTop: 16, padding: 24, textAlign: 'center' }}>
            <div style={{ fontSize: 36, marginBottom: 8 }}>📋</div>
            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>Nothing here</div>
            <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 4 }}>
              Try a different filter, or tap + to create an assessment.
            </div>
          </div>
        )}

        {/* Assessment cards */}
        <div className="col" style={{ gap: 10, marginTop: 12 }}>
          {visible.map(a => {
            const tt = a._t || { state: a.state, total: 32, submitted: 0, graded: 0, pending: 0, avgPct: null };
            const m = T_STATE_META[tt.state];
            const onTap = () => {
              if (tt.state === 'draft' || tt.state === 'scheduled') nav.push('teachCreateAssessment', { id: a.id });
              else nav.push('teachSubmissions', { id: a.id });
            };
            const submitPct = Math.round((tt.submitted / tt.total) * 100);
            return (
              <button key={a.id} onClick={onTap} className="card" style={{ padding: 14, textAlign: 'left' }}>
                <div className="row" style={{ gap: 12, alignItems: 'flex-start' }}>
                  <div style={{ width: 40, height: 40, borderRadius: 11, background: a.bg, color: a.clr, display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name={a.icon} size={18}/></div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="spread">
                      <div style={{ fontSize: 13.5, fontWeight: 800, color: 'var(--n900)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{a.title}</div>
                      <TStatePill state={tt.state}/>
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 2 }}>
                      {a.sub} · Class {a.cls} · {a.qCount}q · {a.marks}m
                    </div>
                  </div>
                </div>

                {/* State-specific footer strip */}
                {tt.state === 'live' && (
                  <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--n100)' }}>
                    <div className="spread" style={{ marginBottom: 6 }}>
                      <span style={{ fontSize: 11, color: 'var(--n600)', fontWeight: 700 }}>
                        {tt.submitted} of {tt.total} submitted
                      </span>
                      <span style={{ fontSize: 10.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 600 }}>
                        Due {a.dueOn}
                      </span>
                    </div>
                    <div style={{ height: 5, background: 'var(--n100)', borderRadius: 999, overflow: 'hidden' }}>
                      <div style={{ width: submitPct + '%', height: '100%', background: m.tone }}/>
                    </div>
                  </div>
                )}
                {tt.state === 'to_grade' && (
                  <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--n100)' }}>
                    <div className="row" style={{ gap: 8, justifyContent: 'space-between' }}>
                      <span style={{ fontSize: 11, color: 'var(--warning)', fontWeight: 800 }}>
                        ● {tt.pending} awaiting your review
                      </span>
                      <span style={{ fontSize: 10.5, color: 'var(--n500)', fontFamily: 'var(--mono)' }}>
                        {tt.graded}/{tt.submitted} graded
                      </span>
                    </div>
                  </div>
                )}
                {tt.state === 'published' && (
                  <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--n100)' }}>
                    <div className="row" style={{ gap: 16 }}>
                      <div>
                        <div style={{ fontSize: 9.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 700, letterSpacing: '.06em' }}>CLASS AVG</div>
                        <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)', fontVariantNumeric: 'tabular-nums', marginTop: 2 }}>{tt.avgPct}%</div>
                      </div>
                      <div>
                        <div style={{ fontSize: 9.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 700, letterSpacing: '.06em' }}>SUBMITTED</div>
                        <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)', fontVariantNumeric: 'tabular-nums', marginTop: 2 }}>{tt.submitted}/{tt.total}</div>
                      </div>
                      <div style={{ marginLeft: 'auto' }}>
                        <button onClick={(e) => { e.stopPropagation(); nav.push('teachClassAnalytics', { id: a.id }); }} className="btn-sm btn-soft" style={{ height: 30, padding: '0 12px', fontSize: 11 }}>Analytics</button>
                      </div>
                    </div>
                  </div>
                )}
                {tt.state === 'draft' && (
                  <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--n100)' }}>
                    <div className="spread" style={{ marginBottom: 6 }}>
                      <span style={{ fontSize: 11, color: 'var(--n600)', fontWeight: 700 }}>
                        {Math.round((a.completion || 0.5) * 100)}% complete
                      </span>
                      <span style={{ fontSize: 10.5, color: 'var(--n500)', fontFamily: 'var(--mono)' }}>
                        Edited {a.lastEdited}
                      </span>
                    </div>
                    <div style={{ height: 5, background: 'var(--n100)', borderRadius: 999, overflow: 'hidden' }}>
                      <div style={{ width: Math.round((a.completion || 0.5) * 100) + '%', height: '100%', background: 'var(--n400)' }}/>
                    </div>
                  </div>
                )}
                {tt.state === 'scheduled' && (
                  <div style={{ marginTop: 12, paddingTop: 12, borderTop: '1px solid var(--n100)' }}>
                    <div style={{ fontSize: 11, color: 'var(--n600)', fontWeight: 700 }}>
                      <Icon name="clock" size={11} style={{ verticalAlign: -1, marginRight: 4 }}/>
                      Releases {a.releasesOn}
                    </div>
                  </div>
                )}
              </button>
            );
          })}
        </div>

        <div style={{ height: 32 }}/>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// 2. Teacher — Create / Edit assessment (form + question list)
// ─────────────────────────────────────────────────────────────
function TeacherCreateAssessmentScreen({ nav, params }) {
  const editing = params && params.id ? findTeacherAssessment(params.id) : null;
  const [title, setTitle] = useStateA(editing ? editing.title : '');
  const [sub, setSub] = useStateA(editing ? editing.sub : 'Mathematics');
  const [cls, setCls] = useStateA(editing ? editing.cls : '8-B');
  const [duration, setDuration] = useStateA(editing ? editing.durationMin : 20);
  const [marks, setMarks] = useStateA(editing ? editing.marks : 20);
  const [resultsMode, setResultsMode] = useStateA(editing ? editing.resultsMode : 'instant');
  const [attempts, setAttempts] = useStateA(1);
  const [dueOn, setDueOn] = useStateA(editing && editing.dueOn ? editing.dueOn : 'Fri 14 Mar 11:59 PM');
  const [questions, setQuestions] = useStateA(editing ? banksFor(editing).slice(0, editing.qCount || 6) : []);
  const totalMarks = questions.reduce((s, q) => s + (q.marks || 2), 0) || marks;

  // Consume questions staged by the AI generation flow (set just before nav.pop)
  useEffectA(() => {
    const staged = window.__aiPickedQuestions;
    if (staged && staged.length) {
      setQuestions(qs => [...qs, ...staged]);
      window.__aiPickedQuestions = null;
    }
  });

  const SUBJECTS = ['Mathematics', 'Science', 'English', 'Social Studies', 'History'];
  const SUB_META = {
    Mathematics: { ic: 'flask', clr: 'var(--p600)', bg: 'var(--p50)' },
    Science: { ic: 'flask', clr: 'var(--success)', bg: 'var(--success-50)' },
    English: { ic: 'book-open', clr: '#1E40AF', bg: 'var(--info-50)' },
    'Social Studies': { ic: 'globe', clr: 'var(--c600)', bg: 'var(--c50)' },
    History: { ic: 'globe', clr: 'var(--warning)', bg: 'var(--warning-50)' },
  };

  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingBottom: 100 }}>
        <NavHeader title={editing ? 'Edit assessment' : 'New assessment'} onBack={() => nav.pop()}/>

        {/* Basics */}
        <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 18 }}>
          Basics
        </div>
        <div className="card" style={{ padding: 16, marginTop: 8 }}>
          <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block' }}>Title</label>
          <input value={title} onChange={e => setTitle(e.target.value)} placeholder="e.g. Linear equations · Practice quiz" style={{
            width: '100%', marginTop: 4, padding: '10px 0', border: 'none', borderBottom: '1px solid var(--n200)',
            font: 'inherit', fontSize: 15, fontWeight: 700, outline: 'none', color: 'var(--n900)', background: 'transparent',
          }}/>

          <div style={{ marginTop: 16 }}>
            <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block', marginBottom: 8 }}>Subject</label>
            <div style={{ display: 'flex', gap: 6, overflowX: 'auto', margin: '0 -16px', padding: '0 16px 4px' }}>
              {SUBJECTS.map(s => {
                const isActive = sub === s;
                const m = SUB_META[s];
                return (
                  <button key={s} onClick={() => setSub(s)} style={{
                    flexShrink: 0, padding: '8px 12px',
                    display: 'inline-flex', alignItems: 'center', gap: 6,
                    background: isActive ? m.bg : '#fff',
                    color: isActive ? m.clr : 'var(--n600)',
                    border: '1px solid ' + (isActive ? m.clr : 'var(--n200)'),
                    borderRadius: 10, fontSize: 12, fontWeight: 700, cursor: 'pointer',
                  }}><Icon name={m.ic} size={13}/> {s}</button>
                );
              })}
            </div>
          </div>

          <div style={{ marginTop: 16 }}>
            <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block', marginBottom: 8 }}>Send to class</label>
            <div className="row" style={{ gap: 6, flexWrap: 'wrap' }}>
              {TEACHER_CONTEXT.classes.map(c => {
                const isActive = cls === c.cls;
                return (
                  <button key={c.cls} onClick={() => setCls(c.cls)} style={{
                    padding: '8px 14px',
                    background: isActive ? 'var(--p600)' : '#fff',
                    color: isActive ? '#fff' : 'var(--n700)',
                    border: '1px solid ' + (isActive ? 'var(--p600)' : 'var(--n200)'),
                    borderRadius: 10, fontSize: 12, fontWeight: 700, cursor: 'pointer',
                  }}>Class {c.cls} <span style={{ fontWeight: 500, opacity: .7 }}>· {c.n}</span></button>
                );
              })}
            </div>
          </div>
        </div>

        {/* Schedule + settings */}
        <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 24 }}>
          Schedule & rules
        </div>
        <div className="card" style={{ padding: 0, marginTop: 8 }}>
          <SettingRow label="Due on" value={dueOn} icon="calendar"/>
          <SettingRow label="Duration" value={duration + ' min'} icon="clock" onTap={() => setDuration(duration === 20 ? 30 : duration === 30 ? 45 : 20)}/>
          <SettingRow label="Total marks" value={totalMarks + ' m'} icon="target"/>
          <SettingRow label="Attempts allowed" value={attempts === 1 ? '1 (single attempt)' : attempts === 2 ? '2 attempts' : 'Unlimited'} icon="zap" onTap={() => setAttempts(attempts === 1 ? 2 : attempts === 2 ? 99 : 1)}/>
          <SettingRow label="Result mode" rightSlot={
            <div className="row" style={{ gap: 4 }}>
              <button onClick={() => setResultsMode('instant')} style={{
                padding: '6px 10px',
                background: resultsMode === 'instant' ? 'var(--success)' : 'var(--n100)',
                color: resultsMode === 'instant' ? '#fff' : 'var(--n600)',
                border: 'none', borderRadius: 8, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              }}>Instant</button>
              <button onClick={() => setResultsMode('delayed')} style={{
                padding: '6px 10px',
                background: resultsMode === 'delayed' ? 'var(--warning)' : 'var(--n100)',
                color: resultsMode === 'delayed' ? '#fff' : 'var(--n600)',
                border: 'none', borderRadius: 8, fontSize: 11, fontWeight: 700, cursor: 'pointer',
              }}>Delayed</button>
            </div>
          } icon="info" last/>
        </div>
        <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 6, lineHeight: 1.5, padding: '0 4px' }}>
          {resultsMode === 'instant'
            ? 'Students see their score and review immediately on submit.'
            : 'Students see only "Submitted". You publish results manually after grading.'}
        </div>

        {/* Question list */}
        <div className="spread" style={{ marginTop: 24 }}>
          <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)' }}>
            Questions · {questions.length}
          </div>
          <div className="row" style={{ gap: 8 }}>
            <button onClick={() => nav.push('teachAIGenerate', { sub, cls, title })} style={{
              display: 'inline-flex', alignItems: 'center', gap: 4,
              padding: '6px 10px', borderRadius: 8, border: 'none', cursor: 'pointer',
              background: 'linear-gradient(135deg, var(--p50), var(--c50))',
              color: 'var(--p700)', fontSize: 11.5, fontWeight: 700,
            }}>
              <Icon name="sparkles" size={13}/> Generate with AI
            </button>
            <button onClick={() => nav.push('teachAddQuestion')} className="btn-ghost" style={{ fontSize: 12, fontWeight: 700, color: 'var(--p600)' }}>
              <Icon name="plus" size={14}/> Add question
            </button>
          </div>
        </div>

        {questions.length === 0 ? (
          <div className="card-flat" style={{ marginTop: 8, padding: 24, textAlign: 'center', border: '1.5px dashed var(--n200)' }}>
            <div style={{
              width: 52, height: 52, borderRadius: 14, margin: '0 auto',
              background: 'linear-gradient(135deg, var(--p50), var(--c50))',
              color: 'var(--p600)', display: 'grid', placeItems: 'center',
            }}><Icon name="sparkles" size={24}/></div>
            <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--n900)', marginTop: 12 }}>Let AI write the first draft</div>
            <div style={{ fontSize: 11.5, color: 'var(--n500)', marginTop: 4, lineHeight: 1.5, maxWidth: 240, margin: '4px auto 0' }}>
              Generate questions from this assessment's context — or paste a chapter and let AI build from it.
            </div>
            <button onClick={() => nav.push('teachAIGenerate', { sub, cls, title })} className="btn" style={{ height: 40, fontSize: 12.5, marginTop: 14, paddingLeft: 16, paddingRight: 16 }}>
              <Icon name="sparkles" size={14}/> Generate with AI
            </button>
            <div style={{ fontSize: 10.5, color: 'var(--n400)', marginTop: 14, fontFamily: 'var(--mono)', letterSpacing: '.06em' }}>OR</div>
            <div className="row" style={{ gap: 8, marginTop: 10, justifyContent: 'center' }}>
              <button onClick={() => nav.push('teachAddQuestion')} className="btn btn-outline" style={{ height: 36, fontSize: 12 }}>
                <Icon name="plus" size={13}/> Add manually
              </button>
              <button onClick={() => setQuestions(BANK_LINEAR.slice(0, 6))} className="btn btn-soft" style={{ height: 36, fontSize: 12 }}>
                <Icon name="clipboard" size={13}/> Import from bank
              </button>
            </div>
          </div>
        ) : (
          <div className="col" style={{ gap: 8, marginTop: 8 }}>
            {questions.map((q, i) => {
              const meta = TYPE_META[q.type] || { lab: q.type, icon: 'circle' };
              return (
                <div key={i} className="card" style={{ padding: 12 }}>
                  <div className="row" style={{ gap: 12, alignItems: 'flex-start' }}>
                    <div style={{
                      width: 28, height: 28, borderRadius: 8, background: 'var(--p50)', color: 'var(--p600)',
                      display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 800,
                      fontFamily: 'var(--mono)', flexShrink: 0,
                    }}>Q{i + 1}</div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--n900)', lineHeight: 1.4 }}>
                        {q.q}
                      </div>
                      <div className="row" style={{ gap: 8, marginTop: 6 }}>
                        <span style={{
                          fontSize: 9.5, fontWeight: 700, padding: '2px 7px',
                          background: 'var(--n100)', color: 'var(--n600)',
                          borderRadius: 5, letterSpacing: '.04em', fontFamily: 'var(--mono)',
                        }}>{meta.lab}</span>
                        <span style={{ fontSize: 10.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 600 }}>{q.marks || 2}m</span>
                      </div>
                    </div>
                    <button onClick={() => setQuestions(qs => qs.filter((_, j) => j !== i))} style={{
                      width: 28, height: 28, borderRadius: 8, background: 'var(--n50)', color: 'var(--n500)',
                      display: 'grid', placeItems: 'center', border: 'none', cursor: 'pointer',
                    }}><Icon name="x" size={12}/></button>
                  </div>
                </div>
              );
            })}
          </div>
        )}

      </div>

      {/* Bottom CTAs */}
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0,
        background: '#fff', borderTop: '1px solid var(--n100)',
        padding: '12px 16px', display: 'flex', gap: 8,
      }}>
        {!editing ? (
          <button onClick={() => nav.replace('teachAssessments', { tab: 'draft' })} className="btn" style={{ flex: 1, height: 46 }} disabled={!title}>
            <Icon name="check" size={14}/> Save draft
          </button>
        ) : (
          <>
            <button onClick={() => nav.replace('teachAssessments', { tab: editing.state === 'scheduled' ? 'scheduled' : 'draft' })} className="btn btn-outline" style={{ flex: 1, height: 46 }}>
              Save changes
            </button>
            <button onClick={() => nav.replace('teachAssessments', { tab: 'live' })} className="btn" style={{ flex: 1.4, height: 46 }} disabled={!title || questions.length === 0}>
              <Icon name="send" size={14}/> {editing.state === 'scheduled' ? 'Update' : 'Publish to class'}
            </button>
          </>
        )}
      </div>
    </div>
  );
}

// Helper: settings row component
function SettingRow({ label, value, icon, onTap, rightSlot, last }) {
  return (
    <div onClick={onTap} className="row" style={{
      padding: '14px 16px', gap: 12, cursor: onTap ? 'pointer' : 'default',
      borderBottom: last ? 'none' : '1px solid var(--n100)',
    }}>
      {icon && <div style={{ width: 32, height: 32, borderRadius: 8, background: 'var(--n50)', color: 'var(--n600)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name={icon} size={14}/></div>}
      <div style={{ flex: 1, fontSize: 12.5, fontWeight: 600, color: 'var(--n800)' }}>{label}</div>
      {rightSlot ? rightSlot : <div className="row" style={{ gap: 6 }}>
        <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--n900)', fontFamily: 'var(--mono)' }}>{value}</div>
        {onTap && <Icon name="chev-r" size={14} style={{ color: 'var(--n400)' }}/>}
      </div>}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// 3. Teacher — Add question (type picker → simple editor)
// ─────────────────────────────────────────────────────────────
function TeacherAddQuestionScreen({ nav }) {
  const [step, setStep] = useStateA('type'); // 'type' | 'edit'
  const [type, setType] = useStateA(null);
  const [text, setText] = useStateA('');
  const [opts, setOpts] = useStateA(['', '', '', '']);
  const [correct, setCorrect] = useStateA(null);
  const [marks, setMarks] = useStateA(2);

  const TYPES = [
    { id: 'mcq', lab: 'Multiple choice', sub: 'One correct answer · A/B/C/D', icon: 'circle' },
    { id: 'multi', lab: 'Multi-select', sub: 'Pick all that apply', icon: 'check' },
    { id: 'tf', lab: 'True / False', sub: 'Two-button binary choice', icon: 'check' },
    { id: 'numeric', lab: 'Numeric answer', sub: 'Single number, with tolerance', icon: 'flask' },
    { id: 'short', lab: 'Short answer', sub: '1–2 words; teacher graded if open', icon: 'edit' },
    { id: 'fill', lab: 'Fill-in-the-blank', sub: 'Inline blanks in a sentence', icon: 'edit' },
    { id: 'match', lab: 'Match the pairs', sub: 'Connect left to right', icon: 'clipboard' },
  ];

  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingBottom: 100 }}>
        <NavHeader title={step === 'type' ? 'Choose type' : (TYPES.find(t => t.id === type) || {}).lab || 'Edit question'} onBack={() => nav.pop()}/>

        {step === 'type' && (
          <>
            <div style={{ fontSize: 13, color: 'var(--n600)', marginTop: 14, lineHeight: 1.5 }}>
              Pick a question type. You can mix types in one assessment.
            </div>
            <div className="col" style={{ gap: 8, marginTop: 14 }}>
              {TYPES.map(tt => (
                <button key={tt.id} onClick={() => { setType(tt.id); setStep('edit'); }} className="card" style={{ padding: 14, textAlign: 'left' }}>
                  <div className="row" style={{ gap: 12 }}>
                    <div style={{ width: 40, height: 40, borderRadius: 11, background: 'var(--p50)', color: 'var(--p600)', display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name={tt.icon} size={18}/></div>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--n900)' }}>{tt.lab}</div>
                      <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 2 }}>{tt.sub}</div>
                    </div>
                    <Icon name="chev-r" size={16} style={{ color: 'var(--n400)' }}/>
                  </div>
                </button>
              ))}
            </div>
          </>
        )}

        {step === 'edit' && (
          <>
            <div className="card" style={{ padding: 16, marginTop: 14 }}>
              <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block' }}>Question</label>
              <textarea value={text} onChange={e => setText(e.target.value)} rows={3} placeholder="Type the question…" style={{
                width: '100%', marginTop: 6, padding: 10, border: '1px solid var(--n200)',
                borderRadius: 10, font: 'inherit', fontSize: 14, lineHeight: 1.5, outline: 'none',
                color: 'var(--n900)', resize: 'vertical',
              }}/>

              {(type === 'mcq' || type === 'multi') && (
                <div style={{ marginTop: 16 }}>
                  <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block', marginBottom: 8 }}>
                    Options · tap the radio to mark correct
                  </label>
                  {opts.map((o, i) => (
                    <div key={i} className="row" style={{ gap: 10, marginBottom: 8 }}>
                      <button onClick={() => setCorrect(i)} style={{
                        width: 22, height: 22, borderRadius: '50%',
                        border: '2px solid ' + (correct === i ? 'var(--success)' : 'var(--n300)'),
                        background: correct === i ? 'var(--success)' : '#fff',
                        display: 'grid', placeItems: 'center', flexShrink: 0, cursor: 'pointer',
                      }}>
                        {correct === i && <Icon name="check" size={11} style={{ color: '#fff' }}/>}
                      </button>
                      <input value={o} onChange={e => setOpts(os => os.map((x, j) => j === i ? e.target.value : x))} placeholder={'Option ' + String.fromCharCode(65 + i)} style={{
                        flex: 1, padding: '9px 12px', border: '1px solid var(--n200)',
                        borderRadius: 10, font: 'inherit', fontSize: 13, outline: 'none', color: 'var(--n900)',
                      }}/>
                    </div>
                  ))}
                </div>
              )}

              {type === 'tf' && (
                <div style={{ marginTop: 16 }}>
                  <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block', marginBottom: 8 }}>Correct answer</label>
                  <div className="row" style={{ gap: 8 }}>
                    {['True', 'False'].map((v, i) => (
                      <button key={i} onClick={() => setCorrect(i === 0)} style={{
                        flex: 1, padding: '12px 16px',
                        background: correct === (i === 0) ? 'var(--success-50)' : '#fff',
                        color: correct === (i === 0) ? 'var(--success)' : 'var(--n700)',
                        border: '1.5px solid ' + (correct === (i === 0) ? 'var(--success)' : 'var(--n200)'),
                        borderRadius: 12, fontSize: 14, fontWeight: 700, cursor: 'pointer',
                      }}>{v}</button>
                    ))}
                  </div>
                </div>
              )}

              {type === 'numeric' && (
                <div style={{ marginTop: 16 }}>
                  <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block', marginBottom: 6 }}>Correct value</label>
                  <input type="number" placeholder="e.g. 42" style={{
                    width: '100%', padding: '10px 12px', border: '1px solid var(--n200)',
                    borderRadius: 10, font: 'inherit', fontSize: 14, outline: 'none', color: 'var(--n900)',
                    fontFamily: 'var(--mono)', fontWeight: 700,
                  }}/>
                  <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block', marginTop: 14, marginBottom: 6 }}>Tolerance (±)</label>
                  <input type="number" defaultValue="0" style={{
                    width: '100%', padding: '10px 12px', border: '1px solid var(--n200)',
                    borderRadius: 10, font: 'inherit', fontSize: 14, outline: 'none', color: 'var(--n900)',
                    fontFamily: 'var(--mono)',
                  }}/>
                </div>
              )}

              {(type === 'short' || type === 'fill') && (
                <div style={{ marginTop: 16 }}>
                  <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, display: 'block', marginBottom: 6 }}>
                    Accepted answers
                  </label>
                  <input placeholder="comma-separated, e.g. chlorophyll, chlorophyl" style={{
                    width: '100%', padding: '10px 12px', border: '1px solid var(--n200)',
                    borderRadius: 10, font: 'inherit', fontSize: 13, outline: 'none', color: 'var(--n900)',
                  }}/>
                  <div className="row" style={{ marginTop: 10, gap: 8 }}>
                    <input type="checkbox" id="tg"/>
                    <label htmlFor="tg" style={{ fontSize: 12, color: 'var(--n700)', fontWeight: 600 }}>
                      Open response — I'll grade manually
                    </label>
                  </div>
                </div>
              )}

              {type === 'match' && (
                <div style={{ marginTop: 16 }}>
                  <div style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, marginBottom: 8 }}>Pairs</div>
                  {[1, 2, 3, 4].map(i => (
                    <div key={i} className="row" style={{ gap: 6, marginBottom: 6 }}>
                      <input placeholder={'Left ' + i} style={{ flex: 1, padding: '8px 10px', border: '1px solid var(--n200)', borderRadius: 9, font: 'inherit', fontSize: 12, outline: 'none' }}/>
                      <Icon name="arrow-right" size={14} style={{ color: 'var(--n400)' }}/>
                      <input placeholder={'Right ' + i} style={{ flex: 1, padding: '8px 10px', border: '1px solid var(--n200)', borderRadius: 9, font: 'inherit', fontSize: 12, outline: 'none' }}/>
                    </div>
                  ))}
                </div>
              )}

              <div style={{ marginTop: 18, paddingTop: 14, borderTop: '1px solid var(--n100)' }}>
                <div className="spread">
                  <label style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700 }}>Marks</label>
                  <div className="row" style={{ gap: 6 }}>
                    {[1, 2, 3, 5].map(m => (
                      <button key={m} onClick={() => setMarks(m)} style={{
                        width: 38, height: 32, borderRadius: 8,
                        background: marks === m ? 'var(--p600)' : '#fff',
                        color: marks === m ? '#fff' : 'var(--n700)',
                        border: '1px solid ' + (marks === m ? 'var(--p600)' : 'var(--n200)'),
                        fontSize: 12, fontWeight: 700, cursor: 'pointer', fontFamily: 'var(--mono)',
                      }}>{m}m</button>
                    ))}
                  </div>
                </div>
              </div>
            </div>

            <div className="card-flat" style={{ marginTop: 12, padding: 12, background: 'var(--info-50)', border: 'none' }}>
              <div className="row" style={{ gap: 10, alignItems: 'flex-start' }}>
                <Icon name="info" size={16} style={{ color: '#1E40AF', flexShrink: 0, marginTop: 1 }}/>
                <div style={{ fontSize: 11.5, color: '#1E3A8A', lineHeight: 1.5 }}>
                  Add an explanation or solution under the answer — students see it after they submit, even when answered incorrectly.
                </div>
              </div>
            </div>
          </>
        )}
      </div>

      {step === 'edit' && (
        <div style={{
          position: 'absolute', bottom: 0, left: 0, right: 0,
          background: '#fff', borderTop: '1px solid var(--n100)',
          padding: '12px 16px', display: 'flex', gap: 8,
        }}>
          <button onClick={() => setStep('type')} className="btn btn-outline" style={{ flex: 1, height: 46 }}>
            Change type
          </button>
          <button onClick={() => nav.pop()} className="btn" style={{ flex: 1.4, height: 46 }} disabled={!text}>
            <Icon name="check" size={14}/> Add to assessment
          </button>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// 4. Teacher — Submissions list for one assessment
// ─────────────────────────────────────────────────────────────
function TeacherSubmissionsScreen({ nav, params }) {
  const a = findTeacherAssessment(params && params.id) || TEACHER_ASSESSMENTS[2];
  const tt = a._t || { subs: [], total: 0, submitted: 0, graded: 0, pending: 0 };
  const [filter, setFilter] = useStateA('all');
  const [search, setSearch] = useStateA('');

  const list = useMemoA(() => {
    return (tt.subs || []).filter(s => {
      if (filter === 'submitted' && s.state === 'absent') return false;
      if (filter === 'pending' && s.state !== 'submitted') return false;
      if (filter === 'graded' && s.state !== 'graded') return false;
      if (filter === 'absent' && s.state !== 'absent') return false;
      if (search && !s.name.toLowerCase().includes(search.toLowerCase())) return false;
      return true;
    });
  }, [filter, search, tt.subs]);

  const filters = [
    { id: 'all', lab: 'All', n: tt.total },
    { id: 'pending', lab: 'To grade', n: tt.pending },
    { id: 'graded', lab: 'Graded', n: tt.graded },
    { id: 'absent', lab: 'Absent', n: (tt.subs || []).filter(s => s.state === 'absent').length },
  ];

  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingBottom: a.resultsMode === 'delayed' && tt.pending === 0 && tt.graded > 0 ? 100 : 24 }}>
        <NavHeader title="Submissions" onBack={() => nav.pop()}/>

        {/* Assessment context */}
        <div className="card" style={{ padding: 14, marginTop: 12 }}>
          <div className="row" style={{ gap: 12, alignItems: 'flex-start' }}>
            <div style={{ width: 40, height: 40, borderRadius: 11, background: a.bg, color: a.clr, display: 'grid', placeItems: 'center', flexShrink: 0 }}><Icon name={a.icon} size={18}/></div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)' }}>{a.title}</div>
              <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 2 }}>{a.sub} · Class {a.cls} · {a.qCount}q · {a.marks}m</div>
            </div>
            <TStatePill state={tt.state}/>
          </div>
        </div>

        {/* Stats strip */}
        <div className="card-flat" style={{ marginTop: 10, padding: 14, display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 10 }}>
          <div style={{ borderRight: '1px solid var(--n200)' }}>
            <div style={{ fontSize: 19, fontWeight: 800, color: 'var(--n900)', fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>
              {tt.submitted}<span style={{ fontSize: 13, color: 'var(--n500)', fontWeight: 600 }}>/{tt.total}</span>
            </div>
            <div style={{ fontSize: 10, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>Submitted</div>
          </div>
          <div style={{ borderRight: '1px solid var(--n200)' }}>
            <div style={{ fontSize: 19, fontWeight: 800, color: 'var(--warning)', fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>{tt.pending}</div>
            <div style={{ fontSize: 10, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>To grade</div>
          </div>
          <div>
            <div style={{ fontSize: 19, fontWeight: 800, color: 'var(--success)', fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>
              {tt.avgPct != null ? tt.avgPct + '%' : '—'}
            </div>
            <div style={{ fontSize: 10, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>Class avg</div>
          </div>
        </div>

        {/* Search */}
        <div className="row" style={{ marginTop: 14, padding: '10px 14px', background: 'var(--n50)', borderRadius: 12, gap: 8 }}>
          <Icon name="search" size={16} style={{ color: 'var(--n500)' }}/>
          <input value={search} onChange={e => setSearch(e.target.value)} placeholder="Search students…" style={{
            border: 0, outline: 0, width: '100%', font: 'inherit', fontSize: 13, color: 'var(--n800)', background: 'transparent',
          }}/>
        </div>

        {/* Filter chips */}
        <div style={{ display: 'flex', gap: 6, overflowX: 'auto', margin: '12px -20px 0', padding: '0 20px 4px' }}>
          {filters.map(f => {
            const isActive = filter === f.id;
            return (
              <button key={f.id} onClick={() => setFilter(f.id)} style={{
                flexShrink: 0, padding: '7px 12px',
                background: isActive ? 'var(--n900)' : 'var(--n50)',
                color: isActive ? '#fff' : 'var(--n700)',
                border: '1px solid ' + (isActive ? 'var(--n900)' : 'var(--n100)'),
                borderRadius: 999, fontSize: 12, fontWeight: 700, cursor: 'pointer', whiteSpace: 'nowrap',
                display: 'inline-flex', alignItems: 'center', gap: 6,
              }}>
                {f.lab}
                {f.n > 0 && <span style={{
                  fontSize: 10, fontWeight: 700, padding: '1px 6px',
                  background: isActive ? 'rgba(255,255,255,.2)' : 'var(--n100)',
                  color: isActive ? '#fff' : 'var(--n500)',
                  borderRadius: 999, fontFamily: 'var(--mono)',
                }}>{f.n}</span>}
              </button>
            );
          })}
        </div>

        {/* Submission rows */}
        <div className="col" style={{ gap: 6, marginTop: 14 }}>
          {list.length === 0 && (
            <div className="card-flat" style={{ padding: 24, textAlign: 'center' }}>
              <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>No matches</div>
              <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 4 }}>Try a different filter or search.</div>
            </div>
          )}
          {list.map(s => {
            const isAbsent = s.state === 'absent';
            const pct = s.scoreVal != null ? Math.round((s.scoreVal / (a.scoreMax || a.marks)) * 100) : null;
            const onTap = () => {
              if (isAbsent) return;
              if (s.state === 'submitted') nav.push('teachGradeSubmission', { aid: a.id, sid: s.id });
              else nav.push('teachGradeSubmission', { aid: a.id, sid: s.id, view: 'graded' });
            };
            return (
              <button key={s.id} onClick={onTap} disabled={isAbsent} className="row card" style={{ padding: 12, gap: 12, opacity: isAbsent ? 0.55 : 1 }}>
                <div className={`av av-44 ${s.clr}`} style={{ flexShrink: 0 }}>{s.initial}</div>
                <div style={{ flex: 1, minWidth: 0, textAlign: 'left' }}>
                  <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>{s.name}</div>
                  <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 1, fontFamily: 'var(--mono)' }}>
                    {isAbsent ? 'Absent' : s.state === 'submitted' ? `Submitted ${s.submittedOn} · ${s.timeMin}m` : `Graded · ${s.timeMin}m`}
                  </div>
                </div>
                {isAbsent ? (
                  <span style={{ fontSize: 10, fontWeight: 700, color: 'var(--n500)', fontFamily: 'var(--mono)', letterSpacing: '.06em' }}>—</span>
                ) : s.state === 'submitted' ? (
                  <span className="pill" style={{ background: 'var(--warning-50)', color: 'var(--warning)', fontSize: 10 }}>● Pending</span>
                ) : (
                  <div style={{ textAlign: 'right' }}>
                    <div style={{ fontSize: 14, fontWeight: 800, color: pct >= 80 ? 'var(--success)' : pct >= 60 ? 'var(--n900)' : 'var(--c600)', fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>
                      {s.scoreVal}<span style={{ fontSize: 10, color: 'var(--n500)', fontWeight: 600 }}>/{a.scoreMax || a.marks}</span>
                    </div>
                    <div style={{ fontSize: 9.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 600 }}>{pct}%</div>
                  </div>
                )}
                <Icon name="chev-r" size={14} style={{ color: 'var(--n400)' }}/>
              </button>
            );
          })}
        </div>

        <div style={{ height: 24 }}/>
      </div>

      {/* Footer CTA — Publish, only for delayed mode with grading complete */}
      {a.resultsMode === 'delayed' && tt.pending === 0 && tt.graded > 0 && tt.state !== 'published' && (
        <div style={{
          position: 'absolute', bottom: 0, left: 0, right: 0,
          background: '#fff', borderTop: '1px solid var(--n100)',
          padding: '12px 16px',
        }}>
          <button onClick={() => nav.push('teachPublishResults', { id: a.id })} className="btn" style={{ width: '100%', height: 48 }}>
            <Icon name="send" size={16}/> Publish results to {tt.graded} students
          </button>
        </div>
      )}
      {a.resultsMode === 'instant' && tt.state === 'live' && (
        <div style={{
          position: 'absolute', bottom: 0, left: 0, right: 0,
          background: '#fff', borderTop: '1px solid var(--n100)',
          padding: '12px 16px',
        }}>
          <button onClick={() => nav.push('teachClassAnalytics', { id: a.id })} className="btn btn-outline" style={{ width: '100%', height: 46 }}>
            <Icon name="target" size={14}/> View class analytics
          </button>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// 5. Teacher — Grade one submission
// ─────────────────────────────────────────────────────────────
function TeacherGradeSubmissionScreen({ nav, params }) {
  const a = findTeacherAssessment(params && params.aid) || TEACHER_ASSESSMENTS[2];
  const tt = a._t || { subs: [] };
  const sub = (tt.subs || []).find(s => s.id === (params && params.sid)) || (tt.subs || [])[0];
  const bank = banksFor(a);
  const isViewing = params && params.view === 'graded';

  // Mock student answers — for grading view, deterministically pick "their" answers
  const studentAns = useMemoA(() => {
    if (!sub) return [];
    const seed = sub.id.charCodeAt(1) + sub.id.charCodeAt(2);
    return bank.map((q, i) => {
      const r = ((Math.sin(seed + i * 7) * 1000) % 1 + 1) % 1;
      // ~70% chance correct
      if (q.type === 'mcq') return r > 0.3 ? q.correct : (q.correct + 1) % q.opts.length;
      if (q.type === 'multi') return r > 0.4 ? q.correct : [q.correct[0]];
      if (q.type === 'tf') return r > 0.25 ? q.correct : !q.correct;
      if (q.type === 'numeric') return r > 0.3 ? q.correct : q.correct + 1;
      if (q.type === 'short') return r > 0.4 && q.correct.length ? q.correct[0] :
        (q.teacherGraded ? 'It was a peaceful protest against the salt tax that became a turning point in the Indian freedom movement.' : 'unsure');
      if (q.type === 'fill') return Array.from({ length: q.blanks }, (_, b) =>
        r > 0.3 ? (Array.isArray(q.correct[b]) ? q.correct[b][0] : q.correct[b]) : 'wrong');
      if (q.type === 'match') return q.pairs.map((_, idx) => r > 0.5 ? idx : (idx + 1) % q.pairs.length);
      return null;
    });
  }, [sub && sub.id, a.id]);

  // Per-question grade state for teacher-graded items
  const [scores, setScores] = useStateA(() => {
    return bank.map((q, i) => {
      if (q.type === 'short' && q.teacherGraded) return null; // needs grading
      return isCorrectAnswer(q, studentAns[i]) ? (q.marks || 2) : 0;
    });
  });
  const [comments, setComments] = useStateA(() => bank.map(() => ''));
  const totalPossible = bank.reduce((s, q) => s + (q.marks || 2), 0);
  const totalScored = scores.reduce((s, x) => s + (x || 0), 0);
  const allGraded = scores.every(s => s !== null);
  const pct = Math.round((totalScored / totalPossible) * 100);

  if (!sub) return <div className="app"><div style={{ padding: 40, textAlign: 'center' }}>Submission not found.</div></div>;

  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingBottom: 100 }}>
        <NavHeader title="Grade submission" onBack={() => nav.pop()}/>

        {/* Student summary */}
        <div className="card" style={{ padding: 14, marginTop: 12 }}>
          <div className="row" style={{ gap: 12 }}>
            <div className={`av av-48 ${sub.clr}`}>{sub.initial}</div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)' }}>{sub.name}</div>
              <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 1, fontFamily: 'var(--mono)' }}>
                Class {a.cls} · Submitted {sub.submittedOn} · {sub.timeMin}m
              </div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <div style={{ fontSize: 22, fontWeight: 800, color: pct >= 80 ? 'var(--success)' : pct >= 60 ? 'var(--n900)' : 'var(--c600)', fontVariantNumeric: 'tabular-nums', letterSpacing: '-.03em' }}>
                {totalScored}<span style={{ fontSize: 13, color: 'var(--n500)', fontWeight: 600 }}>/{totalPossible}</span>
              </div>
              <div style={{ fontSize: 10.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 600, marginTop: 1 }}>
                {allGraded ? `${pct}%` : `${scores.filter(s => s !== null).length}/${bank.length} graded`}
              </div>
            </div>
          </div>
        </div>

        {/* Question-by-question */}
        <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
          Question-by-question · {bank.length}
        </div>

        <div className="col" style={{ gap: 10, marginTop: 8 }}>
          {bank.map((q, i) => {
            const ans = studentAns[i];
            const meta = TYPE_META[q.type] || { lab: q.type };
            const needsManual = q.type === 'short' && q.teacherGraded;
            const autoCorrect = !needsManual && isCorrectAnswer(q, ans);
            const score = scores[i];
            const isUnGraded = score === null;
            const stripeColor = isUnGraded ? 'var(--warning)' : autoCorrect || (score && score === (q.marks || 2)) ? 'var(--success)' : 'var(--c500)';

            return (
              <div key={i} className="card" style={{ padding: 0, overflow: 'hidden', position: 'relative' }}>
                <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: stripeColor }}/>
                <div style={{ padding: 14 }}>
                  <div className="spread" style={{ marginBottom: 8 }}>
                    <div className="row" style={{ gap: 8 }}>
                      <div style={{
                        width: 26, height: 26, borderRadius: 7, background: 'var(--n50)', color: 'var(--n700)',
                        display: 'grid', placeItems: 'center', fontSize: 10.5, fontWeight: 800, fontFamily: 'var(--mono)',
                      }}>Q{i + 1}</div>
                      <span style={{
                        fontSize: 9.5, fontWeight: 700, padding: '2px 7px',
                        background: 'var(--n100)', color: 'var(--n600)',
                        borderRadius: 5, letterSpacing: '.04em', fontFamily: 'var(--mono)',
                      }}>{meta.lab}</span>
                      {needsManual && !isUnGraded === false && isUnGraded && (
                        <span className="pill" style={{ background: 'var(--warning-50)', color: 'var(--warning)', fontSize: 10 }}>● Needs grading</span>
                      )}
                    </div>
                    <span style={{ fontSize: 10.5, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 700 }}>{q.marks || 2}m</span>
                  </div>

                  <div style={{ fontSize: 13, color: 'var(--n800)', lineHeight: 1.5, fontWeight: 600 }}>{q.q}</div>

                  {/* Student answer block */}
                  <div style={{ marginTop: 10, padding: 12, background: 'var(--n50)', borderRadius: 10 }}>
                    <div style={{ fontSize: 9.5, color: 'var(--n500)', fontWeight: 700, fontFamily: 'var(--mono)', letterSpacing: '.06em', marginBottom: 6 }}>
                      STUDENT'S ANSWER
                    </div>
                    {q.type === 'mcq' && (
                      <div style={{ fontSize: 13, color: 'var(--n900)', fontWeight: 700 }}>
                        {String.fromCharCode(65 + ans)}. {q.opts[ans]}
                      </div>
                    )}
                    {q.type === 'multi' && (
                      <div style={{ fontSize: 13, color: 'var(--n900)', fontWeight: 700 }}>
                        {(ans || []).map(idx => String.fromCharCode(65 + idx) + '. ' + q.opts[idx]).join(' · ')}
                      </div>
                    )}
                    {q.type === 'tf' && (
                      <div style={{ fontSize: 13, color: 'var(--n900)', fontWeight: 700 }}>{ans ? 'True' : 'False'}</div>
                    )}
                    {q.type === 'numeric' && (
                      <div style={{ fontSize: 14, color: 'var(--n900)', fontWeight: 800, fontFamily: 'var(--mono)' }}>{ans}</div>
                    )}
                    {(q.type === 'short' || q.type === 'fill') && (
                      <div style={{ fontSize: 13, color: 'var(--n900)', lineHeight: 1.5 }}>
                        {Array.isArray(ans) ? ans.join(' · ') : ans}
                      </div>
                    )}
                    {q.type === 'match' && (
                      <div className="col" style={{ gap: 4 }}>
                        {q.pairs.map((p, idx) => (
                          <div key={idx} style={{ fontSize: 12, color: 'var(--n900)' }}>
                            {p.left} → {q.pairs[ans[idx]] ? q.pairs[ans[idx]].right : '—'}
                          </div>
                        ))}
                      </div>
                    )}
                  </div>

                  {/* Correct answer for context (auto-graded) */}
                  {!needsManual && !autoCorrect && (
                    <div style={{ marginTop: 8, padding: '8px 12px', background: 'var(--success-50)', borderRadius: 8, fontSize: 11.5, color: 'var(--success)', fontWeight: 600 }}>
                      <span style={{ fontWeight: 800, marginRight: 6 }}>EXPECTED:</span>
                      {q.type === 'mcq' ? `${String.fromCharCode(65 + q.correct)}. ${q.opts[q.correct]}` :
                       q.type === 'multi' ? q.correct.map(idx => String.fromCharCode(65 + idx)).join(', ') :
                       q.type === 'tf' ? (q.correct ? 'True' : 'False') :
                       q.type === 'numeric' ? q.correct :
                       q.type === 'short' ? (q.correct[0] || '—') :
                       'See review'}
                    </div>
                  )}

                  {/* Grading control */}
                  {needsManual ? (
                    <div style={{ marginTop: 12 }}>
                      <div style={{ fontSize: 11, color: 'var(--n500)', fontWeight: 700, marginBottom: 6 }}>Award marks (out of {q.marks || 2})</div>
                      <div className="row" style={{ gap: 6 }}>
                        {Array.from({ length: (q.marks || 2) + 1 }, (_, m) => (
                          <button key={m} onClick={() => setScores(ss => ss.map((x, j) => j === i ? m : x))} disabled={isViewing} style={{
                            flex: 1, height: 38, borderRadius: 9,
                            background: score === m ? 'var(--p600)' : '#fff',
                            color: score === m ? '#fff' : 'var(--n700)',
                            border: '1px solid ' + (score === m ? 'var(--p600)' : 'var(--n200)'),
                            fontSize: 13, fontWeight: 700, cursor: isViewing ? 'default' : 'pointer', fontFamily: 'var(--mono)',
                          }}>{m}</button>
                        ))}
                      </div>
                      <div style={{ marginTop: 10 }}>
                        <textarea value={comments[i]} onChange={e => setComments(cs => cs.map((c, j) => j === i ? e.target.value : c))} rows={2} placeholder="Add a comment for the student (optional)…" disabled={isViewing} style={{
                          width: '100%', padding: 10, border: '1px solid var(--n200)',
                          borderRadius: 9, font: 'inherit', fontSize: 12, lineHeight: 1.5, outline: 'none',
                          color: 'var(--n900)', resize: 'vertical', background: '#fff',
                        }}/>
                      </div>
                    </div>
                  ) : (
                    <div className="row" style={{ marginTop: 10, gap: 6, justifyContent: 'space-between' }}>
                      <span style={{
                        fontSize: 11, fontWeight: 700,
                        color: autoCorrect ? 'var(--success)' : 'var(--c600)',
                        fontFamily: 'var(--mono)', letterSpacing: '.04em',
                      }}>
                        {autoCorrect ? '✓ AUTO · CORRECT' : '✗ AUTO · INCORRECT'}
                      </span>
                      <button onClick={() => setScores(ss => ss.map((x, j) => j === i ? (autoCorrect ? 0 : (q.marks || 2)) : x))} className="btn-ghost" style={{ fontSize: 11, color: 'var(--n500)' }}>
                        Override
                      </button>
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>

        <div style={{ height: 16 }}/>
      </div>

      {/* CTA */}
      {!isViewing && (
        <div style={{
          position: 'absolute', bottom: 0, left: 0, right: 0,
          background: '#fff', borderTop: '1px solid var(--n100)',
          padding: '12px 16px', display: 'flex', gap: 8,
        }}>
          <button onClick={() => nav.pop()} className="btn btn-outline" style={{ flex: 1, height: 46 }}>
            Save draft
          </button>
          <button onClick={() => nav.pop()} className="btn" style={{ flex: 1.4, height: 46 }} disabled={!allGraded}>
            <Icon name="check" size={14}/> Mark graded · {totalScored}/{totalPossible}
          </button>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// 6. Teacher — Class analytics for one assessment
// ─────────────────────────────────────────────────────────────
function TeacherClassAnalyticsScreen({ nav, params }) {
  const a = findTeacherAssessment(params && params.id) || TEACHER_ASSESSMENTS[2];
  const tt = a._t || { subs: [] };
  const bank = banksFor(a);
  const scoreMax = a.scoreMax || a.marks;

  const graded = (tt.subs || []).filter(s => s.state === 'graded' && s.scoreVal != null);
  const scores = graded.map(s => s.scoreVal);
  const avg = scores.length ? Math.round(scores.reduce((s, x) => s + x, 0) / scores.length) : 0;
  const top = scores.length ? Math.max(...scores) : 0;
  const low = scores.length ? Math.min(...scores) : 0;
  const median = scores.length ? scores.slice().sort((a, b) => a - b)[Math.floor(scores.length / 2)] : 0;

  // Distribution into 5 buckets
  const buckets = [
    { lab: '90+', min: 0.9, n: 0, clr: 'var(--success)' },
    { lab: '75–89', min: 0.75, n: 0, clr: '#3B82F6' },
    { lab: '60–74', min: 0.6, n: 0, clr: 'var(--warning)' },
    { lab: '40–59', min: 0.4, n: 0, clr: '#F97316' },
    { lab: '<40', min: 0, n: 0, clr: 'var(--c600)' },
  ];
  scores.forEach(s => {
    const pct = s / scoreMax;
    for (const b of buckets) { if (pct >= b.min) { b.n++; break; } }
  });
  const maxBucket = Math.max(1, ...buckets.map(b => b.n));

  // Per-question difficulty: % of graded students who got this right (mocked deterministically)
  const qDifficulty = bank.map((q, i) => {
    const r = ((Math.sin(a.id.charCodeAt(0) + i * 11) * 1000) % 1 + 1) % 1;
    const correctPct = Math.round(35 + r * 60); // 35–95%
    return { i, q, correctPct };
  });
  const hardest = [...qDifficulty].sort((x, y) => x.correctPct - y.correctPct).slice(0, 3);

  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingBottom: 24 }}>
        <NavHeader title="Class analytics" onBack={() => nav.pop()}/>

        {/* Header card */}
        <div className="card" style={{ padding: 14, marginTop: 12 }}>
          <div className="row" style={{ gap: 12 }}>
            <div style={{ width: 40, height: 40, borderRadius: 11, background: a.bg, color: a.clr, display: 'grid', placeItems: 'center' }}><Icon name={a.icon} size={18}/></div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, fontWeight: 800, color: 'var(--n900)' }}>{a.title}</div>
              <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 2 }}>{a.sub} · Class {a.cls} · {graded.length} graded</div>
            </div>
            <button onClick={() => {}} className="btn-ghost" style={{ width: 36, height: 36, padding: 0, display: 'grid', placeItems: 'center' }} title="Download CSV">
              <Icon name="download" size={16}/>
            </button>
          </div>
        </div>

        {/* 4-stat strip */}
        <div className="card-flat" style={{ marginTop: 10, padding: 14, display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 10 }}>
          {[
            { v: avg, l: 'Average', clr: 'var(--p600)' },
            { v: top, l: 'Top', clr: 'var(--success)' },
            { v: median, l: 'Median', clr: 'var(--n900)' },
            { v: low, l: 'Lowest', clr: 'var(--c600)' },
          ].map((s, i) => (
            <div key={i} style={{ textAlign: 'center', borderRight: i < 3 ? '1px solid var(--n200)' : 'none' }}>
              <div style={{ fontSize: 17, fontWeight: 800, color: s.clr, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>{s.v}<span style={{ fontSize: 10, color: 'var(--n500)', fontWeight: 600 }}>/{scoreMax}</span></div>
              <div style={{ fontSize: 10, color: 'var(--n500)', marginTop: 2, fontWeight: 600 }}>{s.l}</div>
            </div>
          ))}
        </div>

        {/* Distribution */}
        <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
          Score distribution · {graded.length} students
        </div>
        <div className="card" style={{ padding: 16, marginTop: 8 }}>
          <div className="col" style={{ gap: 10 }}>
            {buckets.map((b, i) => {
              const w = Math.round((b.n / maxBucket) * 100);
              return (
                <div key={i} className="row" style={{ gap: 10, alignItems: 'center' }}>
                  <div style={{ width: 56, fontSize: 11.5, color: 'var(--n700)', fontWeight: 700, fontFamily: 'var(--mono)' }}>{b.lab}%</div>
                  <div style={{ flex: 1, height: 22, background: 'var(--n50)', borderRadius: 6, overflow: 'hidden', position: 'relative' }}>
                    <div style={{ width: w + '%', height: '100%', background: b.clr, transition: 'width .6s ease' }}/>
                    {b.n > 0 && (
                      <span style={{
                        position: 'absolute', left: w >= 12 ? `calc(${w}% - 8px)` : `calc(${w}% + 6px)`,
                        top: '50%', transform: 'translateY(-50%)',
                        fontSize: 11, fontWeight: 800, color: w >= 12 ? '#fff' : 'var(--n700)',
                        fontFamily: 'var(--mono)',
                      }}>{b.n}</span>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* Question difficulty — hardest first */}
        <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
          Toughest questions
        </div>
        <div className="col" style={{ gap: 8, marginTop: 8 }}>
          {hardest.map(({ i, q, correctPct }) => (
            <div key={i} className="card" style={{ padding: 12 }}>
              <div className="row" style={{ gap: 10, alignItems: 'flex-start' }}>
                <div style={{
                  width: 32, height: 32, borderRadius: 8, background: 'var(--c50)', color: 'var(--c600)',
                  display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 800, fontFamily: 'var(--mono)', flexShrink: 0,
                }}>Q{i + 1}</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--n900)', lineHeight: 1.4, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{q.q}</div>
                  <div className="row" style={{ gap: 8, marginTop: 6, alignItems: 'center' }}>
                    <div style={{ flex: 1, height: 5, background: 'var(--n100)', borderRadius: 999, overflow: 'hidden' }}>
                      <div style={{ width: correctPct + '%', height: '100%', background: correctPct < 50 ? 'var(--c600)' : 'var(--warning)' }}/>
                    </div>
                    <span style={{ fontSize: 11, fontWeight: 800, color: correctPct < 50 ? 'var(--c600)' : 'var(--warning)', fontFamily: 'var(--mono)', letterSpacing: '-.02em' }}>{correctPct}%</span>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>

        {/* All questions difficulty */}
        <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
          All questions · % correct
        </div>
        <div className="card" style={{ padding: 14, marginTop: 8 }}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 8 }}>
            {qDifficulty.map(({ i, correctPct }) => {
              const tone = correctPct >= 75 ? 'var(--success)' : correctPct >= 50 ? 'var(--warning)' : 'var(--c600)';
              const bg = correctPct >= 75 ? 'var(--success-50)' : correctPct >= 50 ? 'var(--warning-50)' : 'var(--c50)';
              return (
                <div key={i} style={{ textAlign: 'center', padding: 10, background: bg, borderRadius: 8 }}>
                  <div style={{ fontSize: 9.5, color: tone, fontFamily: 'var(--mono)', fontWeight: 800, letterSpacing: '.06em' }}>Q{i + 1}</div>
                  <div style={{ fontSize: 14, fontWeight: 800, color: tone, marginTop: 2, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em' }}>{correctPct}%</div>
                </div>
              );
            })}
          </div>
        </div>

        <div style={{ height: 32 }}/>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// 7. Teacher — Publish results confirmation
// ─────────────────────────────────────────────────────────────
function TeacherPublishResultsScreen({ nav, params }) {
  const a = findTeacherAssessment(params && params.id) || TEACHER_ASSESSMENTS[2];
  const tt = a._t || { graded: 0, total: 0 };
  const [notify, setNotify] = useStateA(true);
  const [showExpl, setShowExpl] = useStateA(true);
  const [allowRetake, setAllowRetake] = useStateA(false);
  const [done, setDone] = useStateA(false);

  if (done) {
    return (
      <div className="app screen-in">
        <StatusBar/>
        <div className="app-body" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', minHeight: '70vh' }}>
          <div style={{ width: 80, height: 80, borderRadius: '50%', background: 'var(--success-50)', color: 'var(--success)', display: 'grid', placeItems: 'center', marginBottom: 20 }}>
            <Icon name="check" size={40}/>
          </div>
          <div style={{ fontSize: 22, fontWeight: 800, color: 'var(--n900)', textAlign: 'center', letterSpacing: '-.02em' }}>Results published</div>
          <div style={{ fontSize: 13, color: 'var(--n500)', marginTop: 8, textAlign: 'center', maxWidth: 280 }}>
            All {tt.graded} students can now see their score and review.
            {notify && ' Parents have been notified.'}
          </div>
          <div className="col" style={{ gap: 10, width: '100%', marginTop: 32, padding: '0 16px' }}>
            <button onClick={() => nav.replace('teachClassAnalytics', { id: a.id })} className="btn" style={{ width: '100%', height: 48 }}>
              <Icon name="target" size={16}/> View class analytics
            </button>
            <button onClick={() => nav.replace('teachAssessments')} className="btn btn-outline" style={{ width: '100%', height: 46 }}>
              Back to assessments
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingBottom: 100 }}>
        <NavHeader title="Publish results" onBack={() => nav.pop()}/>

        {/* Hero */}
        <div className="card" style={{ padding: 18, marginTop: 14, background: 'var(--p50)', border: '1px solid var(--p100)' }}>
          <div style={{ width: 44, height: 44, borderRadius: 12, background: 'var(--p600)', color: '#fff', display: 'grid', placeItems: 'center' }}>
            <Icon name="send" size={20}/>
          </div>
          <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--n900)', marginTop: 12, letterSpacing: '-.02em' }}>
            Ready to publish?
          </div>
          <div style={{ fontSize: 12.5, color: 'var(--n600)', marginTop: 4, lineHeight: 1.5 }}>
            {tt.graded} of {tt.total} students will see their results. This action can't be reversed.
          </div>
        </div>

        {/* Assessment summary */}
        <div className="card" style={{ padding: 14, marginTop: 12 }}>
          <div className="row" style={{ gap: 12 }}>
            <div style={{ width: 36, height: 36, borderRadius: 10, background: a.bg, color: a.clr, display: 'grid', placeItems: 'center' }}><Icon name={a.icon} size={16}/></div>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--n900)' }}>{a.title}</div>
              <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 1 }}>{a.sub} · Class {a.cls} · Avg {tt.avgPct}%</div>
            </div>
          </div>
        </div>

        {/* Options */}
        <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
          Publishing options
        </div>
        <div className="card" style={{ padding: 0, marginTop: 8 }}>
          <ToggleRow label="Notify parents" sub="Sends push + email" icon="bell" value={notify} onChange={setNotify}/>
          <ToggleRow label="Show explanations" sub="Students see why each answer is correct" icon="info" value={showExpl} onChange={setShowExpl}/>
          <ToggleRow label="Allow practice mode" sub="Students can retry, not for marks" icon="zap" value={allowRetake} onChange={setAllowRetake} last/>
        </div>

        {/* Warning */}
        <div className="card-flat" style={{ marginTop: 16, padding: 14, background: 'var(--warning-50)', border: '1px solid #FED7AA' }}>
          <div className="row" style={{ gap: 10, alignItems: 'flex-start' }}>
            <Icon name="info" size={16} style={{ color: 'var(--warning)', flexShrink: 0, marginTop: 1 }}/>
            <div style={{ fontSize: 11.5, color: '#9A3412', lineHeight: 1.5 }}>
              <span style={{ fontWeight: 800 }}>Heads up.</span> Once published, students get a notification immediately and the result is locked. Re-grading after publish requires a manual override per student.
            </div>
          </div>
        </div>
      </div>

      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0,
        background: '#fff', borderTop: '1px solid var(--n100)',
        padding: '12px 16px', display: 'flex', gap: 8,
      }}>
        <button onClick={() => nav.pop()} className="btn btn-outline" style={{ flex: 1, height: 46 }}>
          Not yet
        </button>
        <button onClick={() => setDone(true)} className="btn" style={{ flex: 1.4, height: 46 }}>
          <Icon name="send" size={14}/> Publish to {tt.graded} students
        </button>
      </div>
    </div>
  );
}

// Helper: settings toggle row
function ToggleRow({ label, sub, icon, value, onChange, last }) {
  return (
    <div className="row" style={{
      padding: '14px 16px', gap: 12,
      borderBottom: last ? 'none' : '1px solid var(--n100)',
    }}>
      <div style={{ width: 32, height: 32, borderRadius: 8, background: 'var(--n50)', color: 'var(--n600)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
        <Icon name={icon} size={14}/>
      </div>
      <div style={{ flex: 1 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>{label}</div>
        {sub && <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 1 }}>{sub}</div>}
      </div>
      <button onClick={() => onChange(!value)} style={{
        width: 44, height: 26, borderRadius: 13,
        background: value ? 'var(--success)' : 'var(--n200)',
        position: 'relative', border: 'none', cursor: 'pointer', flexShrink: 0,
        transition: 'background .2s',
      }}>
        <div style={{
          position: 'absolute', top: 3, left: value ? 21 : 3,
          width: 20, height: 20, borderRadius: '50%', background: '#fff',
          transition: 'left .2s', boxShadow: '0 1px 3px rgba(0,0,0,.2)',
        }}/>
      </button>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Export
// ─────────────────────────────────────────────────────────────
// ─────────────────────────────────────────────────────────────
// 8. Teacher — AI Generate questions (form → generating → results)
// ─────────────────────────────────────────────────────────────

// Bank picker for AI generation, returns a deterministic set seeded by inputs
function _aiBankFor(sub) {
  if (sub === 'Mathematics') return BANK_LINEAR.concat(BANK_MENTAL);
  if (sub === 'Science') return BANK_PHOTO;
  if (sub === 'English') return BANK_GRAMMAR;
  if (sub === 'Social Studies') return BANK_CIVICS;
  if (sub === 'History') return BANK_HISTORY;
  return BANK_LINEAR;
}

// Quick-prompt chips by subject — give the teacher a starting point
const AI_QUICK_PROMPTS = {
  Mathematics: ['Focus on word problems', 'Real-world examples', 'Mix easy with one tricky', 'Reduce calculation, more concept'],
  Science: ['Use diagrams in stems', 'Focus on definitions', 'Add experiment-based Qs', 'Cover entire chapter evenly'],
  English: ['Mix tenses & vocabulary', 'Add reading comprehension', 'Focus on common errors', 'Use Indian-English context'],
  'Social Studies': ['Cover key dates', 'Compare events', 'Map-based questions', 'Focus on causes & effects'],
  History: ['Chronology questions', 'Cause and consequence', 'Source-based interpretation', 'Compare two periods'],
};

const QTYPE_OPTIONS = [
  { id: 'mcq', lab: 'Multiple choice', short: 'MCQ', icon: 'circle' },
  { id: 'multi', lab: 'Multi-select', short: 'Multi', icon: 'check' },
  { id: 'tf', lab: 'True / False', short: 'T/F', icon: 'check' },
  { id: 'numeric', lab: 'Numeric', short: 'Numeric', icon: 'flask' },
  { id: 'short', lab: 'Short answer', short: 'Short', icon: 'edit' },
  { id: 'fill', lab: 'Fill blanks', short: 'Fill', icon: 'edit' },
  { id: 'match', lab: 'Match pairs', short: 'Match', icon: 'clipboard' },
];

// Difficulty colour map
const DIFF_META = {
  easy:    { lab: 'Easy',    bg: 'var(--success-50)', clr: 'var(--success)' },
  medium:  { lab: 'Medium',  bg: 'var(--info-50)',    clr: '#1E40AF' },
  hard:    { lab: 'Hard',    bg: 'var(--warning-50)', clr: 'var(--warning)' },
  mixed:   { lab: 'Mixed',   bg: 'var(--p50)',        clr: 'var(--p600)' },
};

function TeacherAIGenerateScreen({ nav, params }) {
  const ctx = params || {};
  const sub = ctx.sub || 'Mathematics';
  const cls = ctx.cls || '8-B';
  const title = ctx.title || '';

  const [step, setStep] = useStateA('form');
  const [source, setSource] = useStateA('context');
  const [files, setFiles] = useStateA([]);
  const [instructions, setInstructions] = useStateA('');
  const [count, setCount] = useStateA(8);
  const [typesSel, setTypesSel] = useStateA(['mcq', 'tf', 'short']);
  const [difficulty, setDifficulty] = useStateA('mixed');
  const [language, setLanguage] = useStateA('en');

  // Generation state
  const [genStage, setGenStage] = useStateA(0);
  const [generated, setGenerated] = useStateA([]);
  const [selected, setSelected] = useStateA(() => new Set());
  const [regenIdx, setRegenIdx] = useStateA(null);

  const allowedTypes = typesSel.length ? typesSel : QTYPE_OPTIONS.map(t => t.id);
  const validToGenerate = source === 'document' ? files.length > 0 : !!sub;
  const promptChips = AI_QUICK_PROMPTS[sub] || AI_QUICK_PROMPTS.Mathematics;

  // Toggle a question type
  const toggleType = (id) => {
    setTypesSel(prev => prev.includes(id) ? prev.filter(t => t !== id) : [...prev, id]);
  };

  // Add fake-uploaded file (prototype: generate plausible metadata)
  const addFile = (kind) => {
    const stamps = {
      pdf:  { ext: 'pdf', size: '2.4 MB', pages: 14, name: 'Chapter ' + (Math.floor(Math.random() * 5) + 1) + ' — ' + sub + '.pdf' },
      docx: { ext: 'docx', size: '486 KB', pages: 6,  name: 'Notes-' + sub.toLowerCase() + '.docx' },
      img:  { ext: 'jpg', size: '1.2 MB', pages: 1,  name: 'IMG-board-' + Math.floor(Math.random() * 9000 + 1000) + '.jpg' },
    };
    setFiles(prev => [...prev, stamps[kind] || stamps.pdf]);
  };

  // Generate (mocked) — pull from bank, augment with AI markers
  const runGenerate = () => {
    setStep('generating');
    setGenStage(0);
    const stages = [
      source === 'document' ? 'Reading uploaded document…' : 'Reading assessment context…',
      'Drafting ' + count + ' questions…',
      'Tuning for Class ' + cls + ' level…',
      'Finalising answers and explanations…',
    ];
    let s = 0;
    const tick = setInterval(() => {
      s++;
      if (s >= stages.length) {
        clearInterval(tick);
        // Build the generated set
        const bank = _aiBankFor(sub);
        const filtered = bank.filter(q => allowedTypes.includes(q.type));
        const pool = filtered.length > 0 ? filtered : bank;
        const pick = [];
        for (let i = 0; i < count; i++) {
          const q = pool[i % pool.length];
          const diff = difficulty === 'mixed'
            ? ['easy', 'medium', 'hard'][i % 3]
            : difficulty;
          pick.push(Object.assign({}, q, {
            _aiId: 'g' + i + '-' + Date.now(),
            _aiDifficulty: diff,
            marks: diff === 'easy' ? 1 : diff === 'hard' ? 3 : 2,
            _aiSource: source === 'document' && files[0] ? files[0].name : null,
          }));
        }
        setGenerated(pick);
        setSelected(new Set(pick.map((_, i) => i)));
        setStep('results');
      } else {
        setGenStage(s);
      }
    }, 700);
  };

  // Regenerate one question
  const regenerateOne = (i) => {
    setRegenIdx(i);
    setTimeout(() => {
      const bank = _aiBankFor(sub);
      const filtered = bank.filter(q => allowedTypes.includes(q.type));
      const pool = filtered.length > 0 ? filtered : bank;
      const newQ = pool[(i + Date.now()) % pool.length];
      const cur = generated[i];
      setGenerated(prev => prev.map((q, j) => j === i ? Object.assign({}, newQ, {
        _aiId: 'g' + i + '-r-' + Date.now(),
        _aiDifficulty: cur._aiDifficulty,
        marks: cur.marks,
        _aiSource: cur._aiSource,
      }) : q));
      setRegenIdx(null);
    }, 900);
  };

  // Toggle selection
  const toggleSel = (i) => {
    setSelected(prev => {
      const next = new Set(prev);
      if (next.has(i)) next.delete(i);
      else next.add(i);
      return next;
    });
  };
  const allSelected = generated.length > 0 && selected.size === generated.length;
  const noneSelected = selected.size === 0;

  // Confirm: stage picked questions to window, pop back to create
  const confirmAdd = () => {
    const picks = generated.filter((_, i) => selected.has(i)).map(q => {
      const clean = Object.assign({}, q);
      delete clean._aiId;
      delete clean._aiDifficulty;
      delete clean._aiSource;
      return clean;
    });
    window.__aiPickedQuestions = picks;
    nav.pop();
  };

  // ───────── FORM STEP ─────────
  if (step === 'form') {
    const SUB_META = {
      Mathematics: { ic: 'flask', clr: 'var(--p600)', bg: 'var(--p50)' },
      Science: { ic: 'flask', clr: 'var(--success)', bg: 'var(--success-50)' },
      English: { ic: 'book-open', clr: '#1E40AF', bg: 'var(--info-50)' },
      'Social Studies': { ic: 'globe', clr: 'var(--c600)', bg: 'var(--c50)' },
      History: { ic: 'globe', clr: 'var(--warning)', bg: 'var(--warning-50)' },
    };
    const sm = SUB_META[sub] || SUB_META.Mathematics;

    return (
      <div className="app screen-in">
        <StatusBar/>
        <div className="app-body" style={{ paddingBottom: 100 }}>
          <NavHeader title="Generate with AI" onBack={() => nav.pop()}/>

          {/* AI hero */}
          <div className="card" style={{
            padding: 16, marginTop: 14, overflow: 'hidden', position: 'relative',
            background: 'linear-gradient(135deg, var(--p50) 0%, var(--c50) 100%)',
            border: '1px solid var(--p100)',
          }}>
            <div className="row" style={{ gap: 12, alignItems: 'flex-start' }}>
              <div style={{
                width: 44, height: 44, borderRadius: 12,
                background: 'linear-gradient(135deg, var(--p600), var(--c600))',
                color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0,
              }}><Icon name="sparkles" size={22}/></div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)' }}>Draft questions in seconds</div>
                <div style={{ fontSize: 11.5, color: 'var(--n600)', marginTop: 2, lineHeight: 1.5 }}>
                  AI uses your assessment context — or any document you upload — to draft questions you review before adding.
                </div>
              </div>
            </div>
          </div>

          {/* SOURCE */}
          <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
            Source
          </div>
          <div className="row" style={{ gap: 8, marginTop: 8 }}>
            <button onClick={() => setSource('context')} style={{
              flex: 1, padding: '12px 12px', borderRadius: 12, cursor: 'pointer',
              border: '1.5px solid ' + (source === 'context' ? 'var(--p600)' : 'var(--n200)'),
              background: source === 'context' ? 'var(--p50)' : '#fff', textAlign: 'left',
            }}>
              <div className="row" style={{ gap: 8, alignItems: 'center' }}>
                <Icon name="target" size={14} style={{ color: source === 'context' ? 'var(--p600)' : 'var(--n500)' }}/>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: source === 'context' ? 'var(--p700)' : 'var(--n800)' }}>Assessment context</div>
              </div>
              <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 4, lineHeight: 1.4 }}>
                Subject · class · title
              </div>
            </button>
            <button onClick={() => setSource('document')} style={{
              flex: 1, padding: '12px 12px', borderRadius: 12, cursor: 'pointer',
              border: '1.5px solid ' + (source === 'document' ? 'var(--p600)' : 'var(--n200)'),
              background: source === 'document' ? 'var(--p50)' : '#fff', textAlign: 'left',
            }}>
              <div className="row" style={{ gap: 8, alignItems: 'center' }}>
                <Icon name="paperclip" size={14} style={{ color: source === 'document' ? 'var(--p600)' : 'var(--n500)' }}/>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: source === 'document' ? 'var(--p700)' : 'var(--n800)' }}>Upload document</div>
              </div>
              <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 4, lineHeight: 1.4 }}>
                PDF · DOCX · image
              </div>
            </button>
          </div>

          {/* Source body */}
          {source === 'context' && (
            <div className="card" style={{ padding: 14, marginTop: 8 }}>
              <div style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--n500)', fontFamily: 'var(--mono)', letterSpacing: '.06em' }}>
                AI WILL USE
              </div>
              <div className="col" style={{ gap: 10, marginTop: 10 }}>
                <div className="row" style={{ gap: 10 }}>
                  <div style={{ width: 30, height: 30, borderRadius: 8, background: sm.bg, color: sm.clr, display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                    <Icon name={sm.ic} size={14}/>
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 10.5, color: 'var(--n500)' }}>Subject</div>
                    <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>{sub}</div>
                  </div>
                </div>
                <div className="row" style={{ gap: 10 }}>
                  <div style={{ width: 30, height: 30, borderRadius: 8, background: 'var(--n50)', color: 'var(--n600)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                    <Icon name="users" size={14}/>
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 10.5, color: 'var(--n500)' }}>Class</div>
                    <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', fontFamily: 'var(--mono)' }}>Class {cls}</div>
                  </div>
                </div>
                {title && (
                  <div className="row" style={{ gap: 10 }}>
                    <div style={{ width: 30, height: 30, borderRadius: 8, background: 'var(--n50)', color: 'var(--n600)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                      <Icon name="edit" size={14}/>
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 10.5, color: 'var(--n500)' }}>Title / topic</div>
                      <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)' }}>{title}</div>
                    </div>
                  </div>
                )}
              </div>
            </div>
          )}

          {source === 'document' && (
            <>
              <div className="card-flat" style={{
                marginTop: 8, padding: 22, textAlign: 'center',
                border: '1.5px dashed var(--n200)', background: 'var(--n50)',
              }}>
                <div style={{
                  width: 48, height: 48, borderRadius: 12, margin: '0 auto',
                  background: '#fff', color: 'var(--p600)', display: 'grid', placeItems: 'center',
                  border: '1px solid var(--n100)',
                }}><Icon name="paperclip" size={22}/></div>
                <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--n900)', marginTop: 10 }}>
                  Add chapter or notes
                </div>
                <div style={{ fontSize: 11, color: 'var(--n500)', marginTop: 4, lineHeight: 1.5 }}>
                  AI reads the content and generates aligned questions.
                </div>
                <div className="row" style={{ gap: 6, marginTop: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
                  <button onClick={() => addFile('pdf')} className="btn btn-outline" style={{ height: 34, fontSize: 11.5 }}>
                    <Icon name="document" size={13}/> PDF
                  </button>
                  <button onClick={() => addFile('docx')} className="btn btn-outline" style={{ height: 34, fontSize: 11.5 }}>
                    <Icon name="document" size={13}/> DOCX
                  </button>
                  <button onClick={() => addFile('img')} className="btn btn-outline" style={{ height: 34, fontSize: 11.5 }}>
                    <Icon name="camera" size={13}/> Image
                  </button>
                </div>
                <div style={{ fontSize: 10, color: 'var(--n400)', marginTop: 10, fontFamily: 'var(--mono)' }}>
                  MAX 50 MB · STORED 7 DAYS
                </div>
              </div>

              {files.length > 0 && (
                <div className="col" style={{ gap: 6, marginTop: 8 }}>
                  {files.map((f, i) => (
                    <div key={i} className="card" style={{ padding: 12 }}>
                      <div className="row" style={{ gap: 10, alignItems: 'center' }}>
                        <div style={{
                          width: 36, height: 36, borderRadius: 9,
                          background: f.ext === 'jpg' ? 'var(--c50)' : 'var(--info-50)',
                          color: f.ext === 'jpg' ? 'var(--c600)' : '#1E40AF',
                          display: 'grid', placeItems: 'center', flexShrink: 0,
                          fontSize: 9.5, fontWeight: 800, fontFamily: 'var(--mono)', letterSpacing: '.04em',
                        }}>{f.ext.toUpperCase()}</div>
                        <div style={{ flex: 1, minWidth: 0 }}>
                          <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--n900)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                            {f.name}
                          </div>
                          <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 2, fontFamily: 'var(--mono)' }}>
                            {f.size} · {f.pages} {f.pages === 1 ? 'page' : 'pages'}
                          </div>
                        </div>
                        <button onClick={() => setFiles(prev => prev.filter((_, j) => j !== i))} style={{
                          width: 28, height: 28, borderRadius: 8, background: 'var(--n50)', color: 'var(--n500)',
                          display: 'grid', placeItems: 'center', border: 'none', cursor: 'pointer',
                        }}><Icon name="x" size={12}/></button>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </>
          )}

          {/* INSTRUCTIONS */}
          <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
            Instructions <span style={{ color: 'var(--n400)', fontWeight: 600 }}>· optional</span>
          </div>
          <div className="card" style={{ padding: 14, marginTop: 8 }}>
            <textarea
              value={instructions}
              onChange={e => setInstructions(e.target.value)}
              rows={3}
              placeholder={'e.g. focus on word problems, use real-world examples, avoid trick questions…'}
              style={{
                width: '100%', padding: 10, border: '1px solid var(--n200)',
                borderRadius: 10, font: 'inherit', fontSize: 13, lineHeight: 1.5, outline: 'none',
                color: 'var(--n900)', resize: 'vertical', background: '#fff',
              }}
            />
            <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 10, fontFamily: 'var(--mono)', letterSpacing: '.06em' }}>
              QUICK PROMPTS
            </div>
            <div className="row" style={{ gap: 6, flexWrap: 'wrap', marginTop: 6 }}>
              {promptChips.map((p) => (
                <button key={p} onClick={() => setInstructions(s => s ? s + ' · ' + p : p)} style={{
                  padding: '6px 10px', borderRadius: 8,
                  background: 'var(--p50)', color: 'var(--p700)',
                  border: '1px solid var(--p100)', fontSize: 11, fontWeight: 600, cursor: 'pointer',
                }}>+ {p}</button>
              ))}
            </div>
          </div>

          {/* OPTIONS */}
          <div style={{ fontSize: 11, fontWeight: 800, color: 'var(--n500)', textTransform: 'uppercase', letterSpacing: '.08em', fontFamily: 'var(--mono)', marginTop: 22 }}>
            Options
          </div>
          <div className="card" style={{ padding: 0, marginTop: 8 }}>
            {/* count */}
            <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--n100)' }}>
              <div className="spread">
                <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--n800)' }}>Number of questions</div>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--p600)', fontFamily: 'var(--mono)' }}>{count}</div>
              </div>
              <div className="row" style={{ gap: 6, marginTop: 8 }}>
                {[5, 8, 10, 15, 20].map(n => (
                  <button key={n} onClick={() => setCount(n)} style={{
                    flex: 1, padding: '8px 0', borderRadius: 8,
                    background: count === n ? 'var(--p600)' : '#fff',
                    color: count === n ? '#fff' : 'var(--n700)',
                    border: '1px solid ' + (count === n ? 'var(--p600)' : 'var(--n200)'),
                    fontSize: 12, fontWeight: 700, cursor: 'pointer', fontFamily: 'var(--mono)',
                  }}>{n}</button>
                ))}
              </div>
            </div>

            {/* types */}
            <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--n100)' }}>
              <div className="spread">
                <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--n800)' }}>Question types</div>
                <button onClick={() => setTypesSel(typesSel.length === QTYPE_OPTIONS.length ? [] : QTYPE_OPTIONS.map(t => t.id))} style={{
                  fontSize: 11, fontWeight: 700, color: 'var(--p600)', background: 'transparent', border: 'none', cursor: 'pointer', padding: 0,
                }}>{typesSel.length === QTYPE_OPTIONS.length ? 'Clear' : 'All types'}</button>
              </div>
              <div className="row" style={{ gap: 6, marginTop: 8, flexWrap: 'wrap' }}>
                {QTYPE_OPTIONS.map(t => {
                  const isOn = typesSel.includes(t.id);
                  return (
                    <button key={t.id} onClick={() => toggleType(t.id)} style={{
                      padding: '6px 10px', borderRadius: 8, cursor: 'pointer',
                      background: isOn ? 'var(--p50)' : '#fff',
                      color: isOn ? 'var(--p700)' : 'var(--n600)',
                      border: '1px solid ' + (isOn ? 'var(--p600)' : 'var(--n200)'),
                      fontSize: 11, fontWeight: 700, display: 'inline-flex', alignItems: 'center', gap: 4,
                    }}>
                      {isOn && <Icon name="check" size={11}/>} {t.short}
                    </button>
                  );
                })}
              </div>
            </div>

            {/* difficulty */}
            <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--n100)' }}>
              <div className="spread">
                <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--n800)' }}>Difficulty</div>
              </div>
              <div className="row" style={{ gap: 6, marginTop: 8 }}>
                {Object.keys(DIFF_META).map(d => {
                  const m = DIFF_META[d];
                  const isOn = difficulty === d;
                  return (
                    <button key={d} onClick={() => setDifficulty(d)} style={{
                      flex: 1, padding: '8px 0', borderRadius: 8,
                      background: isOn ? m.bg : '#fff',
                      color: isOn ? m.clr : 'var(--n600)',
                      border: '1px solid ' + (isOn ? m.clr : 'var(--n200)'),
                      fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
                    }}>{m.lab}</button>
                  );
                })}
              </div>
            </div>

            {/* language */}
            <div style={{ padding: '14px 16px' }}>
              <div className="spread">
                <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--n800)' }}>Language</div>
              </div>
              <div className="row" style={{ gap: 6, marginTop: 8 }}>
                {[
                  { id: 'en', lab: 'English' },
                  { id: 'hi', lab: 'हिंदी' },
                  { id: 'te', lab: 'తెలుగు' },
                ].map(L => (
                  <button key={L.id} onClick={() => setLanguage(L.id)} style={{
                    flex: 1, padding: '8px 0', borderRadius: 8,
                    background: language === L.id ? 'var(--p600)' : '#fff',
                    color: language === L.id ? '#fff' : 'var(--n700)',
                    border: '1px solid ' + (language === L.id ? 'var(--p600)' : 'var(--n200)'),
                    fontSize: 12, fontWeight: 700, cursor: 'pointer',
                  }}>{L.lab}</button>
                ))}
              </div>
            </div>
          </div>

          {/* Disclaimer */}
          <div className="card-flat" style={{ marginTop: 14, padding: 12, background: 'var(--info-50)', border: 'none' }}>
            <div className="row" style={{ gap: 10, alignItems: 'flex-start' }}>
              <Icon name="info" size={16} style={{ color: '#1E40AF', flexShrink: 0, marginTop: 1 }}/>
              <div style={{ fontSize: 11, color: '#1E3A8A', lineHeight: 1.5 }}>
                AI generation uses your school's configured plan. Generations may take up to 30 seconds. Always review questions before publishing — AI can make mistakes.
              </div>
            </div>
          </div>
        </div>

        {/* Bottom CTA */}
        <div style={{
          position: 'absolute', bottom: 0, left: 0, right: 0,
          background: '#fff', borderTop: '1px solid var(--n100)',
          padding: '12px 16px', display: 'flex', gap: 8,
        }}>
          <button
            onClick={runGenerate}
            disabled={!validToGenerate}
            className="btn"
            style={{
              flex: 1, height: 48, fontSize: 14, fontWeight: 700,
              background: 'linear-gradient(135deg, var(--p600), var(--c600))',
              color: '#fff', border: 'none',
            }}
          >
            <Icon name="sparkles" size={16}/> Generate {count} questions
          </button>
        </div>
      </div>
    );
  }

  // ───────── GENERATING STEP ─────────
  if (step === 'generating') {
    const stages = [
      source === 'document' ? 'Reading uploaded document…' : 'Reading assessment context…',
      'Drafting ' + count + ' questions…',
      'Tuning for Class ' + cls + ' level…',
      'Finalising answers and explanations…',
    ];
    const progress = ((genStage + 1) / stages.length) * 100;
    return (
      <div className="app screen-in">
        <StatusBar/>
        <div className="app-body" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', minHeight: '70vh', textAlign: 'center', padding: 24 }}>
          <div style={{
            width: 88, height: 88, borderRadius: 24,
            background: 'linear-gradient(135deg, var(--p600), var(--c600))',
            color: '#fff', display: 'grid', placeItems: 'center',
            boxShadow: '0 12px 32px -8px var(--p400)',
            animation: 'aiPulse 1.4s ease-in-out infinite',
          }}>
            <Icon name="sparkles" size={40}/>
          </div>
          <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--n900)', marginTop: 22, letterSpacing: '-0.01em' }}>
            Generating questions…
          </div>
          <div style={{ fontSize: 12.5, color: 'var(--n600)', marginTop: 6, lineHeight: 1.5, maxWidth: 280 }}>
            AI is drafting {count} questions for your assessment. Hang tight.
          </div>

          {/* Progress bar */}
          <div style={{ width: '100%', maxWidth: 280, marginTop: 26, height: 4, background: 'var(--n100)', borderRadius: 4, overflow: 'hidden' }}>
            <div style={{
              width: progress + '%', height: '100%',
              background: 'linear-gradient(90deg, var(--p600), var(--c600))',
              transition: 'width .5s ease',
            }}/>
          </div>

          {/* Stage list */}
          <div className="col" style={{ gap: 8, marginTop: 22, width: '100%', maxWidth: 280, alignItems: 'flex-start' }}>
            {stages.map((s, i) => {
              const done = i < genStage;
              const active = i === genStage;
              return (
                <div key={i} className="row" style={{ gap: 10, alignItems: 'center', opacity: i > genStage ? .35 : 1 }}>
                  <div style={{
                    width: 18, height: 18, borderRadius: '50%',
                    background: done ? 'var(--success)' : active ? 'var(--p600)' : 'var(--n100)',
                    color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0,
                  }}>
                    {done ? <Icon name="check" size={11}/> : active ? (
                      <div style={{ width: 6, height: 6, borderRadius: '50%', background: '#fff', animation: 'aiPulse 1s infinite' }}/>
                    ) : null}
                  </div>
                  <div style={{ fontSize: 12, fontWeight: active ? 700 : 500, color: active ? 'var(--n900)' : 'var(--n600)', textAlign: 'left' }}>
                    {s}
                  </div>
                </div>
              );
            })}
          </div>

          <button onClick={() => setStep('form')} style={{
            marginTop: 28, padding: '8px 16px', background: 'transparent',
            border: 'none', color: 'var(--n500)', fontSize: 12, fontWeight: 600, cursor: 'pointer',
          }}>Cancel</button>
        </div>
        <style>{`@keyframes aiPulse { 0%, 100% { transform: scale(1); opacity: 1 } 50% { transform: scale(1.06); opacity: .85 } }`}</style>
      </div>
    );
  }

  // ───────── RESULTS STEP ─────────
  return (
    <div className="app screen-in">
      <StatusBar/>
      <div className="app-body" style={{ paddingBottom: 100 }}>
        <NavHeader title="AI generated" onBack={() => setStep('form')}/>

        {/* Summary banner */}
        <div className="card" style={{
          padding: 14, marginTop: 14,
          background: 'linear-gradient(135deg, var(--p50), var(--c50))',
          border: '1px solid var(--p100)',
        }}>
          <div className="row" style={{ gap: 12, alignItems: 'center' }}>
            <div style={{
              width: 38, height: 38, borderRadius: 10,
              background: 'linear-gradient(135deg, var(--p600), var(--c600))',
              color: '#fff', display: 'grid', placeItems: 'center', flexShrink: 0,
            }}><Icon name="sparkles" size={18}/></div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--n900)' }}>
                {generated.length} questions ready
              </div>
              <div style={{ fontSize: 11, color: 'var(--n600)', marginTop: 2 }}>
                {sub} · Class {cls} · {DIFF_META[difficulty].lab.toLowerCase()} difficulty
              </div>
            </div>
          </div>
          {files.length > 0 && (
            <div className="row" style={{ gap: 8, marginTop: 10, padding: '8px 10px', background: '#fff', borderRadius: 8 }}>
              <Icon name="paperclip" size={12} style={{ color: 'var(--n500)' }}/>
              <div style={{ fontSize: 10.5, color: 'var(--n600)', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                Source: {files[0].name}{files.length > 1 ? ' + ' + (files.length - 1) + ' more' : ''}
              </div>
            </div>
          )}
        </div>

        {/* Selection bar */}
        <div className="row" style={{ gap: 8, alignItems: 'center', marginTop: 16 }}>
          <button onClick={() => setSelected(allSelected ? new Set() : new Set(generated.map((_, i) => i)))} style={{
            padding: '6px 10px', borderRadius: 8,
            background: 'var(--n50)', color: 'var(--n700)',
            border: '1px solid var(--n200)', fontSize: 11.5, fontWeight: 700, cursor: 'pointer',
          }}>
            {allSelected ? 'Deselect all' : 'Select all'}
          </button>
          <div style={{ flex: 1, fontSize: 11.5, fontWeight: 600, color: 'var(--n600)' }}>
            <span style={{ color: 'var(--p600)', fontWeight: 800, fontFamily: 'var(--mono)' }}>{selected.size}</span> of {generated.length} selected
          </div>
          <button onClick={runGenerate} className="btn-ghost" style={{
            fontSize: 11.5, fontWeight: 700, color: 'var(--p600)',
          }}>
            <Icon name="sparkles" size={13}/> Regenerate all
          </button>
        </div>

        {/* Generated questions */}
        <div className="col" style={{ gap: 10, marginTop: 14 }}>
          {generated.map((q, i) => {
            const meta = TYPE_META[q.type] || { lab: q.type, icon: 'circle' };
            const dm = DIFF_META[q._aiDifficulty] || DIFF_META.medium;
            const isSel = selected.has(i);
            const isRegenning = regenIdx === i;
            return (
              <div key={q._aiId} className="card" style={{
                padding: 14, position: 'relative',
                border: isSel ? '1.5px solid var(--p600)' : '1px solid var(--n100)',
                background: isSel ? 'var(--p25, ' + 'rgba(89,67,243,0.02))' : '#fff',
                opacity: isRegenning ? .5 : 1, transition: 'opacity .3s',
              }}>
                <div className="row" style={{ gap: 12, alignItems: 'flex-start' }}>
                  {/* checkbox */}
                  <button onClick={() => toggleSel(i)} style={{
                    width: 24, height: 24, borderRadius: 7,
                    background: isSel ? 'var(--p600)' : '#fff',
                    border: '1.5px solid ' + (isSel ? 'var(--p600)' : 'var(--n300)'),
                    display: 'grid', placeItems: 'center', cursor: 'pointer', flexShrink: 0, marginTop: 2,
                  }}>
                    {isSel && <Icon name="check" size={13} style={{ color: '#fff' }}/>}
                  </button>

                  <div style={{ flex: 1, minWidth: 0 }}>
                    {/* Top row */}
                    <div className="row" style={{ gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
                      <span style={{
                        fontSize: 9.5, fontWeight: 800, padding: '2px 7px',
                        background: 'var(--p50)', color: 'var(--p700)',
                        borderRadius: 5, letterSpacing: '.04em', fontFamily: 'var(--mono)',
                      }}>Q{i + 1}</span>
                      <span style={{
                        fontSize: 9.5, fontWeight: 700, padding: '2px 7px',
                        background: 'var(--n100)', color: 'var(--n600)',
                        borderRadius: 5, letterSpacing: '.04em', fontFamily: 'var(--mono)',
                      }}>{meta.lab}</span>
                      <span style={{
                        fontSize: 9.5, fontWeight: 700, padding: '2px 7px',
                        background: dm.bg, color: dm.clr,
                        borderRadius: 5, letterSpacing: '.04em', fontFamily: 'var(--mono)',
                      }}>{dm.lab.toUpperCase()}</span>
                      <span style={{ fontSize: 10, color: 'var(--n500)', fontFamily: 'var(--mono)', fontWeight: 600 }}>{q.marks}m</span>
                    </div>

                    {/* Question */}
                    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--n900)', lineHeight: 1.45, marginTop: 8 }}>
                      {q.q}
                    </div>

                    {/* Answer preview */}
                    <div style={{ marginTop: 8, padding: '8px 10px', background: 'var(--success-50)', borderRadius: 8, borderLeft: '2px solid var(--success)' }}>
                      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--success)', fontFamily: 'var(--mono)', letterSpacing: '.06em' }}>
                        ANSWER
                      </div>
                      <div style={{ fontSize: 11.5, color: 'var(--n800)', marginTop: 3, lineHeight: 1.4 }}>
                        {q.type === 'mcq' && q.opts ? String.fromCharCode(65 + q.correct) + '. ' + q.opts[q.correct] : null}
                        {q.type === 'multi' && q.opts && Array.isArray(q.correct) ? q.correct.map(c => String.fromCharCode(65 + c) + '. ' + q.opts[c]).join('  ·  ') : null}
                        {q.type === 'tf' ? (q.correct ? 'True' : 'False') : null}
                        {q.type === 'numeric' ? String(q.correct) + (q.unit ? ' ' + q.unit : '') : null}
                        {(q.type === 'short' || q.type === 'fill') && Array.isArray(q.correct) ? q.correct.flat().slice(0, 3).join(', ') : null}
                        {q.type === 'match' && q.pairs ? q.pairs.length + ' pairs' : null}
                      </div>
                    </div>

                    {/* Footer actions */}
                    <div className="row" style={{ gap: 8, marginTop: 10, alignItems: 'center' }}>
                      <span style={{
                        fontSize: 9.5, fontWeight: 700, color: 'var(--p600)',
                        display: 'inline-flex', alignItems: 'center', gap: 4,
                        fontFamily: 'var(--mono)', letterSpacing: '.04em',
                      }}>
                        <Icon name="sparkles" size={11}/> AI-SUGGESTED
                      </span>
                      <div style={{ flex: 1 }}/>
                      <button onClick={() => regenerateOne(i)} disabled={isRegenning} style={{
                        padding: '4px 8px', borderRadius: 6,
                        background: 'transparent', color: 'var(--n600)',
                        border: '1px solid var(--n200)', fontSize: 10.5, fontWeight: 700,
                        cursor: isRegenning ? 'wait' : 'pointer',
                        display: 'inline-flex', alignItems: 'center', gap: 4,
                      }}>
                        <Icon name="sparkles" size={11}/> {isRegenning ? 'Regenerating…' : 'Regenerate'}
                      </button>
                    </div>
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        {/* Tip card */}
        <div className="card-flat" style={{ marginTop: 14, padding: 12, background: 'var(--warning-50)', border: 'none' }}>
          <div className="row" style={{ gap: 10, alignItems: 'flex-start' }}>
            <Icon name="info" size={16} style={{ color: 'var(--warning)', flexShrink: 0, marginTop: 1 }}/>
            <div style={{ fontSize: 11, color: '#7C2D12', lineHeight: 1.5 }}>
              Review each question before adding. You can edit answers, marks, and explanations after they're added to the assessment.
            </div>
          </div>
        </div>
      </div>

      {/* Bottom CTA */}
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0,
        background: '#fff', borderTop: '1px solid var(--n100)',
        padding: '12px 16px', display: 'flex', gap: 8,
      }}>
        <button onClick={() => setStep('form')} className="btn btn-outline" style={{ flex: 1, height: 46 }}>
          <Icon name="chev-l" size={14}/> Refine
        </button>
        <button
          onClick={confirmAdd}
          disabled={noneSelected}
          className="btn"
          style={{ flex: 1.6, height: 46 }}
        >
          <Icon name="check" size={14}/> Add {selected.size} to assessment
        </button>
      </div>
    </div>
  );
}

Object.assign(window, {
  AssessmentsHubScreen,
  AssessmentIntroScreen,
  AssessmentAttemptScreen,
  AssessmentSubmittedScreen,
  AssessmentResultScreen,
  LeaderboardScreen,
  AssessmentLeaderboardScreen,
  PracticeIntroScreen,
  PracticeAttemptScreen,
  // Teacher side
  TeacherAssessmentsHubScreen,
  TeacherCreateAssessmentScreen,
  TeacherAddQuestionScreen,
  TeacherAIGenerateScreen,
  TeacherSubmissionsScreen,
  TeacherGradeSubmissionScreen,
  TeacherClassAnalyticsScreen,
  TeacherPublishResultsScreen,
});
