{"id":795,"date":"2026-03-05T16:15:51","date_gmt":"2026-03-05T16:15:51","guid":{"rendered":"https:\/\/i-cte.org\/robot\/?p=795"},"modified":"2026-03-05T16:15:51","modified_gmt":"2026-03-05T16:15:51","slug":"ai-for-quantitative-research","status":"publish","type":"post","link":"https:\/\/i-cte.org\/robot\/ai-for-quantitative-research\/","title":{"rendered":"AI for Quantitative Research"},"content":{"rendered":"\n<!-- \u2705 ICTE Teacher Micro-Lesson \u2014 AI for Quantitative Research Support\n     WP-safe single block, Multi-speaker Google Voices (2 voices)\n     Includes: Overview + Conversation + Reading + Quiz + Toolkit + Prompts + Listening + Quant Lab + Problem-solving + Progress\n     Focus: variable operationalization, survey item drafting, basic stats interpretation, reporting results clearly.\n-->\n<div id=\"icte-quantai\">\n\n  <!-- \u2705 TOP MENU -->\n  <nav class=\"icte-menu\" aria-label=\"Quantitative AI lesson navigation\">\n    <a href=\"#\" class=\"is-current\" data-view=\"overview\">Overview<\/a>\n    <a href=\"#\" data-view=\"conversation\">Conversation<\/a>\n    <a href=\"#\" data-view=\"reading\">Reading<\/a>\n    <a href=\"#\" data-view=\"toolkit\">Quant Toolkit<\/a>\n    <a href=\"#\" data-view=\"prompts\">Prompts<\/a>\n    <a href=\"#\" data-view=\"listening\">Listening<\/a>\n    <a href=\"#\" data-view=\"lab\">Quant Research Lab<\/a>\n    <a href=\"#\" data-view=\"problem\">Problem-solving<\/a>\n    <a href=\"#\" data-view=\"progress\">Progress<\/a>\n  <\/nav>\n\n  <section class=\"icte-shell\" aria-label=\"ICTE quantitative AI lesson\">\n\n    <!-- \u2705 Header -->\n    <header class=\"icte-hero\">\n      <div class=\"icte-hero__text\">\n        <div class=\"hero-top\">\n          <img decoding=\"async\"\n            class=\"hero-img\"\n            src=\"https:\/\/i-cte.org\/robot\/wp-content\/uploads\/2026\/03\/Screenshot-2026-03-05-at-23.14.04.png\"\n            alt=\"AI for quantitative research support banner\"\n            loading=\"lazy\"\n          \/>\n          <div class=\"hero-title\">\n            <h2>AI for Quantitative Research<\/h2>\n            <p class=\"muted\">\n              Use AI to support <b>variable operationalization<\/b>, <b>survey item drafting<\/b>, <b>basic statistics interpretation<\/b>, and\n              <b>clear reporting<\/b>\u2014while keeping <b>researcher control<\/b>, transparency, and validity.\n              Includes a hands-on <b>quant lab<\/b> and an end-of-lesson <b>problem-solving<\/b> task.\n            <\/p>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"icte-hero__controls\">\n        <div class=\"icte-pill\">\n          <span class=\"dot\" id=\"icteMicDot\" aria-hidden=\"true\"><\/span>\n          <span id=\"icteMicStatus\">Mic: Off<\/span>\n        <\/div>\n\n        <div class=\"icte-row\">\n          <button class=\"btn\" id=\"icteStartVoice\" type=\"button\">Start Voice<\/button>\n          <button class=\"btn ghost\" id=\"icteStopVoice\" type=\"button\">Stop<\/button>\n        <\/div>\n\n        <!-- \u2705 Multi-speaker Google Voices -->\n        <div class=\"grid2\" style=\"margin-top:10px;\">\n          <label class=\"icte-label\">\n            Speaker A (Google)\n            <select id=\"voiceA\" class=\"icte-select\" aria-label=\"Speaker A voice\"><\/select>\n          <\/label>\n\n          <label class=\"icte-label\">\n            Speaker B (Google)\n            <select id=\"voiceB\" class=\"icte-select\" aria-label=\"Speaker B voice\"><\/select>\n          <\/label>\n        <\/div>\n\n        <div class=\"icte-row\" style=\"margin-top:10px;\">\n          <button class=\"btn mini ghost\" type=\"button\" id=\"speakActive\">\ud83d\udd0a Read this page<\/button>\n          <button class=\"btn mini ghost\" type=\"button\" id=\"stopSpeak\">\u23f9 Stop audio<\/button>\n        <\/div>\n\n        <div class=\"icte-small muted\">\n          Tip: For best voice options, use Chrome\/Edge. If voices don\u2019t appear yet, click once on the page and wait 2\u20133 seconds.\n        <\/div>\n      <\/div>\n    <\/header>\n\n    <!-- \u2705 Views -->\n    <main class=\"icte-main\">\n\n      <!-- ===================== -->\n      <!-- \u2705 OVERVIEW -->\n      <!-- ===================== -->\n      <section class=\"view is-active\" data-view=\"overview\" aria-label=\"Lesson overview\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>1) Outcomes<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"overview-instr\">\ud83d\udd0a Read instructions<\/button>\n            <\/div>\n          <\/div>\n\n          <div class=\"grid2\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">By the end, you can\u2026<\/div>\n              <ul class=\"ul\">\n                <li>Operationalize constructs into <b>measurable variables<\/b> (DV\/IV\/covariates).<\/li>\n                <li>Draft <b>survey items<\/b> with clear wording, scale anchors, and reverse items.<\/li>\n                <li>Interpret <b>basic statistics<\/b> (mean, SD, correlations, t-tests) carefully.<\/li>\n                <li>Report results clearly using <b>APA-style quantitative reporting<\/b> patterns (numbers, effect, interpretation).<\/li>\n                <li>Maintain researcher control: validity checks, assumptions, and transparency.<\/li>\n              <\/ul>\n            <\/div>\n\n            <div class=\"qitem\">\n              <div class=\"qtext\">Researcher control rules<\/div>\n              <ul class=\"ul\">\n                <li>AI drafts; <b>you validate<\/b> (construct validity, content validity, reliability).<\/li>\n                <li>Never \u201cinfer causality\u201d from correlational data.<\/li>\n                <li>Check assumptions (normality, independence) before interpreting tests.<\/li>\n                <li>Keep an audit trail: prompts, decisions, revisions, and versioning.<\/li>\n              <\/ul>\n            <\/div>\n          <\/div>\n\n          <div class=\"note\">\n            <b>Principle:<\/b> AI can help with <b>structure and clarity<\/b>, but you must ensure <b>measurement quality<\/b> and correct interpretation.\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 CONVERSATION -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"conversation\" aria-label=\"Conversation coach\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>2) Conversation (Quant Research Coach)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"conv-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"convHear\">\ud83d\udd0a Read last question<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"convReset\">Reset<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">\n            Practice a disciplined workflow: research question \u2192 variables \u2192 operationalization \u2192 items \u2192 analysis plan \u2192 reporting.\n          <\/p>\n\n          <div class=\"chat\" id=\"convChat\" aria-live=\"polite\" aria-label=\"Conversation chat log\"><\/div>\n\n          <div class=\"chatbar\">\n            <input id=\"convText\" class=\"input\" type=\"text\" placeholder=\"Type your answer (or use voice)...\" autocomplete=\"off\" \/>\n            <button class=\"btn\" id=\"convSend\" type=\"button\">Send<\/button>\n          <\/div>\n\n          <div class=\"note\">\n            <b>Tip:<\/b> A strong quantitative prompt includes: population, constructs, proposed measures, and planned analysis.\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 READING + QUIZ -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"reading\" aria-label=\"Reading and quiz\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>3) Reading + Comprehension Quiz<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"reading-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"readTextBtn\">\ud83d\udd0a Read the text<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"quizCheck\">Check answers<\/button>\n            <\/div>\n          <\/div>\n\n          <article class=\"reading\" id=\"readingText\" aria-label=\"Reading text about quantitative AI support\">\n            <div class=\"reading-title\">Reading: Using AI responsibly in quantitative research<\/div>\n\n            <div class=\"reading-p\">\n              <b>1<\/b> AI can support quantitative research by drafting variable definitions, survey items, and reporting language.\n              However, the quality of quantitative research depends on <b>measurement validity<\/b>, <b>reliability<\/b>, and correct statistical reasoning.\n              AI output should be treated as a starting point that requires researcher checking.\n            <\/div>\n\n            <div class=\"reading-p\">\n              <b>2<\/b> Operationalization turns an abstract construct (e.g., motivation) into measurable indicators. A good operational definition specifies:\n              the construct, the population, the scale or instrument, scoring, and expected direction. It also clarifies what the measure <b>does not<\/b> capture.\n            <\/div>\n\n            <div class=\"reading-p\">\n              <b>3<\/b> AI can help draft survey items, but item quality requires attention to wording (one idea per item), avoiding leading language,\n              appropriate response scales, and cultural\/context suitability. Pilot testing and reliability checks (e.g., internal consistency) remain essential.\n            <\/div>\n\n            <div class=\"reading-p\">\n              <b>4<\/b> For statistics, AI can assist with interpretation, but common errors include confusing correlation with causation, ignoring assumptions,\n              and overinterpreting small differences. Good reporting communicates the test used, key numbers, effect size where possible, and practical meaning.\n            <\/div>\n\n            <div class=\"reading-p\">\n              <b>5<\/b> Researcher control means transparency: document how AI assisted, what you checked, and what decisions you made.\n              This protects the study\u2019s integrity and helps readers evaluate evidence.\n            <\/div>\n          <\/article>\n\n          <h4 class=\"h4\" style=\"margin-top:12px;\">Comprehension check (choose the best answer)<\/h4>\n          <div id=\"quiz\" class=\"stack\"><\/div>\n          <div class=\"feedback\" id=\"quizFb\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 TOOLKIT -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"toolkit\" aria-label=\"Quantitative toolkit\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>4) Quantitative Toolkit (Operationalization, items, stats, reporting)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"toolkit-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"toolkitSpeak\">\ud83d\udd0a Read toolkit<\/button>\n            <\/div>\n          <\/div>\n\n          <div class=\"grid2\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">Operationalization template<\/div>\n              <pre class=\"pre\" id=\"tkOp\"><\/pre>\n            <\/div>\n            <div class=\"qitem\">\n              <div class=\"qtext\">Survey item quality checklist<\/div>\n              <pre class=\"pre\" id=\"tkItems\"><\/pre>\n            <\/div>\n          <\/div>\n\n          <div class=\"grid2\" style=\"margin-top:12px;\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">Basic stats interpretation guardrails<\/div>\n              <pre class=\"pre\" id=\"tkStats\"><\/pre>\n            <\/div>\n            <div class=\"qitem\">\n              <div class=\"qtext\">Reporting template (clear, APA-friendly)<\/div>\n              <pre class=\"pre\" id=\"tkReport\"><\/pre>\n            <\/div>\n          <\/div>\n\n          <div class=\"qitem\" style=\"margin-top:12px;\">\n            <div class=\"qtext\">Validity &#038; reliability checklist (printable)<\/div>\n            <pre class=\"pre\" id=\"tkVR\"><\/pre>\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 PROMPTS -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"prompts\" aria-label=\"Prompts and examples\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>5) Prompts + Examples (Copy &#038; Adapt)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"prompts-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"promptsSpeak\">\ud83d\udd0a Read prompts<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"copyPrompts\">Copy all<\/button>\n            <\/div>\n          <\/div>\n\n          <div class=\"note\">\n            These prompts force clarity: operational definitions, item boundaries, analysis plan, assumptions, and reporting.\n          <\/div>\n\n          <div class=\"grid2\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">Prompt 1 \u2014 Operationalize variables (DV\/IV\/covariates)<\/div>\n              <pre class=\"pre\" id=\"p1\"><\/pre>\n            <\/div>\n            <div class=\"qitem\">\n              <div class=\"qtext\">Prompt 2 \u2014 Draft survey items + scales<\/div>\n              <pre class=\"pre\" id=\"p2\"><\/pre>\n            <\/div>\n          <\/div>\n\n          <div class=\"grid2\" style=\"margin-top:12px;\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">Prompt 3 \u2014 Analysis plan + assumptions<\/div>\n              <pre class=\"pre\" id=\"p3\"><\/pre>\n            <\/div>\n            <div class=\"qitem\">\n              <div class=\"qtext\">Prompt 4 \u2014 Reporting results clearly<\/div>\n              <pre class=\"pre\" id=\"p4\"><\/pre>\n            <\/div>\n          <\/div>\n\n          <div class=\"qitem\" style=\"margin-top:12px;\">\n            <div class=\"qtext\">Mini example (expected output style)<\/div>\n            <pre class=\"pre\" id=\"pExample\"><\/pre>\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 LISTENING -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"listening\" aria-label=\"Two-speaker listening\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>6) Listening (Two Google Voices) \u2014 \u201cMeasurement first, stats second\u201d<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"list-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini\" type=\"button\" id=\"listenPlay\">\u25b6\ufe0f Play dialogue<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"listenStop\">\u23f9 Stop<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"listenCheck\">Check answers<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">Listen to two instructors discussing how AI supports quantitative work without breaking validity.<\/p>\n\n          <div id=\"listenQ\" class=\"stack\"><\/div>\n          <div class=\"feedback\" id=\"listenFb\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 QUANT LAB -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"lab\" aria-label=\"Quant research lab\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>7) Quant Research Lab (Enter variables + numbers \u2192 generate interpretation &#038; report)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"lab-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"labRun\">Run lab<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"labCopy\">Copy report<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"labReset\">Reset<\/button>\n            <\/div>\n          <\/div>\n\n          <div class=\"note\">\n            Provide your DV\/IV and either (A) descriptive stats or (B) a test summary (t, p, means\/SDs) or (C) correlation (r, p).\n            The lab will produce an <b>operationalization draft<\/b>, <b>item suggestions<\/b>, and a <b>clear results paragraph<\/b>.\n            <br><b>Reminder:<\/b> This is formatting + reasoning support; you must verify assumptions and calculations.\n          <\/div>\n\n          <div class=\"grid2\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">A) Study setup<\/div>\n              <textarea class=\"textarea\" id=\"qSetup\" rows=\"14\" placeholder=\"Population: ...&#10;RQ\/Hypothesis: ...&#10;DV: ...&#10;IV\/group: ...&#10;Covariates (optional): ...&#10;Planned analysis: (t-test\/correlation\/ANOVA\/regression) ...\"><\/textarea>\n              <div class=\"icte-small muted\" style=\"margin-top:6px;\">\n                Tip: Be explicit about direction (e.g., higher scores = more motivation).\n              <\/div>\n            <\/div>\n\n            <div class=\"qitem\">\n              <div class=\"qtext\">B) Numbers to interpret (paste)<\/div>\n              <textarea class=\"textarea\" id=\"qNums\" rows=\"14\" placeholder=\"Option 1 (t-test): Group A M=..., SD=..., n=...; Group B M=..., SD=..., n=...; t(df)=..., p=...&#10;&#10;Option 2 (correlation): r=..., p=..., n=...&#10;&#10;Option 3 (descriptives): M=..., SD=..., range=...\"><\/textarea>\n              <div class=\"icte-small muted\" style=\"margin-top:6px;\">\n                Tip: If you have effect size, include it (d, \u03b7\u00b2, R\u00b2). If not, the lab will suggest what to compute.\n              <\/div>\n            <\/div>\n          <\/div>\n\n          <div class=\"qitem\" style=\"margin-top:12px;\">\n            <div class=\"qtext\">Lab output: Operationalization + Items + Reporting<\/div>\n            <pre class=\"pre\" id=\"labOut\"><\/pre>\n          <\/div>\n\n          <div class=\"qitem\" style=\"margin-top:12px;\">\n            <div class=\"qtext\">Safe AI prompt (for quantitative support without errors)<\/div>\n            <pre class=\"pre\" id=\"safePrompt\"><\/pre>\n          <\/div>\n\n          <div class=\"feedback\" id=\"labFb\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 PROBLEM-SOLVING -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"problem\" aria-label=\"Problem solving task\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>8) Problem-solving<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"problem-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"psCheck\">Check my solution<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"psReset\">Reset<\/button>\n            <\/div>\n          <\/div>\n\n          <div class=\"note\">\n            <b>Scenario:<\/b> You measure \u201cspeaking confidence\u201d and \u201cchatbot usage frequency.\u201d\n            A colleague claims: \u201cChatbot usage causes higher confidence\u201d because the correlation is significant.\n            <br><br>\n            Your task:\n            <ul class=\"ul\">\n              <li>Write a <b>correction<\/b> (3\u20135 lines) explaining why correlation \u2260 causation.<\/li>\n              <li>Propose <b>2 alternative explanations<\/b> (confounds).<\/li>\n              <li>Suggest <b>one improved design<\/b> that supports causal inference.<\/li>\n              <li>Rewrite the claim into a <b>statistically accurate<\/b> statement for a paper.<\/li>\n            <\/ul>\n          <\/div>\n\n          <div class=\"grid2\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">A) Correction (3\u20135 lines)<\/div>\n              <textarea class=\"textarea\" id=\"psA\" rows=\"10\" placeholder=\"Explain why correlation does not prove causation...\"><\/textarea>\n            <\/div>\n            <div class=\"qitem\">\n              <div class=\"qtext\">B) Alternative explanations (2 bullets)<\/div>\n              <textarea class=\"textarea\" id=\"psB\" rows=\"10\" placeholder=\"- Confound 1...&#10;- Confound 2...\"><\/textarea>\n            <\/div>\n          <\/div>\n\n          <div class=\"grid2\" style=\"margin-top:12px;\">\n            <div class=\"qitem\">\n              <div class=\"qtext\">C) Improved design (1 proposal)<\/div>\n              <textarea class=\"textarea\" id=\"psC\" rows=\"7\" placeholder=\"e.g., randomized controlled study, pre-post with matched controls, longitudinal cross-lagged...\"><\/textarea>\n            <\/div>\n            <div class=\"qitem\">\n              <div class=\"qtext\">D) Accurate rewrite<\/div>\n              <textarea class=\"textarea\" id=\"psD\" rows=\"7\" placeholder=\"Rewrite using cautious, accurate language (e.g., 'was associated with').\"><\/textarea>\n            <\/div>\n          <\/div>\n\n          <div class=\"feedback\" id=\"psFb\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 PROGRESS -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"progress\" aria-label=\"Progress tracking\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>Progress<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini ghost\" type=\"button\" id=\"progressReset\">Clear progress<\/button>\n            <\/div>\n          <\/div>\n\n          <div class=\"progress-grid\">\n            <div class=\"pbox\">\n              <div class=\"pnum\" id=\"pDone\">0<\/div>\n              <div class=\"muted\">Activities completed<\/div>\n            <\/div>\n            <div class=\"pbox\">\n              <div class=\"pnum\" id=\"pScore\">0%<\/div>\n              <div class=\"muted\">Average score<\/div>\n            <\/div>\n            <div class=\"pbox\">\n              <div class=\"pnum\" id=\"pChecks\">0<\/div>\n              <div class=\"muted\">Checklist items used<\/div>\n            <\/div>\n          <\/div>\n\n          <div class=\"note\">Saved locally in your browser (local storage).<\/div>\n\n          <h4 class=\"h4\">Checklist bank<\/h4>\n          <div class=\"bank\" id=\"checksBank\"><\/div>\n        <\/div>\n      <\/section>\n\n    <\/main>\n  <\/section>\n\n  <style>\n    \/* ===== WP-SAFE STYLES (scoped) ===== *\/\n    #icte-quantai *{ box-sizing:border-box; }\n    #icte-quantai{\n      --green:#28a745;\n      --dark:#132018;\n      --card:#ffffff;\n      --muted:#6b7280;\n      --line:#e5e7eb;\n      --shadow:0 8px 24px rgba(17,24,39,.08);\n      --radius:16px;\n      font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;\n      color:#111827;\n    }\n    #icte-quantai .icte-menu{\n      width:100%;\n      background:var(--green);\n      padding:10px 12px;\n      text-align:center;\n      overflow-x:auto;\n      white-space:nowrap;\n      position:sticky;\n      top:0;\n      z-index:999;\n      box-shadow:0 2px 10px rgba(0,0,0,.12);\n      border-radius:12px;\n      margin-bottom:12px;\n    }\n    #icte-quantai .icte-menu a{\n      display:inline-block;\n      color:#fff;\n      text-decoration:none;\n      font-weight:900;\n      padding:8px 10px;\n      border-radius:999px;\n      margin:0 3px;\n      opacity:.92;\n      transition:.15s;\n    }\n    #icte-quantai .icte-menu a:hover{ opacity:1; background:rgba(255,255,255,.14); }\n    #icte-quantai .icte-menu a.is-current{ background:#fff; color:var(--dark); opacity:1; }\n\n    #icte-quantai .icte-shell{ max-width:1100px; margin:0 auto; }\n    #icte-quantai .icte-hero{\n      display:grid;\n      grid-template-columns: 1.2fr .8fr;\n      gap:14px;\n      background:linear-gradient(135deg,#e9fff0, #ffffff);\n      border:1px solid var(--line);\n      border-radius:var(--radius);\n      padding:16px;\n      box-shadow:var(--shadow);\n      margin-bottom:14px;\n    }\n    @media (max-width: 920px){ #icte-quantai .icte-hero{ grid-template-columns:1fr; } }\n    #icte-quantai h2{ margin:0 0 6px 0; font-size:22px; }\n    #icte-quantai .muted{ color:var(--muted); }\n\n    #icte-quantai .hero-top{ display:flex; gap:12px; align-items:center; }\n    #icte-quantai .hero-img{\n      width:140px;\n      height:auto;\n      border-radius:14px;\n      border:1px solid var(--line);\n      background:#111;\n      box-shadow:var(--shadow);\n    }\n    @media (max-width: 920px){\n      #icte-quantai .hero-top{ flex-direction:column; align-items:flex-start; }\n      #icte-quantai .hero-img{ width:100%; max-width:520px; }\n    }\n\n    #icte-quantai .icte-hero__controls{\n      border-left:1px dashed var(--line);\n      padding-left:14px;\n    }\n    @media (max-width: 920px){\n      #icte-quantai .icte-hero__controls{ border-left:none; padding-left:0; border-top:1px dashed var(--line); padding-top:12px; }\n    }\n\n    #icte-quantai .icte-row{ display:flex; gap:8px; flex-wrap:wrap; }\n    #icte-quantai .icte-label{ display:block; font-size:12px; font-weight:900; margin-top:8px; }\n    #icte-quantai .icte-select{\n      width:100%;\n      padding:10px 10px;\n      border:1px solid var(--line);\n      border-radius:12px;\n      background:#fff;\n      outline:none;\n      margin-top:6px;\n    }\n\n    #icte-quantai .icte-pill{\n      display:flex; align-items:center; gap:8px;\n      padding:10px 12px;\n      border:1px solid var(--line);\n      border-radius:999px;\n      background:#fff;\n      margin-bottom:10px;\n      font-weight:900;\n    }\n    #icte-quantai .dot{\n      width:10px; height:10px; border-radius:50%;\n      background:#9ca3af;\n      box-shadow:0 0 0 4px rgba(156,163,175,.18);\n    }\n    #icte-quantai .dot.on{\n      background:#22c55e;\n      box-shadow:0 0 0 4px rgba(34,197,94,.18);\n    }\n\n    #icte-quantai .btn{\n      border:none;\n      padding:10px 12px;\n      border-radius:12px;\n      background:var(--green);\n      color:#fff;\n      font-weight:900;\n      cursor:pointer;\n      transition:.15s;\n    }\n    #icte-quantai .btn:hover{ filter:brightness(.95); transform:translateY(-1px); }\n    #icte-quantai .btn:active{ transform:translateY(0); }\n    #icte-quantai .btn.ghost{\n      background:#fff;\n      color:#111827;\n      border:1px solid var(--line);\n    }\n    #icte-quantai .btn.mini{ padding:8px 10px; border-radius:10px; font-size:13px; }\n    #icte-quantai .icte-small{ font-size:12px; }\n\n    #icte-quantai .card{\n      background:var(--card);\n      border:1px solid var(--line);\n      border-radius:var(--radius);\n      padding:14px;\n      box-shadow:var(--shadow);\n      margin-bottom:14px;\n    }\n    #icte-quantai .card-h{\n      display:flex; gap:10px; align-items:flex-start; justify-content:space-between;\n      border-bottom:1px solid var(--line);\n      padding-bottom:10px;\n      margin-bottom:10px;\n    }\n    #icte-quantai .card-h h3{ margin:0; font-size:18px; }\n    #icte-quantai .card-actions{ display:flex; gap:8px; flex-wrap:wrap; justify-content:flex-end; }\n\n    #icte-quantai .view{ display:none; }\n    #icte-quantai .view.is-active{ display:block; }\n\n    #icte-quantai .grid2{\n      display:grid;\n      grid-template-columns:1fr 1fr;\n      gap:14px;\n      margin-top:10px;\n    }\n    @media (max-width: 920px){ #icte-quantai .grid2{ grid-template-columns:1fr; } }\n\n    #icte-quantai .stack{ display:flex; flex-direction:column; gap:10px; }\n    #icte-quantai .h4{ margin:0 0 6px 0; font-size:15px; }\n    #icte-quantai .qitem{\n      padding:10px;\n      border:1px solid var(--line);\n      border-radius:14px;\n      background:#fafafa;\n    }\n    #icte-quantai .qtext{ font-weight:900; margin-bottom:8px; }\n\n    #icte-quantai .feedback{\n      margin-top:10px;\n      padding:10px 12px;\n      border-radius:14px;\n      border:1px solid var(--line);\n      background:#f9fafb;\n      font-weight:800;\n      display:none;\n      white-space:pre-line;\n    }\n    #icte-quantai .feedback.ok{ display:block; border-color:rgba(34,197,94,.35); background:#ecfdf5; }\n    #icte-quantai .feedback.bad{ display:block; border-color:rgba(239,68,68,.35); background:#fef2f2; }\n\n    #icte-quantai .note{\n      background:#eff6ff;\n      border:1px solid rgba(59,130,246,.22);\n      padding:10px 12px;\n      border-radius:14px;\n      margin:10px 0;\n    }\n\n    #icte-quantai .reading{\n      border:1px solid var(--line);\n      border-radius:14px;\n      padding:12px;\n      background:#fff;\n      margin-top:10px;\n    }\n    #icte-quantai .reading-title{ font-weight:900; margin-bottom:8px; }\n    #icte-quantai .reading-p{ padding:8px 0; border-top:1px dashed var(--line); }\n    #icte-quantai .reading-p:first-of-type{ border-top:none; }\n\n    #icte-quantai .progress-grid{\n      display:grid;\n      grid-template-columns:repeat(3,1fr);\n      gap:12px;\n      margin-top:10px;\n      margin-bottom:10px;\n    }\n    @media (max-width: 920px){ #icte-quantai .progress-grid{ grid-template-columns:1fr; } }\n    #icte-quantai .pbox{\n      border:1px solid var(--line);\n      border-radius:16px;\n      background:#fff;\n      padding:12px;\n      text-align:center;\n      box-shadow:var(--shadow);\n    }\n    #icte-quantai .pnum{ font-size:28px; font-weight:1000; }\n\n    #icte-quantai .bank{\n      border:1px solid var(--line);\n      border-radius:14px;\n      padding:12px;\n      background:#fff;\n      display:flex;\n      flex-wrap:wrap;\n      gap:8px;\n    }\n    #icte-quantai .tag{\n      border:1px solid var(--line);\n      background:#f9fafb;\n      padding:6px 10px;\n      border-radius:999px;\n      font-weight:900;\n      font-size:13px;\n    }\n\n    #icte-quantai .pre{\n      white-space:pre-wrap;\n      background:#0b1220;\n      color:#e5e7eb;\n      border-radius:12px;\n      padding:12px;\n      border:1px solid rgba(255,255,255,.08);\n      overflow:auto;\n      font-size:13px;\n      line-height:1.45;\n    }\n\n    #icte-quantai .ul{ margin:0; padding-left:18px; }\n    #icte-quantai .ul li{ margin:6px 0; }\n\n    #icte-quantai .textarea{\n      width:100%;\n      padding:12px;\n      border:1px solid var(--line);\n      border-radius:12px;\n      outline:none;\n      resize:vertical;\n    }\n\n    \/* Conversation UI *\/\n    #icte-quantai .chat{\n      background:#0b1220;\n      color:#e5e7eb;\n      border-radius:14px;\n      padding:12px;\n      min-height:220px;\n      max-height:420px;\n      overflow:auto;\n      border:1px solid rgba(255,255,255,.08);\n    }\n    #icte-quantai .msg{ margin:10px 0; display:flex; gap:10px; align-items:flex-start; }\n    #icte-quantai .who{\n      min-width:90px;\n      font-weight:900;\n      font-size:12px;\n      color:#93c5fd;\n      text-transform:uppercase;\n      letter-spacing:.06em;\n    }\n    #icte-quantai .bubble{\n      flex:1;\n      background:rgba(255,255,255,.06);\n      padding:10px 10px;\n      border-radius:12px;\n      line-height:1.45;\n      border:1px solid rgba(255,255,255,.06);\n      white-space:pre-line;\n    }\n    #icte-quantai .msg.user .who{ color:#86efac; }\n    #icte-quantai .msg.user .bubble{ background:rgba(34,197,94,.10); border-color:rgba(34,197,94,.18); }\n\n    #icte-quantai .chatbar{\n      margin-top:10px;\n      display:flex;\n      gap:8px;\n      align-items:center;\n    }\n    #icte-quantai .input{\n      flex:1;\n      padding:12px 12px;\n      border:1px solid var(--line);\n      border-radius:12px;\n      outline:none;\n    }\n  <\/style>\n\n  <script>\n    (function(){\n      const root = document.getElementById('icte-quantai');\n      if(!root) return;\n\n      \/* =========================\n         Helpers\n      ========================= *\/\n      const qs  = (sel, el=root) => el.querySelector(sel);\n      const qsa = (sel, el=root) => Array.from(el.querySelectorAll(sel));\n      const clamp = (n,min,max)=>Math.max(min,Math.min(max,n));\n      const norm = (s)=> (s||\"\").toString().trim();\n      const esc  = (s)=> (s||\"\").replace(\/[&<>\"']\/g, m=>({ \"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#039;\" }[m]));\n\n      \/* =========================\n         Navigation\n      ========================= *\/\n      const navLinks = qsa('.icte-menu a');\n      const views = qsa('.view');\n      function showView(name){\n        views.forEach(v=> v.classList.toggle('is-active', v.getAttribute('data-view')===name));\n        navLinks.forEach(a=> a.classList.toggle('is-current', a.getAttribute('data-view')===name));\n        window.scrollTo({top: root.offsetTop - 10, behavior:'smooth'});\n      }\n      navLinks.forEach(a=>{\n        a.addEventListener('click', (e)=>{\n          e.preventDefault();\n          const v = a.getAttribute('data-view');\n          if(v) showView(v);\n        });\n      });\n      function activeViewName(){\n        const v = qs('.view.is-active');\n        return v ? v.getAttribute('data-view') : \"overview\";\n      }\n\n      \/* =========================\n         Multi-speaker Google Voices\n      ========================= *\/\n      const voiceASelect = qs('#voiceA');\n      const voiceBSelect = qs('#voiceB');\n\n      let allVoices = [];\n      let googleVoicesEN = [];\n      let voiceA = null;\n      let voiceB = null;\n\n      function isEnglish(v){ return (v.lang||\"\").toLowerCase().startsWith(\"en\"); }\n      function isGoogle(v){ return (v.name||\"\").toLowerCase().includes(\"google\"); }\n\n      function looksMaleName(name){\n        const n=(name||\"\").toLowerCase();\n        return n.includes(\"male\") || n.includes(\"david\") || n.includes(\"mark\") || n.includes(\"daniel\") || n.includes(\"james\") || n.includes(\"john\") || n.includes(\"michael\");\n      }\n      function looksFemaleName(name){\n        const n=(name||\"\").toLowerCase();\n        return n.includes(\"female\") || n.includes(\"susan\") || n.includes(\"amy\") || n.includes(\"emma\") || n.includes(\"olivia\") || n.includes(\"sophia\") || n.includes(\"ava\");\n      }\n\n      function pickDefaultVoices(list){\n        if(!list || !list.length) return {a:null,b:null};\n        const a = list.find(v=>looksFemaleName(v.name)) || list[0] || null;\n        let b = list.find(v=>v!==a && looksMaleName(v.name)) || list.find(v=>v!==a) || a || null;\n        if(b === a && list.length > 1) b = list.find(v=>v!==a) || b;\n        return {a,b};\n      }\n\n      function buildSelect(sel, list){\n        sel.innerHTML = \"\";\n        list.forEach((v,i)=>{\n          const opt=document.createElement(\"option\");\n          opt.value=String(i);\n          opt.textContent=`${v.name} (${v.lang})`;\n          sel.appendChild(opt);\n        });\n      }\n\n      function loadVoices(){\n        if(!window.speechSynthesis) return;\n        allVoices = speechSynthesis.getVoices() || [];\n\n        const google = allVoices.filter(v => isEnglish(v) && isGoogle(v));\n        const english = allVoices.filter(v => isEnglish(v));\n        googleVoicesEN = google.length ? google : english;\n\n        buildSelect(voiceASelect, googleVoicesEN);\n        buildSelect(voiceBSelect, googleVoicesEN);\n\n        const picked = pickDefaultVoices(googleVoicesEN);\n        voiceA = picked.a;\n        voiceB = picked.b;\n\n        const idxA = Math.max(0, googleVoicesEN.indexOf(voiceA));\n        const idxB = Math.max(0, googleVoicesEN.indexOf(voiceB));\n\n        voiceASelect.value = String(idxA);\n        voiceBSelect.value = String(idxB);\n\n        voiceASelect.onchange = ()=>{\n          const idx=parseInt(voiceASelect.value,10);\n          voiceA = googleVoicesEN[idx] || voiceA;\n          if(voiceB === voiceA && googleVoicesEN.length > 1){\n            voiceB = googleVoicesEN.find(v=>v!==voiceA) || voiceB;\n            voiceBSelect.value = String(googleVoicesEN.indexOf(voiceB));\n          }\n        };\n        voiceBSelect.onchange = ()=>{\n          const idx=parseInt(voiceBSelect.value,10);\n          voiceB = googleVoicesEN[idx] || voiceB;\n          if(voiceB === voiceA && googleVoicesEN.length > 1){\n            voiceB = googleVoicesEN.find(v=>v!==voiceA) || voiceB;\n            voiceBSelect.value = String(googleVoicesEN.indexOf(voiceB));\n          }\n        };\n      }\n\n      if(window.speechSynthesis){\n        loadVoices();\n        speechSynthesis.onvoiceschanged = loadVoices;\n        setTimeout(loadVoices, 700);\n      }\n\n      function stopSpeak(){ if(window.speechSynthesis) speechSynthesis.cancel(); }\n      function speakAs(role, text, opts){\n        const t = norm(text);\n        if(!t || !window.speechSynthesis) return Promise.resolve();\n        const o = opts || {};\n        const u = new SpeechSynthesisUtterance(t);\n        if(role===\"A\" && voiceA) u.voice = voiceA;\n        if(role===\"B\" && voiceB) u.voice = voiceB;\n        u.rate = o.rate ?? 1.02;\n        u.pitch = o.pitch ?? 1.0;\n        u.volume = o.volume ?? 1.0;\n        return new Promise(resolve=>{\n          u.onend=resolve; u.onerror=resolve;\n          speechSynthesis.speak(u);\n        });\n      }\n      async function speakDialogue(lines){\n        stopSpeak();\n        for(const line of lines){\n          await speakAs(line.role, line.text);\n        }\n      }\n      qs('#stopSpeak').addEventListener('click', stopSpeak);\n\n      \/* =========================\n         Mic Speech Recognition (ASR)\n      ========================= *\/\n      const micDot = qs('#icteMicDot');\n      const micStatus = qs('#icteMicStatus');\n      const btnStartVoice = qs('#icteStartVoice');\n      const btnStopVoice  = qs('#icteStopVoice');\n\n      let recognition = null;\n      let listening = false;\n\n      function setMicUI(on){\n        listening = on;\n        micDot.classList.toggle('on', on);\n        micStatus.textContent = on ? \"Mic: Listening\u2026\" : \"Mic: Off\";\n      }\n\n      function initRecognition(){\n        const SR = window.SpeechRecognition || window.webkitSpeechRecognition;\n        if(!SR) return null;\n        const r = new SR();\n        r.lang = 'en-US';\n        r.continuous = true;\n        r.interimResults = false;\n        r.maxAlternatives = 1;\n        return r;\n      }\n\n      function startListening(){\n        if(listening) return;\n        recognition = recognition || initRecognition();\n        if(!recognition){\n          alert(\"Speech Recognition is not available in this browser. Use Chrome\/Edge, or type your answers.\");\n          return;\n        }\n\n        recognition.onresult = (e)=>{\n          const res = e.results[e.results.length - 1];\n          const transcript = res && res[0] ? res[0].transcript : \"\";\n          handleVoiceTranscript(transcript);\n        };\n        recognition.onerror = ()=> setMicUI(false);\n        recognition.onend = ()=>{ if(listening){ try{ recognition.start(); }catch(_){ } } };\n\n        setMicUI(true);\n        try{ recognition.start(); }catch(_){ }\n      }\n\n      function stopListening(){\n        setMicUI(false);\n        try{ recognition && recognition.stop(); }catch(_){ }\n      }\n\n      btnStartVoice.addEventListener('click', startListening);\n      btnStopVoice.addEventListener('click', stopListening);\n\n      \/* =========================\n         Progress (localStorage)\n      ========================= *\/\n      const LS_KEY = \"icte_quantai_progress_v1\";\n      let progress = {};\n      try{ progress = JSON.parse(localStorage.getItem(LS_KEY) || \"{}\") || {}; }catch(_){ progress = {}; }\n\n      function saveProgress(){ localStorage.setItem(LS_KEY, JSON.stringify(progress)); renderProgress(); }\n      function markDone(key, scorePct){\n        progress[key] = { done:true, score: clamp(scorePct,0,100), ts: Date.now() };\n        saveProgress();\n      }\n      function resetProgress(){ localStorage.removeItem(LS_KEY); location.reload(); }\n      qs('#progressReset').addEventListener('click', resetProgress);\n\n      const checks = [\n        {k:\"rq\", label:\"RQ\/Hypothesis clarified\"},\n        {k:\"vars\", label:\"Variables defined\"},\n        {k:\"ops\", label:\"Operationalization drafted\"},\n        {k:\"items\", label:\"Survey items drafted\"},\n        {k:\"assump\", label:\"Assumptions checked\"},\n        {k:\"stats\", label:\"Stats interpreted\"},\n        {k:\"report\", label:\"Results reported\"},\n        {k:\"audit\", label:\"Audit trail noted\"}\n      ];\n      qs('#checksBank').innerHTML = checks.map(x=>`<span class=\"tag\">${esc(x.label)}<\/span>`).join(\"\");\n\n      function addCheck(k){\n        progress._checks = progress._checks || {};\n        progress._checks[k] = true;\n        saveProgress();\n      }\n\n      function renderProgress(){\n        const items = Object.values(progress).filter(p=>p && p.done);\n        const done = items.length;\n        const avg = done ? Math.round(items.reduce((s,p)=>s+(p.score||0),0)\/done) : 0;\n        qs('#pDone').textContent = String(done);\n        qs('#pScore').textContent = String(avg) + \"%\";\n        qs('#pChecks').textContent = String(Object.keys(progress._checks || {}).length);\n      }\n\n      \/* =========================\n         Instruction TTS\n      ========================= *\/\n      const SAY = {\n        \"overview-instr\":\"Overview. Learn how AI can support operationalization, survey drafting, basic statistics interpretation, and clear reporting while maintaining validity and researcher control.\",\n        \"conv-instr\":\"Conversation. Clarify the research question and hypothesis, define variables, choose measures, plan analysis, and plan reporting.\",\n        \"reading-instr\":\"Reading. Read about responsible AI use in quantitative research and answer the quiz.\",\n        \"toolkit-instr\":\"Toolkit. Use templates for operationalization, item quality, statistics guardrails, and reporting patterns.\",\n        \"prompts-instr\":\"Prompts. Copy prompts that force operational definitions, assumptions, and accurate reporting language.\",\n        \"list-instr\":\"Listening. Two instructors discuss measurement first and statistics second.\",\n        \"lab-instr\":\"Lab. Enter your setup and numbers, then generate operationalization, survey item suggestions, and a results paragraph. Verify all assumptions and computations.\",\n        \"problem-instr\":\"Problem-solving. Correct a causal claim, propose confounds, choose a better design, and rewrite accurately.\"\n      };\n      qsa('[data-say]').forEach(btn=>{\n        btn.addEventListener('click', async ()=>{\n          const k = btn.getAttribute('data-say');\n          if(SAY[k]) await speakAs(\"A\", SAY[k]);\n        });\n      });\n\n      qs('#speakActive').addEventListener('click', async ()=>{\n        const v = activeViewName();\n        const map = {\n          overview:\"Overview page. Outcomes and researcher-control rules for quantitative AI support.\",\n          conversation:\"Conversation page. Define variables and plan analysis.\",\n          reading:\"Reading page. Read and take the quiz.\",\n          toolkit:\"Toolkit page. Operationalization, items, stats guardrails, and reporting.\",\n          prompts:\"Prompts page. Copy and adapt quantitative prompts.\",\n          listening:\"Listening page. Two-speaker dialogue about measurement and interpretation.\",\n          lab:\"Lab page. Enter your setup and numbers to produce reporting scaffolds.\",\n          problem:\"Problem-solving page. Fix correlation versus causation and improve design.\",\n          progress:\"Progress page.\"\n        };\n        await speakAs(\"A\", map[v] || \"AI for quantitative research support lesson.\");\n      });\n\n      \/* =========================\n         Conversation coach (steps)\n      ========================= *\/\n      const convChat = qs('#convChat');\n      const convText = qs('#convText');\n      const convSend = qs('#convSend');\n      const convReset = qs('#convReset');\n      const convHear  = qs('#convHear');\n\n      let convStep = 0;\n      let lastCoachQ = \"\";\n\n      const convSteps = [\n        {\n          bot:\"Step 1: State your research question and a directional hypothesis (one sentence each).\",\n          check:(a)=>\/(hypoth|predict|expect)\/i.test(a) && a.split(\/\\s+\/).length >= 14,\n          tips:\"Include RQ + hypothesis using 'expect\/predict' and direction (higher\/lower).\"\n        },\n        {\n          bot:\"Step 2: Define DV, IV\/group, and at least one covariate (if relevant).\",\n          check:(a)=>\/(dv|dependent|outcome)\/i.test(a) && \/(iv|independent|group|treatment)\/i.test(a),\n          tips:\"Label DV and IV\/group clearly. Add covariate if needed (e.g., proficiency, gender, prior experience).\"\n        },\n        {\n          bot:\"Step 3: Operationalize the DV: instrument\/scale, scoring, and what higher scores mean.\",\n          check:(a)=>\/(scale|instrument|item|score|likert|test)\/i.test(a) && \/(higher|lower|means)\/i.test(a),\n          tips:\"Say how you measure DV and interpret scores (higher = more\/less).\"\n        },\n        {\n          bot:\"Step 4: Draft 4 survey items for one construct (one idea per item) + response anchors.\",\n          check:(a)=>\/(strongly disagree|strongly agree|1|5|7|likert)\/i.test(a) && (a.match(\/\\n\/g)||[]).length >= 3,\n          tips:\"Include response anchors (e.g., 1=Strongly disagree \u2026 5=Strongly agree).\"\n        },\n        {\n          bot:\"Step 5: Choose analysis (t-test\/correlation\/regression) and name 2 assumptions you will check.\",\n          check:(a)=>\/(t-test|ttest|correlation|regression|anova)\/i.test(a) && \/(normal|independ|homogen|linearity|outlier)\/i.test(a),\n          tips:\"State the test and at least two assumptions (normality, independence, homogeneity, linearity, outliers).\"\n        }\n      ];\n\n      function addMsg(who, text){\n        const div = document.createElement('div');\n        div.className = 'msg ' + (who==='You' ? 'user' : 'bot');\n        div.innerHTML = `<div class=\"who\">${esc(who)}<\/div><div class=\"bubble\">${esc(text)}<\/div>`;\n        convChat.appendChild(div);\n        convChat.scrollTop = convChat.scrollHeight;\n      }\n\n      async function coachAsk(){\n        const step = convSteps[convStep];\n        if(!step){\n          addMsg(\"Coach\",\"\u2705 Done. You defined RQ\/hypothesis, variables, operationalization, items, and an analysis plan with assumptions.\");\n          markDone(\"conversation\", 100);\n          addCheck(\"rq\"); addCheck(\"vars\"); addCheck(\"ops\"); addCheck(\"items\"); addCheck(\"assump\"); addCheck(\"audit\");\n          await speakAs(\"A\",\"Done. You clarified the research question, variables, operationalization, survey items, and analysis plan with assumptions.\");\n          return;\n        }\n        lastCoachQ = step.bot;\n        addMsg(\"Coach\", step.bot);\n        await speakAs(\"A\", step.bot);\n      }\n\n      async function handleConversationInput(text){\n        const a = norm(text);\n        if(!a) return;\n        addMsg(\"You\", a);\n\n        if(\/hypoth|predict|expect\/i.test(a)) addCheck(\"rq\");\n        if(\/dv|dependent|outcome|iv|independent|group|treatment\/i.test(a)) addCheck(\"vars\");\n        if(\/scale|instrument|likert|score|higher|lower\/i.test(a)) addCheck(\"ops\");\n        if(\/strongly disagree|strongly agree|likert\/i.test(a)) addCheck(\"items\");\n        if(\/normal|independ|homogen|linearity|outlier\/i.test(a)) addCheck(\"assump\");\n\n        const step = convSteps[convStep];\n        const ok = step.check(a);\n        const msg = ok ? \"\u2705 Good. Next.\" : \"\u26a0\ufe0f Try again. \" + step.tips;\n\n        addMsg(\"Coach\", msg);\n        await speakAs(\"A\", msg);\n\n        if(ok){ convStep++; setTimeout(coachAsk, 200); }\n      }\n\n      convSend.addEventListener('click', ()=>{ handleConversationInput(convText.value); convText.value=\"\"; });\n      convText.addEventListener('keydown', (e)=>{\n        if(e.key===\"Enter\"){ e.preventDefault(); handleConversationInput(convText.value); convText.value=\"\"; }\n      });\n      convHear.addEventListener('click', ()=> speakAs(\"A\", lastCoachQ || \"No question yet.\"));\n      convReset.addEventListener('click', ()=>{\n        convChat.innerHTML=\"\";\n        convStep=0;\n        addMsg(\"Coach\",\"Ready. Let\u2019s build a quantitative plan with researcher control.\");\n        coachAsk();\n      });\n\n      addMsg(\"Coach\",\"Ready. Let\u2019s build a quantitative plan with researcher control.\");\n      coachAsk();\n\n      \/* =========================\n         Voice transcript routing\n      ========================= *\/\n      function appendToField(el, text){\n        if(!el) return;\n        const t = norm(text);\n        if(!t) return;\n        el.value = (el.value ? (el.value + \" \") : \"\") + t;\n      }\n\n      function handleVoiceTranscript(t){\n        const text = norm(t);\n        if(!text) return;\n\n        const v = activeViewName();\n\n        if(v === \"conversation\"){\n          handleConversationInput(text);\n          return;\n        }\n\n        if(v === \"lab\"){\n          const a = qs('#qSetup');\n          const b = qs('#qNums');\n          if(a && !norm(a.value)) appendToField(a, text);\n          else appendToField(b, text);\n          speakAs(\"A\", \"I heard: \" + text);\n          return;\n        }\n\n        if(v === \"problem\"){\n          const A = qs('#psA');\n          const B = qs('#psB');\n          const C = qs('#psC');\n          const D = qs('#psD');\n          const targets = [A,B,C,D].filter(Boolean);\n          const target = targets.find(x => !norm(x.value)) || targets[0];\n          appendToField(target, text);\n          speakAs(\"A\", \"I heard: \" + text);\n          return;\n        }\n\n        speakAs(\"A\",\"I heard: \" + text);\n      }\n\n      \/* =========================\n         Reading TTS\n      ========================= *\/\n      qs('#readTextBtn').addEventListener('click', ()=>{\n        const parts = qsa('#readingText .reading-p').map(p=>p.textContent).join(\" \");\n        speakAs(\"A\", \"Reading. \" + parts);\n      });\n\n      \/* =========================\n         Quiz\n      ========================= *\/\n      const quiz = qs('#quiz');\n      const quizFb = qs('#quizFb');\n\n      const quizItems = [\n        { q:\"1) Operationalization means\u2026\",\n          ans:\"Turning a construct into measurable indicators with clear scoring\",\n          opts:[\n            \"Choosing any statistic you like\",\n            \"Turning a construct into measurable indicators with clear scoring\",\n            \"Writing only hypotheses\",\n            \"Replacing validity checks\"\n          ]\n        },\n        { q:\"2) A good survey item should\u2026\",\n          ans:\"Measure one idea clearly and avoid leading language\",\n          opts:[\n            \"Include two ideas to save time\",\n            \"Measure one idea clearly and avoid leading language\",\n            \"Guarantee causality\",\n            \"Use jargon to sound academic\"\n          ]\n        },\n        { q:\"3) A common interpretation error is\u2026\",\n          ans:\"Treating correlation as causation\",\n          opts:[\n            \"Reporting means and SDs\",\n            \"Treating correlation as causation\",\n            \"Checking assumptions\",\n            \"Describing limitations\"\n          ]\n        },\n        { q:\"4) Researcher control includes\u2026\",\n          ans:\"Checking validity, assumptions, and documenting AI use\",\n          opts:[\n            \"Copying AI output directly\",\n            \"Checking validity, assumptions, and documenting AI use\",\n            \"Ignoring measurement quality\",\n            \"Avoiding transparency\"\n          ]\n        }\n      ];\n\n      function renderQuiz(){\n        quiz.innerHTML = quizItems.map((it)=>{\n          const options = ['<option value=\"\">Choose\u2026<\/option>']\n            .concat(it.opts.map(o=>`<option value=\"${esc(o)}\">${esc(o)}<\/option>`))\n            .join(\"\");\n          return `\n            <div class=\"qitem\">\n              <div class=\"qtext\">${esc(it.q)}<\/div>\n              <select class=\"icte-select\" data-ans=\"${esc(it.ans)}\">${options}<\/select>\n            <\/div>\n          `;\n        }).join(\"\");\n      }\n      renderQuiz();\n\n      qs('#quizCheck').addEventListener('click', ()=>{\n        const sels = qsa('#quiz select');\n        let correct = 0;\n        sels.forEach(s=>{\n          const ok = s.value === s.getAttribute('data-ans');\n          s.style.borderColor = ok ? \"rgba(34,197,94,.6)\" : \"rgba(239,68,68,.6)\";\n          if(ok) correct++;\n        });\n        const pct = Math.round((correct \/ sels.length) * 100);\n        quizFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        quizFb.textContent = `Score: ${correct}\/${sels.length} (${pct}%).`;\n        if(pct>=70){ addCheck(\"ops\"); addCheck(\"stats\"); addCheck(\"report\"); }\n        markDone(\"reading_quiz\", pct);\n      });\n\n      \/* =========================\n         Toolkit content\n      ========================= *\/\n      qs('#tkOp').textContent =\n`OPERATIONALIZATION (template)\nConstruct:\nPopulation:\nVariable role: DV \/ IV \/ Covariate\nInstrument\/measure:\nScale type (Likert\/test\/behavioral log):\nExample item\/indicator:\nScoring (sum\/mean\/subscales):\nInterpretation (higher = ...):\nBoundary (does NOT capture):\nExpected direction (hypothesis):`;\n\n      qs('#tkItems').textContent =\n`SURVEY ITEM QUALITY CHECKLIST\n[ ] One idea per item (no double-barreled items)\n[ ] Clear time frame (e.g., \"in the past 2 weeks\")\n[ ] Avoid leading\/loaded wording\n[ ] Avoid absolute terms (always\/never) unless justified\n[ ] Balanced anchors (1\u20135 or 1\u20137) with labels\n[ ] Include at least one reverse-worded item (carefully)\n[ ] Pilot-test for clarity and cultural fit`;\n\n      qs('#tkStats').textContent =\n`BASIC STATS GUARDRAILS\n- Mean\/SD describe typical score + variability (not causality)\n- Correlation (r) = association; does not prove causation\n- For group differences, report: means, SDs, n, test, p, and effect size (if possible)\n- Check assumptions: independence, normality, equal variance (as relevant)\n- Interpret practical meaning, not just p-values`;\n\n      qs('#tkReport').textContent =\n`RESULTS REPORTING TEMPLATE (APA-friendly)\nWe examined [DV] across\/with [IV or predictor]. Descriptively, [Group A] had M=..., SD=..., (n=...), whereas [Group B] had M=..., SD=..., (n=...).\nA [test] indicated [significant\/non-significant] difference\/association, t(df)=..., p=..., [effect size if available].\nThis suggests [careful interpretation], noting [limitations\/assumptions\/context].`;\n\n      qs('#tkVR').textContent =\n`VALIDITY & RELIABILITY CHECKLIST\n[ ] Content validity: items cover the construct definition\n[ ] Face validity: items are understandable to participants\n[ ] Construct validity: aligns with theory; avoids contamination\n[ ] Reliability: internal consistency \/ stability (as appropriate)\n[ ] Pilot test: item clarity and time to complete\n[ ] Data quality: missingness, outliers, response patterns\n[ ] Transparency: document AI assistance and human decisions`;\n\n      qs('#toolkitSpeak').addEventListener('click', ()=>{\n        speakAs(\"A\",\"Toolkit. Use operationalization templates, item quality checks, statistics guardrails, and reporting patterns to keep quantitative work valid and clear.\");\n      });\n\n      \/* =========================\n         Prompts content\n      ========================= *\/\n      const p1 = qs('#p1'), p2 = qs('#p2'), p3 = qs('#p3'), p4 = qs('#p4'), pExample = qs('#pExample');\n\n      p1.textContent =\n`PROMPT 1 \u2014 OPERATIONALIZE VARIABLES\nContext:\n- Population: [who]\n- RQ\/Hypothesis: [text]\nTask:\nList DV, IV, and covariates.\nFor each variable provide:\n- operational definition\n- instrument\/scale\n- scoring\n- what higher scores mean\n- boundary (what it does NOT measure)\nRules:\n- Do not invent validated scales; offer options to verify.`;\n\n      p2.textContent =\n`PROMPT 2 \u2014 SURVEY ITEMS + SCALES\nConstruct: [name + definition]\nPopulation\/context: [who\/where]\nTask:\nDraft 8 items:\n- 6 standard items (one idea each)\n- 1 reverse-worded item\n- 1 attention-check item (ethical, non-deceptive)\nProvide:\n- recommended Likert anchors (1\u20135 or 1\u20137)\n- time frame wording\nRules:\n- Avoid leading language and absolutes.`;\n\n      p3.textContent =\n`PROMPT 3 \u2014 ANALYSIS PLAN + ASSUMPTIONS\nGiven:\n- DV: ...\n- IV\/predictors: ...\n- Design: (between-groups \/ within \/ correlational)\nTask:\nRecommend an analysis plan (t-test\/ANOVA\/correlation\/regression).\nFor each test:\n- assumptions to check\n- what diagnostics to run\n- what to report (numbers)\nRules:\n- No causal claims unless design supports it.`;\n\n      p4.textContent =\n`PROMPT 4 \u2014 CLEAR RESULTS PARAGRAPH\nInput results:\n[PASTE MEANS\/SDs, test statistic, df, p, effect size if any]\nTask:\nWrite a concise results paragraph with:\n- descriptives\n- test + p\n- effect size (or say what to compute)\n- cautious interpretation\nRules:\n- Keep claims consistent with design (association vs causation).`;\n\n      pExample.textContent =\n`EXAMPLE (snippet)\nDV: Speaking confidence (mean of 8 Likert items; higher = more confidence).\nIV: Chatbot usage frequency (sessions\/week).\nResult: r=.32, p=.01, n=80.\nReport: \"Chatbot usage frequency was moderately positively associated with speaking confidence (r=.32, p=.01), suggesting that students who reported more frequent use also reported higher confidence; however, causal direction cannot be inferred from correlational data.\"`;\n\n      qs('#promptsSpeak').addEventListener('click', ()=>{\n        speakAs(\"A\",\"Prompts. Use prompts to operationalize variables, draft survey items, plan analysis with assumptions, and report results accurately.\");\n      });\n\n      qs('#copyPrompts').addEventListener('click', ()=>{\n        const all =\n`PROMPT 1\\n${p1.textContent}\\n\\nPROMPT 2\\n${p2.textContent}\\n\\nPROMPT 3\\n${p3.textContent}\\n\\nPROMPT 4\\n${p4.textContent}\\n\\nEXAMPLE\\n${pExample.textContent}`;\n        navigator.clipboard.writeText(all)\n          .then(()=> speakAs(\"A\",\"Copied prompts.\"))\n          .catch(()=> alert(\"Clipboard blocked. Copy manually.\"));\n      });\n\n      \/* =========================\n         Listening\n      ========================= *\/\n      const listenFb = qs('#listenFb');\n      const listenQ  = qs('#listenQ');\n\n      const dialogue = [\n        {role:\"A\", text:\"I asked AI to interpret my results, and it said the treatment caused higher scores.\"},\n        {role:\"B\", text:\"First check your design. If it\u2019s correlational, you can only claim association, not causation.\"},\n        {role:\"A\", text:\"What should I report besides the p value?\"},\n        {role:\"B\", text:\"Report descriptives, the test statistic, degrees of freedom, and an effect size if possible. Also note assumptions.\"},\n        {role:\"A\", text:\"Can AI draft survey items safely?\"},\n        {role:\"B\", text:\"Yes, but you must pilot test, check validity, and ensure each item measures one clear idea.\"},\n        {role:\"A\", text:\"So measurement first, stats second.\"},\n        {role:\"B\", text:\"Exactly. Good measurement makes your statistics meaningful.\"}\n      ];\n\n      const listenItems = [\n        {q:\"1) If the design is correlational, you should report\u2026\", ans:\"Association, not causation\"},\n        {q:\"2) Good reporting includes\u2026\", ans:\"Descriptives, test statistic, p, and effect size where possible\"},\n        {q:\"3) AI-drafted survey items require\u2026\", ans:\"Pilot testing and validity checks\"},\n        {q:\"4) The key principle is\u2026\", ans:\"Measurement quality comes before statistical interpretation\"}\n      ];\n\n      function renderListenQ(){\n        const optsMap = {\n          \"Association, not causation\":[\n            \"Association, not causation\",\n            \"Causation immediately\",\n            \"No limitations needed\"\n          ],\n          \"Descriptives, test statistic, p, and effect size where possible\":[\n            \"Descriptives, test statistic, p, and effect size where possible\",\n            \"Only p-values\",\n            \"Only a graph with no numbers\"\n          ],\n          \"Pilot testing and validity checks\":[\n            \"Pilot testing and validity checks\",\n            \"Copying without checking\",\n            \"Avoiding item revision\"\n          ],\n          \"Measurement quality comes before statistical interpretation\":[\n            \"Measurement quality comes before statistical interpretation\",\n            \"Statistics replace measurement\",\n            \"Validity is optional\"\n          ]\n        };\n\n        listenQ.innerHTML = listenItems.map((it)=>{\n          const options = ['<option value=\"\">Choose\u2026<\/option>']\n            .concat((optsMap[it.ans]||[it.ans]).map(o=>`<option value=\"${esc(o)}\">${esc(o)}<\/option>`)).join(\"\");\n          return `\n            <div class=\"qitem\">\n              <div class=\"qtext\">${esc(it.q)}<\/div>\n              <select class=\"icte-select\" data-ans=\"${esc(it.ans)}\">${options}<\/select>\n            <\/div>\n          `;\n        }).join(\"\");\n      }\n      renderListenQ();\n\n      qs('#listenPlay').addEventListener('click', async ()=>{\n        if(googleVoicesEN.length >= 2 && voiceA === voiceB){\n          voiceB = googleVoicesEN.find(v => v !== voiceA) || voiceB;\n          voiceBSelect.value = String(googleVoicesEN.indexOf(voiceB));\n        }\n        await speakDialogue(dialogue);\n      });\n      qs('#listenStop').addEventListener('click', stopSpeak);\n\n      qs('#listenCheck').addEventListener('click', ()=>{\n        const sels = qsa('#listenQ select');\n        let correct = 0;\n        sels.forEach(s=>{\n          const ok = s.value === s.getAttribute('data-ans');\n          s.style.borderColor = ok ? \"rgba(34,197,94,.6)\" : \"rgba(239,68,68,.6)\";\n          if(ok) correct++;\n        });\n        const pct = Math.round((correct \/ sels.length) * 100);\n        listenFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        listenFb.textContent = `Score: ${correct}\/${sels.length} (${pct}%).`;\n        if(pct>=70){ addCheck(\"stats\"); addCheck(\"report\"); addCheck(\"assump\"); }\n        markDone(\"listening\", pct);\n      });\n\n      \/* =========================\n         Quant Lab (parse + scaffold)\n      ========================= *\/\n      const qSetup = qs('#qSetup');\n      const qNums = qs('#qNums');\n      const labOut = qs('#labOut');\n      const safePrompt = qs('#safePrompt');\n      const labFb = qs('#labFb');\n\n      function parseNumber(str){\n        const m = (str||\"\").match(\/-?\\d+(\\.\\d+)?\/);\n        return m ? Number(m[0]) : null;\n      }\n\n      function detectMode(txt){\n        const t = (txt||\"\").toLowerCase();\n        if(\/t\\s*\\(|t\\(\/.test(t) || \/\\bt\\s*=\\s*-?\\d\/.test(t)) return \"ttest\";\n        if(\/\\br\\s*=\\s*-?\\d\/.test(t) || \/\\br\\s*[<>=]\/.test(t)) return \"corr\";\n        if(\/m\\s*=|mean\/i.test(t)) return \"desc\";\n        return \"unknown\";\n      }\n\n      function buildQuantReport(setup, nums){\n        const mode = detectMode(nums);\n\n        const out = [];\n        out.push(`QUANT RESEARCH LAB OUTPUT (scaffold)\\n`);\n        out.push(`A) Operationalization (draft)`);\n        out.push(`- Identify DV\/IV\/covariates in your setup; ensure scoring rules and direction are explicit.`);\n        out.push(`- If using a scale: specify items, anchors, scoring (mean\/sum), and what higher scores mean.\\n`);\n\n        out.push(`B) Survey item suggestions (quality reminders)`);\n        out.push(`- One idea per item; add time frame; avoid leading language; include anchors; consider reverse item carefully.\\n`);\n\n        out.push(`C) Interpretation + reporting (based on your numbers)`);\n        if(mode === \"ttest\"){\n          out.push(`Detected: t-test style input. Ensure you report: Group means\/SDs\/n, t(df), p, and effect size (Cohen\u2019s d if possible).`);\n          out.push(`- Guardrail: Significant p-value indicates a difference, not necessarily practical importance. Check assumptions (independence, normality, equal variances).`);\n        }else if(mode === \"corr\"){\n          out.push(`Detected: correlation style input. Report: r, p, n, and direction (positive\/negative).`);\n          out.push(`- Guardrail: Correlation indicates association; do not claim causation. Consider confounds and directionality.`);\n        }else if(mode === \"desc\"){\n          out.push(`Detected: descriptives. Report: mean, SD, range (or min\/max), and what the scale represents.`);\n          out.push(`- Guardrail: Descriptives describe the sample; avoid generalizing without sampling justification.`);\n        }else{\n          out.push(`Could not detect a test type. Paste either a t-test summary (means\/SDs\/n + t(df), p) or correlation (r, p, n).`);\n        }\n\n        out.push(`\\nD) Draft results paragraph (fill numbers precisely)`);\n        out.push(`Use this structure and replace ... with your verified values:`);\n        out.push(`\"Descriptively, [Group\/overall] had M=..., SD=..., (n=...). A [t-test\/correlation] indicated [significant\/non-significant] [difference\/association], [stat]=..., p=..., [effect size]. This suggests ..., although interpretation should consider [assumptions\/limitations\/confounds].\"`);\n\n        out.push(`\\nE) What to compute next (if missing)`);\n        out.push(`- Effect size: Cohen\u2019s d for t-tests; r already is effect size for correlation; R\u00b2 for regression.`);\n        out.push(`- Confidence intervals where possible.`);\n\n        \/\/ heuristic scoring\n        let score = 100;\n        if((setup||\"\").length < 60) score -= 20;\n        if((nums||\"\").length < 60) score -= 25;\n        if(mode === \"unknown\") score -= 25;\n        score = clamp(score, 0, 100);\n\n        addCheck(\"ops\"); addCheck(\"items\"); addCheck(\"stats\"); addCheck(\"report\"); addCheck(\"audit\");\n\n        return {score, text: out.join(\"\\n\")};\n      }\n\n      function buildSafePrompt(setup, nums){\n        return `ROLE: You are a quantitative research assistant.\n\nCONTEXT (researcher-provided):\n${setup || \"[Add population, RQ\/hypothesis, DV, IV\/groups, covariates, planned analysis]\"}\n\nRESULTS (researcher-provided numbers):\n${nums || \"[Paste means\/SDs\/n + test statistic + p, OR r\/p\/n]\"}\n\nTASK (STRICT):\n1) Identify what test appears to be used (t-test\/correlation\/ANOVA\/regression) based ONLY on the text above.\n2) List what must be reported (descriptives, test statistic, df, p, effect size, assumptions).\n3) Draft a results paragraph that is accurate and cautious (association vs causation).\n4) If any key numbers are missing, say \"MISSING\" and tell me exactly what to compute or report next.\n\nRULES:\n- Do NOT invent numbers, df, p-values, effect sizes, or sample sizes.\n- Do NOT make causal claims unless design supports causality.\n- Use clear, APA-friendly reporting language.`;\n      }\n\n      qs('#labRun').addEventListener('click', ()=>{\n        const setup = norm(qSetup.value);\n        const nums = norm(qNums.value);\n        if(setup.length < 40 || nums.length < 40){\n          labFb.className = \"feedback bad\";\n          labFb.textContent = \"\u26a0\ufe0f Please add more detail to BOTH boxes (setup and numbers).\";\n          return;\n        }\n        const rr = buildQuantReport(setup, nums);\n        labOut.textContent = rr.text;\n        safePrompt.textContent = buildSafePrompt(setup, nums);\n\n        markDone(\"lab\", rr.score);\n        labFb.className = \"feedback \" + (rr.score>=70 ? \"ok\":\"bad\");\n        labFb.textContent = `Lab output generated. Completeness score: ${rr.score}%. Next: verify assumptions, compute missing effect sizes, and finalize reporting.`;\n      });\n\n      qs('#labCopy').addEventListener('click', async ()=>{\n        const pack = `LAB OUTPUT\\n${labOut.textContent}\\n\\nSAFE AI PROMPT\\n${safePrompt.textContent}`;\n        if(!pack.trim()){\n          labFb.className = \"feedback bad\";\n          labFb.textContent = \"\u26a0\ufe0f Run the lab first.\";\n          return;\n        }\n        try{\n          await navigator.clipboard.writeText(pack);\n          labFb.className = \"feedback ok\";\n          labFb.textContent = \"\u2705 Copied lab output + safe prompt.\";\n        }catch(_){\n          labFb.className = \"feedback bad\";\n          labFb.textContent = \"\u26a0\ufe0f Clipboard blocked. Copy manually from the boxes.\";\n        }\n      });\n\n      qs('#labReset').addEventListener('click', ()=>{\n        qSetup.value = \"\";\n        qNums.value = \"\";\n        labOut.textContent = \"\";\n        safePrompt.textContent = \"\";\n        labFb.className = \"feedback\";\n        labFb.textContent = \"\";\n      });\n\n      \/* =========================\n         Problem-solving checker\n      ========================= *\/\n      const psA = qs('#psA');\n      const psB = qs('#psB');\n      const psC = qs('#psC');\n      const psD = qs('#psD');\n      const psFb = qs('#psFb');\n\n      function countBullets(txt){ return (txt.match(\/^\\s*[-\u2022]\/gm)||[]).length; }\n\n      qs('#psCheck').addEventListener('click', ()=>{\n        const aOk = norm(psA.value).length >= 120 && \/(correlation|associate|caus|direction|confound)\/i.test(psA.value);\n        const bOk = countBullets(psB.value) >= 2;\n        const cOk = norm(psC.value).length >= 40 && \/(random|control|pre|post|longitud|matched|experiment)\/i.test(psC.value);\n        const dOk = norm(psD.value).length >= 90 && \/(associated|related|linked|predict|suggests)\/i.test(psD.value) && !\/(causes|proves)\/i.test(psD.value);\n\n        const pct = Math.round(((aOk?1:0)+(bOk?1:0)+(cOk?1:0)+(dOk?1:0))\/4*100);\n\n        psFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        psFb.textContent =\n          `Check: ${pct}%\\n` +\n          `- Correction (correlation \u2260 causation): ${aOk ? \"Yes\" : \"No\"}\\n` +\n          `- Confounds (>=2 bullets): ${bOk ? \"Yes\" : \"No\"}\\n` +\n          `- Improved design (causal support): ${cOk ? \"Yes\" : \"No\"}\\n` +\n          `- Accurate rewrite (association language, no 'causes'): ${dOk ? \"Yes\" : \"No\"}`;\n\n        markDone(\"problem_solving\", pct);\n        addCheck(\"stats\"); addCheck(\"report\"); addCheck(\"assump\"); addCheck(\"audit\");\n      });\n\n      qs('#psReset').addEventListener('click', ()=>{\n        psA.value = \"\";\n        psB.value = \"\";\n        psC.value = \"\";\n        psD.value = \"\";\n        psFb.className = \"feedback\";\n        psFb.textContent = \"\";\n      });\n\n      \/* =========================\n         Start state\n      ========================= *\/\n      renderProgress();\n\n    })();\n  <\/script>\n\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Overview Conversation Reading Quant Toolkit Prompts Listening Quant Research Lab Problem-solving Progress AI for Quantitative Research Use AI to support<\/p>\n","protected":false},"author":1,"featured_media":796,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_layout":"default_layout","footnotes":""},"categories":[52,45],"tags":[],"class_list":["post-795","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-for-research","category-ai-for-teachers"],"_links":{"self":[{"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/posts\/795","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/comments?post=795"}],"version-history":[{"count":1,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/posts\/795\/revisions"}],"predecessor-version":[{"id":797,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/posts\/795\/revisions\/797"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/media\/796"}],"wp:attachment":[{"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/media?parent=795"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/categories?post=795"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/tags?post=795"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}