{"id":724,"date":"2026-03-04T08:11:22","date_gmt":"2026-03-04T08:11:22","guid":{"rendered":"https:\/\/i-cte.org\/robot\/?p=724"},"modified":"2026-03-04T09:33:56","modified_gmt":"2026-03-04T09:33:56","slug":"money-and-shopping","status":"publish","type":"post","link":"https:\/\/i-cte.org\/robot\/money-and-shopping\/","title":{"rendered":"Money and shopping"},"content":{"rendered":"\n<!-- \u2705 ICTE Chatbot Lesson \u2014 Personal Best (B1) Unit 9 (WP-safe single block) -->\n<div id=\"icte-u9\">\n\n  <!-- \u2705 TOP MENU -->\n  <nav class=\"icte-menu\" aria-label=\"Unit 9 lesson navigation\">\n    <a href=\"#\" class=\"is-current\" data-view=\"conversation\">Conversation<\/a>\n    <a href=\"#\" data-view=\"vocab\">Vocabulary<\/a>\n    <a href=\"#\" data-view=\"grammar\">Grammar<\/a>\n    <a href=\"#\" data-view=\"discussion\">Discussion<\/a>\n    <a href=\"#\" data-view=\"reading\">Reading<\/a>\n    <a href=\"#\" data-view=\"listening\">Listening<\/a>\n    <a href=\"#\" data-view=\"problemsolving\">Problem-solving<\/a>\n    <a href=\"#\" data-view=\"progress\">Progress<\/a>\n  <\/nav>\n\n  <section class=\"icte-shell\" aria-label=\"ICTE Unit 9 practice\">\n\n    <!-- \u2705 Header -->\n    <header class=\"icte-hero\">\n      <div class=\"icte-hero__text\">\n        <h2>Unit 9 \u2014 Money and shopping<\/h2>\n        <p class=\"muted\">\n          Practice <b>used to<\/b> (past habits\/states), <b>money verbs<\/b> (borrow, save, spend, owe, etc.),\n          <b>shopping vocabulary<\/b> (discount, receipt, refund\u2026), and <b>the passive<\/b> (auctions).\n        <\/p>\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        <label class=\"icte-label\">\n          Voice (Narrator)\n          <select id=\"icteVoiceSelect\" class=\"icte-select\" aria-label=\"Voice selection\"><\/select>\n        <\/label>\n\n        <div class=\"icte-small muted\">\n          Tip: If you don\u2019t see voices yet, click anywhere once and wait 2\u20133 seconds.\n        <\/div>\n      <\/div>\n    <\/header>\n\n    <!-- \u2705 Views -->\n    <main class=\"icte-main\">\n\n      <!-- ===================== -->\n      <!-- \u2705 1) CONVERSATION -->\n      <!-- ===================== -->\n      <section class=\"view is-active\" data-view=\"conversation\" aria-label=\"Conversation practice\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>1) Conversation (Voice Interactive)<\/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=\"convReset\">Reset<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">\n            Speak your answers. Try to use <b>used to<\/b> (past habits\/states) and at least one <b>money verb<\/b>.\n            Example: <i>I used to waste money on snacks, but now I save more.<\/i>\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 (optional)...\" autocomplete=\"off\" \/>\n            <button class=\"btn\" id=\"convSend\" type=\"button\">Send<\/button>\n            <button class=\"btn ghost\" id=\"convHear\" type=\"button\">\ud83d\udd0a Read last question<\/button>\n          <\/div>\n\n          <div class=\"muted icte-small\">\n            Targets: used to \/ didn\u2019t use to \/ Did you use to\u2026? + money &#038; shopping vocabulary.\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 2) VOCABULARY -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"vocab\" aria-label=\"Vocabulary practice\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>2) Vocabulary (Money verbs + Shopping)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"vocab-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"vocabReset\">Reset<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">\n            Match the words to the meanings, then complete the sentences using the same vocabulary.\n          <\/p>\n\n          <div class=\"grid2\">\n            <div>\n              <h4 class=\"h4\">A) Matching<\/h4>\n              <div id=\"vocabMatch\" class=\"stack\"><\/div>\n              <button class=\"btn\" id=\"vocabCheck\" type=\"button\">Check<\/button>\n              <div class=\"feedback\" id=\"vocabFb\" aria-live=\"polite\"><\/div>\n            <\/div>\n\n            <div>\n              <h4 class=\"h4\">B) Use the words (Fill in the blanks)<\/h4>\n              <div id=\"vocabUse\" class=\"stack\"><\/div>\n              <button class=\"btn\" id=\"vocabUseCheck\" type=\"button\">Check<\/button>\n              <div class=\"feedback\" id=\"vocabUseFb\" aria-live=\"polite\"><\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 3) GRAMMAR -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"grammar\" aria-label=\"Grammar practice\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>3) Grammar \u2014 used to + the passive<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"gram-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"gramReset\">Reset<\/button>\n            <\/div>\n          <\/div>\n\n          <div class=\"note\">\n            <b>used to<\/b> = past habits\/states (true in the past, not true now).<br>\n            Questions\/negatives: <b>Did you use to\u2026?<\/b> \/ <b>I didn\u2019t use to\u2026<\/b><br><br>\n            <b>Passive<\/b>: be + past participle. Use <b>by<\/b> to say who did it.\n          <\/div>\n\n          <div id=\"gramQuiz\" class=\"stack\"><\/div>\n          <button class=\"btn\" id=\"gramCheck\" type=\"button\">Check<\/button>\n          <div class=\"feedback\" id=\"gramFb\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 4) DISCUSSION -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"discussion\" aria-label=\"Discussion practice\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>4) Discussion (Voice or typing)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"disc-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"discNext\">Next question<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">\n            Answer with reasons. Include at least <b>2 vocabulary items<\/b> and at least <b>one<\/b> target grammar form:\n            <i>used to<\/i> or a <i>passive sentence<\/i>.\n          <\/p>\n\n          <div class=\"qa\">\n            <div class=\"q\" id=\"discQ\">Click <b>Next question<\/b> to begin.<\/div>\n            <textarea id=\"discA\" class=\"textarea\" rows=\"4\" placeholder=\"Write your answer here...\"><\/textarea>\n            <div class=\"row\">\n              <button class=\"btn\" id=\"discCheck\" type=\"button\">Check my language<\/button>\n              <button class=\"btn ghost\" id=\"discSpeakQ\" type=\"button\">\ud83d\udd0a Read question<\/button>\n            <\/div>\n            <div class=\"feedback\" id=\"discFb\" aria-live=\"polite\"><\/div>\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 5) READING -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"reading\" aria-label=\"Reading comprehension\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>5) Reading \u2014 \u201cFrom zero to Zara\u201d (used to)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"read-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini\" type=\"button\" id=\"readTextBtn\">\ud83d\udd0a Read the text<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">\n            Read the text, then answer the questions.\n          <\/p>\n\n          <article class=\"reading\" id=\"readingText\">\n            <div class=\"reading-title\">From zero to Zara (shortened)<\/div>\n            <div class=\"reading-p\"><b>1<\/b> Amancio was born in 1936. His father didn\u2019t earn much money and the family sometimes couldn\u2019t afford food.<\/div>\n            <div class=\"reading-p\"><b>2<\/b> His mother used to ask for credit at the grocery store. One day they said no, so Amancio decided to quit school and get a job.<\/div>\n            <div class=\"reading-p\"><b>3<\/b> Clothes used to be very expensive and customers didn\u2019t use to buy many. Amancio realized people would spend more if clothes were cheaper.<\/div>\n            <div class=\"reading-p\"><b>4<\/b> He started his own business, borrowed money from the bank, and in 1975 he opened his first Zara store.<\/div>\n            <div class=\"reading-p\"><b>5<\/b> Today Zara is in many countries, but he still lives where he grew up.<\/div>\n          <\/article>\n\n          <div class=\"grid2\">\n            <div>\n              <h4 class=\"h4\">A) Main idea<\/h4>\n              <div class=\"qitem\">\n                <div class=\"qtext\">1) What is the best summary?<\/div>\n                <select class=\"icte-select\" id=\"rQ1\">\n                  <option value=\"\">Choose\u2026<\/option>\n                  <option value=\"A\">A: Zara became successful because clothes were always expensive.<\/option>\n                  <option value=\"B\">B: Amancio started with very little, learned about clothes, borrowed money, and built Zara.<\/option>\n                  <option value=\"C\">C: Amancio never worked in shops.<\/option>\n                <\/select>\n              <\/div>\n\n              <h4 class=\"h4\" style=\"margin-top:14px;\">B) Headings \u2192 Paragraphs<\/h4>\n              <p class=\"muted icte-small\">Match each heading to a paragraph number (1\u20135).<\/p>\n              <div id=\"readMatch\" class=\"stack\"><\/div>\n\n              <button class=\"btn\" id=\"readCheck\" type=\"button\">Check<\/button>\n              <div class=\"feedback\" id=\"readFb\" aria-live=\"polite\"><\/div>\n            <\/div>\n\n            <div>\n              <h4 class=\"h4\">C) Find evidence<\/h4>\n              <div id=\"readShort\" class=\"stack\"><\/div>\n              <button class=\"btn\" id=\"readShortCheck\" type=\"button\">Check<\/button>\n              <div class=\"feedback\" id=\"readShortFb\" aria-live=\"polite\"><\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 6) LISTENING -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"listening\" aria-label=\"Listening comprehension\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>6) Listening \u2014 Shopping centers &#038; bargains (TTS)<\/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 listening (TTS)<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"listenStop\">\u23f9 Stop<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">\n            Click <b>Play listening<\/b>. Listen and complete the gaps about Trajan\u2019s Market, the Grand Bazaar, and shopping habits.\n          <\/p>\n\n          <div id=\"listenGaps\" class=\"stack\"><\/div>\n          <button class=\"btn\" id=\"listenCheck\" type=\"button\">Check<\/button>\n          <div class=\"feedback\" id=\"listenFb\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 7) PROBLEM-SOLVING -->\n      <!-- ===================== -->\n      <section class=\"view\" data-view=\"problemsolving\" aria-label=\"Problem-solving tasks\">\n        <div class=\"card\">\n          <div class=\"card-h\">\n            <h3>7) Problem-solving (Real-life shopping scenarios)<\/h3>\n            <div class=\"card-actions\">\n              <button class=\"btn mini\" type=\"button\" data-say=\"prob-instr\">\ud83d\udd0a Read instructions<\/button>\n              <button class=\"btn mini ghost\" type=\"button\" id=\"probReset\">Reset<\/button>\n            <\/div>\n          <\/div>\n\n          <p class=\"muted\">\n            Choose the best solution. Then write one sentence using <b>used to<\/b> OR a <b>passive sentence<\/b>.\n          <\/p>\n\n          <div id=\"probSet\" class=\"stack\"><\/div>\n          <button class=\"btn\" id=\"probCheck\" type=\"button\">Check<\/button>\n          <div class=\"feedback\" id=\"probFb\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/section>\n\n      <!-- ===================== -->\n      <!-- \u2705 8) 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=\"pVocab\">0<\/div>\n              <div class=\"muted\">Vocab used (detected)<\/div>\n            <\/div>\n          <\/div>\n\n          <div class=\"note\">\n            Completion is saved in your browser (local storage). If you change device\/browser, progress resets.\n          <\/div>\n\n          <h4 class=\"h4\">Vocabulary Bank (Unit 9)<\/h4>\n          <div class=\"bank\" id=\"vocabBank\"><\/div>\n        <\/div>\n      <\/section>\n\n    <\/main>\n  <\/section>\n\n  <style>\n    \/* ===== WP-SAFE STYLES (scoped) ===== *\/\n    #icte-u9 *{ box-sizing:border-box; }\n    #icte-u9{\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-u9 .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-u9 .icte-menu a{\n      display:inline-block;\n      color:#fff;\n      text-decoration:none;\n      font-weight:700;\n      padding:8px 10px;\n      border-radius:999px;\n      margin:0 3px;\n      opacity:.92;\n      transition:.15s;\n    }\n    #icte-u9 .icte-menu a:hover{ opacity:1; background:rgba(255,255,255,.14); }\n    #icte-u9 .icte-menu a.is-current{ background:#fff; color:var(--dark); opacity:1; }\n\n    #icte-u9 .icte-shell{ max-width:1100px; margin:0 auto; }\n    #icte-u9 .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-u9 .icte-hero{ grid-template-columns:1fr; } }\n\n    #icte-u9 h2{ margin:0 0 6px 0; font-size:22px; }\n    #icte-u9 .muted{ color:var(--muted); }\n\n    #icte-u9 .icte-hero__controls{\n      border-left:1px dashed var(--line);\n      padding-left:14px;\n    }\n    @media (max-width: 920px){\n      #icte-u9 .icte-hero__controls{ border-left:none; padding-left:0; border-top:1px dashed var(--line); padding-top:12px; }\n    }\n\n    #icte-u9 .icte-row{ display:flex; gap:8px; flex-wrap:wrap; }\n    #icte-u9 .icte-label{ display:block; font-size:12px; font-weight:800; margin-top:10px; }\n    #icte-u9 .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-u9 .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:800;\n    }\n    #icte-u9 .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-u9 .dot.on{\n      background:#22c55e;\n      box-shadow:0 0 0 4px rgba(34,197,94,.18);\n    }\n\n    #icte-u9 .btn{\n      border:none;\n      padding:10px 12px;\n      border-radius:12px;\n      background:var(--green);\n      color:#fff;\n      font-weight:800;\n      cursor:pointer;\n      transition:.15s;\n    }\n    #icte-u9 .btn:hover{ filter:brightness(.95); transform:translateY(-1px); }\n    #icte-u9 .btn:active{ transform:translateY(0); }\n    #icte-u9 .btn.ghost{\n      background:#fff;\n      color:#111827;\n      border:1px solid var(--line);\n    }\n    #icte-u9 .btn.mini{ padding:8px 10px; border-radius:10px; font-size:13px; }\n    #icte-u9 .icte-small{ font-size:12px; }\n\n    #icte-u9 .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-u9 .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-u9 .card-h h3{ margin:0; font-size:18px; }\n    #icte-u9 .card-actions{ display:flex; gap:8px; flex-wrap:wrap; justify-content:flex-end; }\n\n    #icte-u9 .view{ display:none; }\n    #icte-u9 .view.is-active{ display:block; }\n\n    #icte-u9 .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-u9 .msg{ margin:10px 0; display:flex; gap:10px; align-items:flex-start; }\n    #icte-u9 .who{\n      min-width:72px;\n      font-weight:900;\n      font-size:12px;\n      color:#93c5fd;\n      text-transform:uppercase;\n      letter-spacing:.06em;\n    }\n    #icte-u9 .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    }\n    #icte-u9 .msg.user .who{ color:#86efac; }\n    #icte-u9 .msg.user .bubble{ background:rgba(34,197,94,.10); border-color:rgba(34,197,94,.18); }\n\n    #icte-u9 .chatbar{\n      margin-top:10px;\n      display:flex;\n      gap:8px;\n      align-items:center;\n    }\n    #icte-u9 .input{\n      flex:1;\n      padding:12px 12px;\n      border:1px solid var(--line);\n      border-radius:12px;\n      outline:none;\n    }\n    #icte-u9 .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    #icte-u9 .grid2{\n      display:grid;\n      grid-template-columns:1fr 1fr;\n      gap:14px;\n      margin-top:10px;\n    }\n    @media (max-width: 920px){ #icte-u9 .grid2{ grid-template-columns:1fr; } }\n\n    #icte-u9 .stack{ display:flex; flex-direction:column; gap:10px; }\n    #icte-u9 .h4{ margin:0 0 6px 0; font-size:15px; }\n    #icte-u9 .qitem{\n      padding:10px;\n      border:1px solid var(--line);\n      border-radius:14px;\n      background:#fafafa;\n    }\n    #icte-u9 .qtext{ font-weight:800; margin-bottom:8px; }\n    #icte-u9 .row{ display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }\n\n    #icte-u9 .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:700;\n      display:none;\n      white-space:pre-line;\n    }\n    #icte-u9 .feedback.ok{ display:block; border-color:rgba(34,197,94,.35); background:#ecfdf5; }\n    #icte-u9 .feedback.bad{ display:block; border-color:rgba(239,68,68,.35); background:#fef2f2; }\n\n    #icte-u9 .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-u9 .reading{\n      border:1px solid var(--line);\n      border-radius:14px;\n      padding:12px;\n      background:#fff;\n      margin-top:10px;\n    }\n    #icte-u9 .reading-title{ font-weight:900; margin-bottom:8px; }\n    #icte-u9 .reading-p{ padding:8px 0; border-top:1px dashed var(--line); }\n    #icte-u9 .reading-p:first-of-type{ border-top:none; }\n\n    #icte-u9 .qa .q{\n      padding:12px;\n      border-radius:14px;\n      border:1px solid var(--line);\n      background:#fff;\n      font-weight:900;\n    }\n\n    #icte-u9 .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-u9 .progress-grid{ grid-template-columns:1fr; } }\n    #icte-u9 .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-u9 .pnum{ font-size:28px; font-weight:1000; }\n\n    #icte-u9 .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-u9 .tag{\n      border:1px solid var(--line);\n      background:#f9fafb;\n      padding:6px 10px;\n      border-radius:999px;\n      font-weight:800;\n      font-size:13px;\n    }\n  <\/style>\n\n  <script>\n    (function(){\n      const root = document.getElementById('icte-u9');\n      if(!root) return;\n\n      \/* ========= Helpers ========= *\/\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 lower = (s)=> norm(s).toLowerCase();\n      const esc = (s)=> (s||\"\").replace(\/[&<>\"']\/g, m=>({ \"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#039;\" }[m]));\n      const shuffle = (arr)=> arr.map(v=>({v, r:Math.random()})).sort((a,b)=>a.r-b.r).map(o=>o.v);\n\n      \/* ========= Navigation ========= *\/\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\n      \/* ========= Speech (TTS + ASR) ========= *\/\n      const micDot = qs('#icteMicDot');\n      const micStatus = qs('#icteMicStatus');\n      const voiceSel = qs('#icteVoiceSelect');\n      const btnStartVoice = qs('#icteStartVoice');\n      const btnStopVoice = qs('#icteStopVoice');\n\n      let chosenVoice = null;\n      let recognition = null;\n      let listening = false;\n      let lastPromptSpoken = \"\";\n\n      function loadVoices(){\n        if(!window.speechSynthesis) return;\n        const all = speechSynthesis.getVoices() || [];\n        let list = all.filter(v => (v.lang||\"\").toLowerCase().startsWith(\"en\"));\n        if(list.length === 0) list = all;\n\n        voiceSel.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          voiceSel.appendChild(opt);\n        });\n\n        chosenVoice = list[0] || null;\n        voiceSel.onchange = ()=>{\n          const idx = parseInt(voiceSel.value,10);\n          chosenVoice = list[idx] || chosenVoice;\n        };\n      }\n      if(window.speechSynthesis){\n        loadVoices();\n        speechSynthesis.onvoiceschanged = loadVoices;\n      }\n\n      function speak(text){\n        const t = norm(text);\n        if(!t || !window.speechSynthesis) return;\n        speechSynthesis.cancel();\n        const u = new SpeechSynthesisUtterance(t);\n        if(chosenVoice) u.voice = chosenVoice;\n        u.rate = 1.02; u.pitch = 1.0; u.volume = 1.0;\n        speechSynthesis.speak(u);\n      }\n      function stopSpeak(){ if(window.speechSynthesis) speechSynthesis.cancel(); }\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        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 = ()=>{\n          if(listening){ try{ recognition.start(); }catch(_){ } }\n        };\n        setMicUI(true);\n        try{ recognition.start(); }catch(_){ }\n      }\n      function stopListening(){\n        setMicUI(false);\n        try{ recognition && recognition.stop(); }catch(_){ }\n      }\n      btnStartVoice.addEventListener('click', startListening);\n      btnStopVoice.addEventListener('click', stopListening);\n\n      \/* ========= Progress ========= *\/\n      const LS_KEY = \"icte_u9_progress_v1\";\n      const progress = JSON.parse(localStorage.getItem(LS_KEY) || \"{}\");\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      \/* ========= Content: Vocabulary ========= *\/\n      const vocabMoney = [\n        {word:\"be worth\", def:\"have a value of a certain amount of money\"},\n        {word:\"borrow\", def:\"take money from someone and return it later\"},\n        {word:\"lend\", def:\"give money to someone and expect it back\"},\n        {word:\"owe\", def:\"need to pay money back\"},\n        {word:\"pay back\", def:\"return money you borrowed\"},\n        {word:\"save\", def:\"keep money and not spend it\"},\n        {word:\"spend\", def:\"use money to buy something\"},\n        {word:\"waste\", def:\"spend money on unnecessary things\"},\n        {word:\"earn\", def:\"make money from work\"},\n        {word:\"can afford\", def:\"have enough money to buy something\"},\n        {word:\"get paid\", def:\"receive money for work\"},\n        {word:\"own\", def:\"have something as your property\"}\n      ];\n\n      const vocabShop = [\n        {word:\"discount\", def:\"a lower price (e.g., 30% off)\"},\n        {word:\"receipt\", def:\"paper that shows what you bought and paid\"},\n        {word:\"refund\", def:\"money you get back when you return something\"},\n        {word:\"exchange\", def:\"change an item for another one\"},\n        {word:\"return\", def:\"take something back to the store\"},\n        {word:\"try on\", def:\"put on clothing to see if it fits\"},\n        {word:\"dressing room\", def:\"place to try on clothes\"},\n        {word:\"cash register\", def:\"machine where you pay in a store\"},\n        {word:\"line \/ queue\", def:\"people waiting (US\/UK)\"},\n        {word:\"window shopping\", def:\"looking without buying\"},\n        {word:\"bargain\", def:\"something very cheap for its value\"},\n        {word:\"shopping center \/ mall\", def:\"a large building with many stores\"}\n      ];\n\n      const vocabAll = [...vocabMoney, ...vocabShop];\n      const bank = qs('#vocabBank');\n      bank.innerHTML = vocabAll.map(v=>`<span class=\"tag\" title=\"${esc(v.def)}\">${esc(v.word)}<\/span>`).join(\"\");\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\n        qs('#pDone').textContent = String(done);\n        qs('#pScore').textContent = String(avg) + \"%\";\n\n        const used = new Set();\n        const txt = (progress._vocabUsedText||\"\");\n        vocabAll.forEach(w=>{\n          if(lower(txt).includes(lower(w.word))) used.add(w.word);\n        });\n        qs('#pVocab').textContent = String(used.size);\n      }\n\n      \/* ========= Instruction TTS ========= *\/\n      const SAY = {\n        \"conv-instr\":\n          \"Conversation. Answer the questions using used to and money or shopping vocabulary.\",\n        \"vocab-instr\":\n          \"Vocabulary. Match the words to meanings. Then complete the sentences. Check your answers.\",\n        \"gram-instr\":\n          \"Grammar. Choose the correct form of used to, or the passive form with be plus past participle.\",\n        \"disc-instr\":\n          \"Discussion. Include at least two vocabulary items and one used to sentence or one passive sentence.\",\n        \"read-instr\":\n          \"Reading. Read about Amancio Ortega and Zara. Answer main idea, headings, and evidence questions.\",\n        \"list-instr\":\n          \"Listening. Click play. Listen and complete the gaps about markets and shopping centers.\",\n        \"prob-instr\":\n          \"Problem-solving. Choose the best solution. Then write one sentence using used to or the passive.\"\n      };\n      qsa('[data-say]').forEach(btn=>{\n        btn.addEventListener('click', ()=>{\n          const k = btn.getAttribute('data-say');\n          if(SAY[k]) speak(SAY[k]);\n        });\n      });\n\n      \/* ========= 1) Conversation ========= *\/\n      const convChat = qs('#convChat');\n      const convText = qs('#convText');\n      const convSend = qs('#convSend');\n      const convHear = qs('#convHear');\n      const convReset = qs('#convReset');\n\n      let convStep = 0;\n      const convSteps = [\n        {\n          bot: \"Hi! Welcome to Unit 9. Do you enjoy shopping or hate it? Give two reasons.\",\n          check: (a)=> a.length >= 12,\n          tips: \"Write at least two reasons (e.g., bargains, queues, refunds).\"\n        },\n        {\n          bot: \"When you were a child, what did you use to spend money on? (Use: used to\u2026) \",\n          check: (a)=> \/\\bused to\\b\/i.test(a),\n          tips: \"Example: I used to spend my money on comics.\"\n        },\n        {\n          bot: \"Did your parents use to give you pocket money (allowance)? Answer with: Yes, they did \/ No, they didn\u2019t.\",\n          check: (a)=> \/\\bdid\\b.*\\buse to\\b\/i.test(a) || \/\\byes\\b.*\\bdid\\b\/i.test(a) || \/\\bno\\b.*\\bdidn'?t\\b\/i.test(a),\n          tips: \"Try: Yes, they did. \/ No, they didn\u2019t.\"\n        },\n        {\n          bot: \"Tell me: do you prefer paying with cash or card? Use one money verb (save, spend, waste, afford, owe).\",\n          check: (a)=> \/(cash|card|credit)\/i.test(a) && \/(save|spend|waste|afford|owe|borrow|pay back|earn|get paid)\/i.test(a),\n          tips: \"Example: I prefer card because I can track how much I spend.\"\n        },\n        {\n          bot: \"Make one passive sentence about an auction. Use: was\/were + past participle (e.g., was sold).\",\n          check: (a)=> \/\\b(was|were|is|are)\\b\\s+\\w+ed\\b\/i.test(a) || \/\\b(was|were)\\b\\s+\\b(sold|made|worn|driven|painted|written)\\b\/i.test(a),\n          tips: \"Example: The painting was sold for a high price.\"\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      function botAsk(){\n        const step = convSteps[convStep];\n        if(!step){\n          addMsg(\"Bot\",\"Great work! You finished Unit 9 conversation. Try other sections.\");\n          speak(\"Great work! You finished Unit 9 conversation. Try other sections.\");\n          markDone(\"conversation\", 100);\n          return;\n        }\n        addMsg(\"Bot\", step.bot);\n        lastPromptSpoken = step.bot;\n        speak(step.bot);\n      }\n\n      function scoreAnswer(a){\n        const step = convSteps[convStep];\n        if(!step) return {ok:true, msg:\"\"};\n        const ok = step.check(norm(a));\n        const msg = ok ? \"\u2705 Good. Nice use of the target language.\" : \"\u26a0\ufe0f Try again. \" + step.tips;\n        return {ok, msg};\n      }\n\n      function handleConversationInput(text){\n        const a = norm(text);\n        if(!a) return;\n        addMsg(\"You\", a);\n\n        progress._vocabUsedText = (progress._vocabUsedText||\"\") + \" \" + a;\n        saveProgress();\n\n        const {ok, msg} = scoreAnswer(a);\n        addMsg(\"Bot\", msg);\n        speak(msg);\n\n        if(ok){ convStep++; setTimeout(botAsk, 450); }\n        else { setTimeout(()=> speak(\"Please try again. \" + convSteps[convStep].bot), 450); }\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', ()=> speak(lastPromptSpoken || \"No question yet.\"));\n      convReset.addEventListener('click', ()=>{\n        convChat.innerHTML = \"\";\n        convStep = 0;\n        addMsg(\"Bot\",\"Ready! Start Voice (optional) and answer. Let\u2019s begin.\");\n        botAsk();\n      });\n\n      addMsg(\"Bot\",\"Ready! Start Voice (optional) and answer. Let\u2019s begin.\");\n      botAsk();\n\n      \/* ========= Route voice transcripts ========= *\/\n      function activeViewName(){\n        const v = qs('.view.is-active');\n        return v ? v.getAttribute('data-view') : \"conversation\";\n      }\n      function handleVoiceTranscript(t){\n        const text = norm(t);\n        if(!text) return;\n\n        const v = activeViewName();\n        if(v === \"conversation\"){ handleConversationInput(text); return; }\n        if(v === \"discussion\"){\n          const ta = qs('#discA');\n          ta.value = (ta.value ? (ta.value + \" \") : \"\") + text;\n          speak(\"I heard: \" + text);\n          return;\n        }\n        const input = qs('.view.is-active input.input');\n        if(input){ input.value = text; speak(\"I heard: \" + text); return; }\n        speak(\"I heard: \" + text);\n      }\n\n      \/* ========= 2) Vocabulary ========= *\/\n      const vocabMatch = qs('#vocabMatch');\n      const vocabFb = qs('#vocabFb');\n\n      const matchSet = shuffle([\n        {word:\"borrow\", def:\"take money from someone and return it later\"},\n        {word:\"save\", def:\"keep money and not spend it\"},\n        {word:\"spend\", def:\"use money to buy something\"},\n        {word:\"be worth\", def:\"have a value of a certain amount of money\"},\n        {word:\"discount\", def:\"a lower price (e.g., 30% off)\"},\n        {word:\"receipt\", def:\"paper that shows what you bought and paid\"},\n        {word:\"refund\", def:\"money you get back when you return something\"},\n        {word:\"exchange\", def:\"change an item for another one\"},\n        {word:\"line \/ queue\", def:\"people waiting (US\/UK)\"},\n        {word:\"window shopping\", def:\"looking without buying\"}\n      ]);\n\n      function renderVocabMatching(){\n        const defs = shuffle(matchSet.map(x=>x.def));\n        vocabMatch.innerHTML = matchSet.map((x,i)=>{\n          const options = ['<option value=\"\">Choose meaning\u2026<\/option>']\n            .concat(defs.map(d=>`<option value=\"${esc(d)}\">${esc(d)}<\/option>`))\n            .join(\"\");\n          return `\n            <div class=\"qitem\">\n              <div class=\"qtext\">${i+1}) <b>${esc(x.word)}<\/b><\/div>\n              <select class=\"icte-select\" data-ans=\"${esc(x.def)}\">${options}<\/select>\n            <\/div>\n          `;\n        }).join(\"\");\n      }\n      renderVocabMatching();\n\n      qs('#vocabCheck').addEventListener('click', ()=>{\n        const sels = qsa('#vocabMatch 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        vocabFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        vocabFb.textContent = `Score: ${correct}\/${sels.length} (${pct}%).`;\n        markDone(\"vocab_match\", pct);\n      });\n\n      const vocabUse = qs('#vocabUse');\n      const vocabUseFb = qs('#vocabUseFb');\n      const useItems = [\n        {sent:\"I didn\u2019t have enough money, so I ____ money from my friend.\", ans:\"borrow\"},\n        {sent:\"I want to ____ money for a new laptop.\", ans:\"save\"},\n        {sent:\"I try not to ____ money on things I don\u2019t need.\", ans:\"waste\"},\n        {sent:\"This jacket was on sale with a 30% ____.\", ans:\"discount\"},\n        {sent:\"Keep the ____ in case you want a refund.\", ans:\"receipt\"},\n        {sent:\"If it doesn\u2019t fit, you can ____ it for a different size.\", ans:\"exchange\"}\n      ];\n\n      function renderVocabUse(){\n        const bank2 = shuffle(useItems.map(x=>x.ans));\n        vocabUse.innerHTML = useItems.map((x,i)=>{\n          const opts = ['<option value=\"\">Choose\u2026<\/option>']\n            .concat(bank2.map(w=>`<option value=\"${esc(w)}\">${esc(w)}<\/option>`)).join(\"\");\n          return `\n            <div class=\"qitem\">\n              <div class=\"qtext\">${i+1}) ${esc(x.sent)}<\/div>\n              <select class=\"icte-select\" data-ans=\"${esc(x.ans)}\">${opts}<\/select>\n            <\/div>\n          `;\n        }).join(\"\");\n      }\n      renderVocabUse();\n\n      qs('#vocabUseCheck').addEventListener('click', ()=>{\n        const sels = qsa('#vocabUse 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        vocabUseFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        vocabUseFb.textContent = `Score: ${correct}\/${sels.length} (${pct}%).`;\n        markDone(\"vocab_use\", pct);\n      });\n\n      qs('#vocabReset').addEventListener('click', ()=>{\n        renderVocabMatching();\n        renderVocabUse();\n        vocabFb.style.display=\"none\";\n        vocabUseFb.style.display=\"none\";\n      });\n\n      \/* ========= 3) Grammar ========= *\/\n      const gramQuiz = qs('#gramQuiz');\n      const gramFb = qs('#gramFb');\n\n      const gramItems = [\n        {q:\"When I was a child, I ____ save up to buy books.\", opts:[\"use to\",\"used to\",\"using to\"], ans:\"used to\"},\n        {q:\"I ____ buy many clothes when I was younger.\", opts:[\"didn't use to\",\"didn't used to\",\"don't use to\"], ans:\"didn't use to\"},\n        {q:\"____ you use to get pocket money?\", opts:[\"Did\",\"Do\",\"Does\"], ans:\"Did\"},\n        {q:\"Which sentence is correct?\", opts:[\"He didn't used to save.\",\"He didn't use to save.\",\"He didn't use save.\"], ans:\"He didn't use to save.\"},\n\n        {q:\"The painting ____ sold for $120 million.\", opts:[\"was\",\"is\",\"were\"], ans:\"was\"},\n        {q:\"This jacket was worn ____ Michael Jackson.\", opts:[\"by\",\"to\",\"from\"], ans:\"by\"},\n        {q:\"The car ____ driven by an actor.\", opts:[\"were\",\"was\",\"are\"], ans:\"was\"},\n        {q:\"Vegemite is ____ by millions of Australians.\", opts:[\"eat\",\"ate\",\"eaten\"], ans:\"eaten\"}\n      ];\n\n      function renderGrammar(){\n        gramQuiz.innerHTML = gramItems.map((it,i)=>{\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\">${i+1}) ${esc(it.q)}<\/div>\n              <select class=\"icte-select\" data-ans=\"${esc(it.ans)}\">${options}<\/select>\n            <\/div>\n          `;\n        }).join(\"\");\n      }\n      renderGrammar();\n\n      qs('#gramCheck').addEventListener('click', ()=>{\n        const sels = qsa('#gramQuiz 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        gramFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        gramFb.textContent = `Score: ${correct}\/${sels.length} (${pct}%).`;\n        markDone(\"grammar\", pct);\n      });\n\n      qs('#gramReset').addEventListener('click', ()=>{\n        renderGrammar();\n        gramFb.style.display=\"none\";\n      });\n\n      \/* ========= 4) Discussion ========= *\/\n      const discQ = qs('#discQ');\n      const discA = qs('#discA');\n      const discFb = qs('#discFb');\n\n      const discQs = [\n        \"How has shopping changed from the past to now? Use: used to + one shopping word (receipt, refund, queue, online\u2026).\",\n        \"Do you prefer malls or small independent shops? Give reasons using at least two shopping words.\",\n        \"Do you think people get paid too much in some professions? Use earn\/get paid\/waste and explain.\",\n        \"Tell a childhood memory using used to (money, toys, vacations, food, bedtime).\",\n        \"Make one passive sentence about auctions (was sold \/ was made \/ was worn \/ was driven).\"\n      ];\n      let discIdx = -1;\n\n      function nextDiscQ(){\n        discIdx = (discIdx + 1) % discQs.length;\n        discQ.textContent = discQs[discIdx];\n        discA.value = \"\";\n        discFb.style.display = \"none\";\n        speak(discQs[discIdx]);\n      }\n      qs('#discNext').addEventListener('click', nextDiscQ);\n      qs('#discSpeakQ').addEventListener('click', ()=> speak(discQs[Math.max(0,discIdx)] || \"Click next question to begin.\"));\n\n      function detectTargets(text){\n        const t = lower(text);\n        const vocabHits = vocabAll.filter(v => t.includes(lower(v.word))).map(v=>v.word);\n        const hasUsedTo = \/\\bused to\\b|\\bdidn't use to\\b|\\bdid you use to\\b\/i.test(text);\n        const hasPassive = \/\\b(was|were|is|are)\\b\\s+\\b(sold|made|worn|driven|painted|written|eaten)\\b\/i.test(text);\n        return { vocabHits, hasUsedTo, hasPassive };\n      }\n\n      qs('#discCheck').addEventListener('click', ()=>{\n        const ans = norm(discA.value);\n        if(!ans){\n          discFb.className = \"feedback bad\";\n          discFb.textContent = \"Please write or speak an answer first.\";\n          return;\n        }\n\n        progress._vocabUsedText = (progress._vocabUsedText||\"\") + \" \" + ans;\n        saveProgress();\n\n        const {vocabHits, hasUsedTo, hasPassive} = detectTargets(ans);\n        const okV = vocabHits.length >= 2;\n        const okG = hasUsedTo || hasPassive;\n\n        let score = 0;\n        if(okV) score += 50;\n        if(okG) score += 50;\n\n        discFb.className = \"feedback \" + (score>=70 ? \"ok\":\"bad\");\n        discFb.textContent =\n          `Detected vocab: ${vocabHits.slice(0,8).join(\", \") || \"none\"}\\n` +\n          `Grammar: ${okG ? \"\u2705 used to or passive detected\" : \"\u26a0\ufe0f add used to OR a passive sentence\"}\\n` +\n          `Score: ${score}%`;\n\n        markDone(\"discussion\", score);\n      });\n\n      \/* ========= 5) Reading ========= *\/\n      const readMatch = qs('#readMatch');\n      const readFb = qs('#readFb');\n      const readShort = qs('#readShort');\n      const readShortFb = qs('#readShortFb');\n\n      const headings = [\n        \"Early life and money problems\",\n        \"Credit at the grocery store\",\n        \"Clothes were expensive\",\n        \"Starting a business\",\n        \"Zara today\"\n      ];\n      const headAns = {\n        \"Early life and money problems\":\"1\",\n        \"Credit at the grocery store\":\"2\",\n        \"Clothes were expensive\":\"3\",\n        \"Starting a business\":\"4\",\n        \"Zara today\":\"5\"\n      };\n\n      function renderReadMatch(){\n        readMatch.innerHTML = headings.map(h=>{\n          return `\n            <div class=\"qitem\">\n              <div class=\"qtext\">${esc(h)}<\/div>\n              <select class=\"icte-select\" data-ans=\"${esc(headAns[h])}\">\n                <option value=\"\">Paragraph\u2026<\/option>\n                <option>1<\/option><option>2<\/option><option>3<\/option><option>4<\/option><option>5<\/option>\n              <\/select>\n            <\/div>\n          `;\n        }).join(\"\");\n      }\n      renderReadMatch();\n\n      const shortItems = [\n        {q:\"Which paragraph mentions credit at a grocery store?\", ans:\"2\"},\n        {q:\"Which paragraph says clothes used to be expensive?\", ans:\"3\"},\n        {q:\"Which paragraph mentions borrowing money from the bank?\", ans:\"4\"},\n        {q:\"Which paragraph explains Zara is now in many countries?\", ans:\"5\"}\n      ];\n\n      function renderReadShort(){\n        readShort.innerHTML = shortItems.map((it,i)=>`\n          <div class=\"qitem\">\n            <div class=\"qtext\">${i+1}) ${esc(it.q)}<\/div>\n            <select class=\"icte-select\" data-ans=\"${esc(it.ans)}\">\n              <option value=\"\">Choose\u2026<\/option>\n              <option>1<\/option><option>2<\/option><option>3<\/option><option>4<\/option><option>5<\/option>\n            <\/select>\n          <\/div>\n        `).join(\"\");\n      }\n      renderReadShort();\n\n      qs('#readCheck').addEventListener('click', ()=>{\n        let score = 0;\n\n        const q1 = qs('#rQ1');\n        const ok1 = q1.value === \"B\";\n        if(ok1) score += 40;\n        q1.style.borderColor = ok1 ? \"rgba(34,197,94,.6)\" : \"rgba(239,68,68,.6)\";\n\n        const sels = qsa('#readMatch 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        score += Math.round((correct \/ sels.length) * 60);\n\n        readFb.className = \"feedback \" + (score>=70 ? \"ok\":\"bad\");\n        readFb.textContent = `Score: ${score}%. (Main idea + headings)`;\n        markDone(\"reading\", score);\n      });\n\n      qs('#readShortCheck').addEventListener('click', ()=>{\n        const sels = qsa('#readShort 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        readShortFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        readShortFb.textContent = `Score: ${correct}\/${sels.length} (${pct}%).`;\n        markDone(\"reading_evidence\", pct);\n      });\n\n      qs('#readTextBtn').addEventListener('click', ()=>{\n        const text = qsa('#readingText .reading-p').map(p=>p.textContent).join(\" \");\n        speak(\"Reading text. \" + text);\n      });\n\n      \/* ========= 6) Listening ========= *\/\n      const listeningScript =\n        \"Today on Learning Curve, it\u2019s all about shopping. One of the oldest markets in Europe is Trajan\u2019s Market in Rome. \" +\n        \"It was built more than one thousand nine hundred years ago and used to be very busy. Shoppers used to buy animals, fruit, vegetables, fish, oil, and spices. \" +\n        \"The Grand Bazaar of Istanbul dates from the fifteenth century and has nearly five thousand shops. Today, more than two hundred and fifty thousand shoppers visit it every day. \" +\n        \"At modern malls, people meet up with friends, see a movie, or return something to a store. Some shoppers look for bargains during a sale, and keep receipts for refunds.\";\n\n      const gapItems = [\n        {q:\"1) Trajan\u2019s Market is in ____.\", ans:\"Rome\"},\n        {q:\"2) It was built more than ____ years ago.\", ans:\"1900\"},\n        {q:\"3) The Grand Bazaar dates from the ____ century.\", ans:\"fifteenth\"},\n        {q:\"4) It has nearly ____ shops.\", ans:\"5000\"},\n        {q:\"5) More than ____ shoppers visit it every day.\", ans:\"250000\"},\n        {q:\"6) In malls, people can meet up with ____.\", ans:\"friends\"},\n        {q:\"7) People keep a ____ for refunds.\", ans:\"receipt\"},\n        {q:\"8) A cheaper price is a ____.\", ans:\"discount\"}\n      ];\n\n      const listenGaps = qs('#listenGaps');\n      const listenFb = qs('#listenFb');\n\n      function renderListeningGaps(){\n        const wordBank = shuffle([\"Rome\",\"1900\",\"fifteenth\",\"5000\",\"250000\",\"friends\",\"receipt\",\"discount\"]);\n        listenGaps.innerHTML =\n          `<div class=\"note\"><b>Word bank:<\/b> ${wordBank.map(w=>`<span class=\"tag\">${esc(w)}<\/span>`).join(\" \")}<\/div>` +\n          gapItems.map((it)=>{\n            const opts = ['<option value=\"\">Choose\u2026<\/option>']\n              .concat(wordBank.map(w=>`<option value=\"${esc(w)}\">${esc(w)}<\/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)}\">${opts}<\/select>\n              <\/div>\n            `;\n          }).join(\"\");\n      }\n      renderListeningGaps();\n\n      qs('#listenPlay').addEventListener('click', ()=> speak(listeningScript));\n      qs('#listenStop').addEventListener('click', stopSpeak);\n\n      qs('#listenCheck').addEventListener('click', ()=>{\n        const sels = qsa('#listenGaps 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        markDone(\"listening\", pct);\n      });\n\n      \/* ========= 7) Problem-solving ========= *\/\n      const probSet = qs('#probSet');\n      const probFb = qs('#probFb');\n\n      const problems = [\n        {\n          scenario: \"Scenario 1: You bought a jacket in the sale, but it doesn\u2019t fit. What should you do?\",\n          choices: [\n            \"Throw away the receipt and keep it forever.\",\n            \"Return it and exchange it for the right size (keep the receipt).\",\n            \"Pay more money and never try it on.\"\n          ],\n          correct: 1,\n          followup: \"Write ONE sentence using used to (e.g., I used to\u2026 \/ I didn\u2019t use to\u2026).\"\n        },\n        {\n          scenario: \"Scenario 2: The cashier gave you the wrong change. What\u2019s the best plan?\",\n          choices: [\n            \"Say nothing and waste money.\",\n            \"Go back to the cash register and explain the problem politely.\",\n            \"Borrow money from strangers and leave.\"\n          ],\n          correct: 1,\n          followup: \"Write ONE passive sentence (e.g., The wrong change was given\u2026).\"\n        },\n        {\n          scenario: \"Scenario 3: The line (queue) is very long. You feel annoyed. What can you do?\",\n          choices: [\n            \"Start shouting at everyone.\",\n            \"Go window shopping and come back later.\",\n            \"Steal the item.\"\n          ],\n          correct: 1,\n          followup: \"Write ONE sentence using a shopping word + a money verb (spend\/save\/afford).\"\n        }\n      ];\n\n      function renderProblems(){\n        probSet.innerHTML = problems.map((p,idx)=>{\n          const opts = p.choices.map((c,i)=>`\n            <label class=\"opt\" style=\"display:flex;gap:10px;align-items:flex-start;padding:8px 10px;border:1px solid var(--line);border-radius:12px;background:#fff;\">\n              <input type=\"radio\" name=\"prob_${idx}\" value=\"${i}\">\n              <span>${esc(c)}<\/span>\n            <\/label>\n          `).join(\"\");\n          return `\n            <div class=\"qitem\">\n              <div class=\"qtext\">${idx+1}) ${esc(p.scenario)}<\/div>\n              <div class=\"stack\" style=\"gap:8px;margin-top:8px\">${opts}<\/div>\n              <div class=\"muted icte-small\" style=\"margin-top:8px\">${esc(p.followup)}<\/div>\n              <textarea class=\"textarea\" rows=\"2\" data-followup=\"${idx}\" placeholder=\"Write your sentence here...\"><\/textarea>\n            <\/div>\n          `;\n        }).join(\"\");\n      }\n      renderProblems();\n\n      function okFollowup(idx, txt){\n        const t = txt.trim();\n        if(idx === 0) return \/\\bused to\\b|\\bdidn't use to\\b\/i.test(t) && t.length >= 10;\n        if(idx === 1) return \/\\b(was|were|is|are)\\b\/i.test(t) && \/\\bby\\b|\\bgiven\\b|\\bpaid\\b|\\bsold\\b\/i.test(t) && t.length >= 10;\n        return (\/(receipt|refund|discount|queue|line|bargain|cash|card|exchange|return)\/i.test(t) &&\n                \/(spend|save|afford|borrow|pay back|waste|earn|get paid)\/i.test(t) && t.length >= 10);\n      }\n\n      qs('#probCheck').addEventListener('click', ()=>{\n        let score = 0;\n        const total = problems.length * 2;\n\n        problems.forEach((p,idx)=>{\n          const sel = qs(`input[name=\"prob_${idx}\"]:checked`);\n          const okChoice = sel && parseInt(sel.value,10) === p.correct;\n          if(okChoice) score++;\n\n          const ta = qs(`textarea[data-followup=\"${idx}\"]`);\n          const txt = norm(ta.value);\n          const okSentence = okFollowup(idx, txt);\n          if(okSentence) score++;\n\n          ta.style.borderColor = okSentence ? \"rgba(34,197,94,.6)\" : \"rgba(239,68,68,.6)\";\n        });\n\n        const pct = Math.round((score \/ total) * 100);\n        probFb.className = \"feedback \" + (pct>=70 ? \"ok\":\"bad\");\n        probFb.textContent =\n          `Score: ${score}\/${total} (${pct}%).\\nTip: Follow-up must match the target grammar\/vocab for each scenario.`;\n        markDone(\"problemsolving\", pct);\n      });\n\n      qs('#probReset').addEventListener('click', ()=>{\n        renderProblems();\n        probFb.style.display=\"none\";\n      });\n\n      \/* ========= Init ========= *\/\n      renderProgress();\n\n    })();\n  <\/script>\n\n<\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Conversation Vocabulary Grammar Discussion Reading Listening Problem-solving Progress Unit 9 \u2014 Money and shopping Practice used to (past habits\/states), money<\/p>\n","protected":false},"author":1,"featured_media":732,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_layout":"default_layout","footnotes":""},"categories":[37],"tags":[],"class_list":["post-724","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-b1"],"_links":{"self":[{"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/posts\/724","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=724"}],"version-history":[{"count":1,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/posts\/724\/revisions"}],"predecessor-version":[{"id":726,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/posts\/724\/revisions\/726"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/media\/732"}],"wp:attachment":[{"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/media?parent=724"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/categories?post=724"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/i-cte.org\/robot\/wp-json\/wp\/v2\/tags?post=724"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}