{"id":113,"date":"2026-04-16T02:42:55","date_gmt":"2026-04-16T02:42:55","guid":{"rendered":"https:\/\/allenglish4u.com\/ielts\/"},"modified":"2026-07-05T02:44:43","modified_gmt":"2026-07-05T02:44:43","slug":"ielts","status":"publish","type":"page","link":"https:\/\/allenglish4u.com\/vi\/ielts\/","title":{"rendered":"IELTS Preparation \u2014 All English 4U"},"content":{"rendered":"\n<style>\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Fraunces:opsz,wght@9..144,700&display=swap');\n\/* AE4U: escape theme constrained wrapper -> full-bleed design *\/\n.entry-content,.wp-block-post-content,.is-layout-constrained{max-width:none !important;width:auto !important;margin-left:0 !important;margin-right:0 !important;padding-left:0 !important;padding-right:0 !important;}\nbody.entry-content>*,body.wp-block-post-content>*{max-width:none !important;}\nbody.entry-content.wp-block-post-title,body.wp-block-post-title{display:none !important;}\n\n\/* ============================ TOKENS ============================ *\/\n:root{\n  --jakarta:'Plus Jakarta Sans',system-ui,-apple-system,sans-serif;\n  --fraunces:'Fraunces',Georgia,serif;\n\n  \/* light surfaces *\/\n  --app:#F0F7FF;\n  --surface-2:#F8FAFF;\n  --surface:#FFFFFF;\n\n  \/* text *\/\n  --ink:#0F172A;\n  --muted:#475569;\n  --subtle:#94A3B8;\n  --border:#E2E8F0;\n\n  \/* dark *\/\n  --dark-1:#050E20;\n  --dark-2:#0A1628;\n  --dark-3:#0D2352;\n\n  \/* THIS PAGE accent = blue (tweakable hue mixes toward cyan) *\/\n  --accent-deep:#1245A8;\n  --accent:#2563EB;\n  --accent-bright:#3B82F6;\n  --cyan:#06B6D4;\n\n  \/* radii *\/\n  --r-xs:6px; --r-sm:10px; --r-md:16px; --r-lg:22px; --r-xl:32px;\n\n  \/* shadows *\/\n  --sh-card:0 2px 8px rgba(0,0,0,.06);\n  --sh-lg:0 12px 40px rgba(0,0,0,.12);\n  --sh-glow:0 8px 24px rgba(37,99,235,.32);\n\n  \/* motion *\/\n  --ease:160ms ease;\n  --smooth:280ms cubic-bezier(.4,0,.2,1);\n  --spring:400ms cubic-bezier(.34,1.56,.64,1);\n  --motion-scale:1;        \/* tweak: animation speed *\/\n  --gauge-intensity:1;     \/* tweak: 3D gauge intensity *\/\n\n  --maxw:1200px;\n}\n\n*{box-sizing:border-box;margin:0;padding:0}\nhtml{scroll-behavior:smooth}\nbody{\n  font-family:var(--jakarta);\n  background:var(--app);\n  color:var(--ink);\n  font-size:16px;\n  line-height:1.6;\n  -webkit-font-smoothing:antialiased;\n  overflow-x:hidden;\n}\nbody.no-motion{scroll-behavior:auto}\na{color:inherit;text-decoration:none}\nimg{display:block;max-width:100%}\nbutton{font-family:inherit;cursor:pointer;border:none;background:none}\n:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}\n.hero :focus-visible,.quiz-side :focus-visible,.yt-sec :focus-visible,footer :focus-visible{outline-color:#7CA9FF}\n.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}\n.eyebrow{\n  display:inline-flex;align-items:center;gap:9px;\n  font-size:12.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;\n  color:var(--accent);\n}\n.eyebrow::before{content:\"\";width:7px;height:7px;border-radius:50%;flex:0 0 auto;\n  background:currentColor;box-shadow:0 0 0 4px color-mix(in srgb,currentColor 16%,transparent)}\n.sec-head.center.eyebrow{justify-content:center}\n.hero.eyebrow{color:#8EB5FF}\n.hero.eyebrow::before{box-shadow:0 0 10px rgba(59,130,246,.7),0 0 0 4px color-mix(in srgb,currentColor 22%,transparent)}\nsection{position:relative}\n\n\/* gradient text helper *\/\n.grad{\n  background:linear-gradient(100deg,var(--accent-deep),var(--accent) 45%,var(--accent-bright) 75%,var(--cyan));\n  -webkit-background-clip:text;background-clip:text;color:transparent;\n}\n\n\/* ============================ REVEALS ============================ *\/\n.reveal{opacity:0;transform:translateY(26px);\n  transition:opacity calc(.7s * var(--motion-scale)) cubic-bezier(.4,0,.2,1),\n             transform calc(.7s * var(--motion-scale)) cubic-bezier(.4,0,.2,1);\n  transition-delay:var(--d,0s);\n}\n.reveal.in{opacity:1;transform:none}\nbody.no-motion.reveal{opacity:1!important;transform:none!important;transition:none!important}\n\n\/* ============================ HEADER ============================ *\/\n.hdr{\n  position:fixed;top:0;left:0;right:0;z-index:90;\n  transition:background var(--smooth),box-shadow var(--smooth),border-color var(--smooth);\n  border-bottom:1px solid transparent;\n}\n.hdr-inner{max-width:var(--maxw);margin:0 auto;padding:16px 24px;\n  display:flex;align-items:center;gap:28px}\n.brand{display:flex;align-items:center;gap:11px;font-weight:800;font-size:17px;letter-spacing:-.01em;color:#fff;transition:color var(--smooth);white-space:nowrap}\n.brand img{width:40px;height:40px;border-radius:11px;object-fit:cover;box-shadow:0 2px 10px rgba(0,0,0,.25)}\n.nav{display:flex;align-items:center;gap:4px;margin-left:6px}\n.nav a{\n  position:relative;font-size:14.5px;font-weight:600;color:rgba(255,255,255,.74);\n  padding:8px 13px;border-radius:var(--r-xs);transition:color var(--ease),background var(--ease);\n}\n.nav a:hover{color:#fff;background:rgba(255,255,255,.08)}\n.nav a.active{color:#fff}\n.nav a.active::after{\n  content:\"\";position:absolute;left:13px;right:13px;bottom:2px;height:2.5px;border-radius:2px;\n  background:linear-gradient(90deg,var(--accent),var(--accent-bright));\n}\n.hdr-right{margin-left:auto;display:flex;align-items:center;gap:10px}\n.icon-btn{\n  width:40px;height:40px;border-radius:var(--r-xs);display:grid;place-items:center;\n  color:rgba(255,255,255,.82);transition:background var(--ease),color var(--ease);\n}\n.icon-btn:hover{background:rgba(255,255,255,.1);color:#fff}\n.pill{\n  display:inline-flex;align-items:center;gap:7px;font-weight:700;font-size:14px;color:#fff;\n  padding:10px 18px;border-radius:999px;\n  background:linear-gradient(100deg,var(--accent-deep),var(--accent) 55%,var(--accent-bright));\n  box-shadow:var(--sh-glow);transition:transform var(--spring),box-shadow var(--smooth);\n}\n.pill:hover{transform:translateY(-2px) scale(1.03);box-shadow:0 12px 30px rgba(37,99,235,.45)}\n.hamb{display:none}\n\n\/* scrolled state *\/\n.hdr.solid{background:rgba(255,255,255,.82);backdrop-filter:blur(18px) saturate(160%);\n  -webkit-backdrop-filter:blur(18px) saturate(160%);\n  border-bottom-color:var(--border);box-shadow:0 1px 0 rgba(15,23,42,.04),0 8px 24px rgba(15,23,42,.05)}\n.hdr.solid.brand{color:var(--ink)}\n.hdr.solid.nav a{color:var(--muted)}\n.hdr.solid.nav a:hover{color:var(--ink);background:rgba(37,99,235,.07)}\n.hdr.solid.nav a.active{color:var(--accent)}\n.hdr.solid.icon-btn{color:var(--muted)}\n.hdr.solid.icon-btn:hover{background:rgba(37,99,235,.08);color:var(--accent)}\n\n\/* mobile menu *\/\n.mobile-menu{\n  position:fixed;inset:0 0 0 auto;width:min(82vw,340px);z-index:100;\n  background:var(--dark-2);transform:translateX(100%);transition:transform var(--smooth);\n  padding:84px 26px 30px;display:flex;flex-direction:column;gap:6px;\n  box-shadow:-20px 0 60px rgba(0,0,0,.5);\n}\n.mobile-menu.open{transform:none}\n.mobile-menu a{color:rgba(255,255,255,.8);font-weight:600;font-size:17px;padding:13px 12px;border-radius:var(--r-sm)}\n.mobile-menu a:hover{background:rgba(255,255,255,.06);color:#fff}\n.mobile-menu a.active{color:var(--accent-bright)}\n.menu-backdrop{position:fixed;inset:0;background:rgba(3,8,20,.55);backdrop-filter:blur(2px);z-index:99;opacity:0;pointer-events:none;transition:opacity var(--smooth)}\n.menu-backdrop.open{opacity:1;pointer-events:auto}\n.menu-close{position:absolute;top:22px;right:22px;color:#fff}\n\n\/* ============================ HERO ============================ *\/\n.hero{\n  position:relative;background:\n    radial-gradient(900px 540px at 78% 12%,rgba(37,99,235,.30),transparent 60%),\n    radial-gradient(700px 500px at 12% 86%,rgba(6,182,212,.14),transparent 55%),\n    linear-gradient(165deg,var(--dark-1),var(--dark-2) 55%,var(--dark-3));\n  color:#fff;overflow:hidden;padding:148px 0 96px;\n}\n.hero::after{content:\"\";position:absolute;left:0;right:0;bottom:-1px;height:120px;\n  background:linear-gradient(to bottom,transparent,var(--app))}\n.hero-grid{position:absolute;inset:0;opacity:.5;\n  background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),\n    linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);\n  background-size:64px 64px;mask-image:radial-gradient(900px 600px at 70% 20%,#000,transparent 75%)}\n.hero-inner{position:relative;max-width:var(--maxw);margin:0 auto;padding:0 24px;\n  display:grid;grid-template-columns:1.05fr.95fr;gap:48px;align-items:center}\n.hero h1{\n  font-family:var(--fraunces);font-weight:700;line-height:1.05;letter-spacing:-.02em;\n  font-size:clamp(40px,5.6vw,72px);margin:18px 0 0;text-wrap:balance;\n}\n.hero h1 .grad{filter:drop-shadow(0 6px 30px rgba(37,99,235,.5))}\n.hero p.sub{color:rgba(255,255,255,.82);font-size:clamp(15px,1.5vw,18px);max-width:60ch;margin:22px 0 0}\n.chips{display:flex;flex-wrap:wrap;gap:10px;margin-top:28px}\n.chip{\n  display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:rgba(255,255,255,.88);\n  padding:9px 14px;border-radius:999px;background:rgba(255,255,255,.06);\n  border:1px solid rgba(255,255,255,.12);backdrop-filter:blur(6px);\n}\n.chip.dot{width:7px;height:7px;border-radius:50%;background:var(--accent-bright);box-shadow:0 0 10px var(--accent-bright)}\n.chip:nth-child(2) .dot{background:var(--cyan);box-shadow:0 0 10px var(--cyan)}\n.hero-cta{display:flex;flex-wrap:wrap;gap:14px;margin-top:32px}\n.btn{\n  display:inline-flex;align-items:center;gap:9px;font-weight:700;font-size:15.5px;\n  padding:14px 24px;border-radius:var(--r-sm);transition:transform var(--spring),box-shadow var(--smooth),background var(--ease),border-color var(--ease);\n}\n.btn-primary{color:#fff;background:linear-gradient(100deg,var(--accent-deep),var(--accent) 55%,var(--accent-bright));box-shadow:var(--sh-glow)}\n.btn-primary:hover{transform:translateY(-2px) scale(1.02);box-shadow:0 14px 34px rgba(37,99,235,.5)}\n.btn-ghost{color:#fff;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.18)}\n.btn-ghost:hover{background:rgba(255,255,255,.12);transform:translateY(-2px)}\n\n\/* 3D hero stage *\/\n.stage{position:relative;aspect-ratio:1\/1;width:100%;max-width:480px;margin-left:auto}\n#gauge-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}\n.stage-num{\n  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;\n  pointer-events:none;\n}\n.stage-num.band{font-family:var(--fraunces);font-weight:700;font-size:clamp(48px,9vw,84px);\n  line-height:1;letter-spacing:-.02em;background:linear-gradient(180deg,#fff,#bcd4ff);\n  -webkit-background-clip:text;background-clip:text;color:transparent;\n  text-shadow:0 0 40px rgba(59,130,246,.4)}\n.stage-num.band-cap{font-size:12px;font-weight:700;letter-spacing:.22em;color:rgba(255,255,255,.55);\n  text-transform:uppercase;margin-top:8px}\n\/* static fallback gauge *\/\n.static-gauge{position:absolute;inset:0;display:none;place-items:center}\n.static-gauge svg{width:100%;height:100%;filter:drop-shadow(0 8px 34px rgba(37,99,235,.42))}\nbody.fallback-3d #gauge-canvas{display:none}\nbody.fallback-3d.static-gauge{display:grid}\n\n\/* ============================ SECTION SHELL ============================ *\/\n.sec{padding:clamp(64px,9vw,128px) 0}\n.sec-head{max-width:720px;margin-bottom:46px}\n.sec-head.center{margin-left:auto;margin-right:auto;text-align:center}\n.sec h2{font-family:var(--fraunces);font-weight:700;letter-spacing:-.02em;line-height:1.05;\n  font-size:clamp(30px,4vw,46px);margin:12px 0 0;text-wrap:balance}\n.sec-head p{color:var(--muted);font-size:17px;line-height:1.6;margin-top:14px;max-width:64ch}\n.sec-head.center p{margin-left:auto;margin-right:auto}\n\n\/* ============================ TOPIC CARDS ============================ *\/\n.topics{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,340px),1fr));gap:18px}\n.topic{\n  position:relative;background:var(--surface);border:1px solid var(--border);border-radius:18px;\n  padding:24px;overflow:hidden;display:flex;flex-direction:column;box-shadow:var(--sh-card);\n  transition:transform var(--spring),box-shadow var(--smooth),border-color var(--smooth);\n}\n.topic::before{content:\"\";position:absolute;inset:0;border-radius:inherit;padding:1px;\n  background:linear-gradient(140deg,rgba(37,99,235,.5),transparent 40%);\n  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);\n  -webkit-mask-composite:xor;mask-composite:exclude;opacity:0;transition:opacity var(--smooth)}\n.topic:hover{transform:translateY(-4px);box-shadow:var(--sh-lg);border-color:transparent}\n.topic:hover::before{opacity:1}\n.topic-top{display:flex;align-items:flex-start;gap:13px;margin-bottom:14px}\n.unit-no{\n  flex:0 0 auto;width:46px;height:46px;border-radius:var(--r-sm);display:grid;place-items:center;\n  font-family:var(--fraunces);font-weight:700;font-size:21px;color:#fff;\n  background:linear-gradient(140deg,var(--accent-deep),var(--accent-bright));box-shadow:var(--sh-glow);\n}\n.unit-cap{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#64748B}\n.topic h3{font-size:18px;font-weight:700;letter-spacing:-.01em;margin-top:1px;line-height:1.2}\n.topic.desc{color:var(--muted);font-size:14px;margin:12px 0 16px;text-wrap:pretty}\n.tagrow{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:14px}\n.tag{font-size:11.5px;font-weight:600;color:var(--accent-deep);background:rgba(37,99,235,.08);\n  padding:5px 10px;border-radius:999px;border:1px solid rgba(37,99,235,.14)}\n.tag.cy{color:#0e7490;background:rgba(6,182,212,.1);border-color:rgba(6,182,212,.2)}\n.task-chip{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;color:var(--muted);\n  margin-top:auto;padding-top:14px;border-top:1px solid var(--border)}\n.task-chip svg{color:var(--accent)}\n.topic.start{position:absolute;top:24px;right:22px;color:var(--subtle);transition:color var(--ease),transform var(--spring)}\n.topic:hover.start{color:var(--accent);transform:translateX(3px)}\n\n\/* ============================ QUIZ ============================ *\/\n.quiz-sec{background:linear-gradient(180deg,var(--surface-2),var(--app))}\n.quiz-card{\n  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-xl);\n  box-shadow:var(--sh-lg);overflow:hidden;max-width:900px;margin:0 auto;\n  display:grid;grid-template-columns:1fr 268px;\n}\n.quiz-main{padding:34px 36px}\n.quiz-kicker{display:flex;align-items:center;gap:10px;color:var(--accent);font-weight:700;font-size:13px;letter-spacing:.04em}\n.quiz-main h3{font-family:var(--fraunces);font-size:27px;font-weight:700;margin:10px 0 4px;letter-spacing:-.01em}\n.quiz-main.lede{color:var(--muted);font-size:14.5px;margin-bottom:22px}\n.q{margin-bottom:18px;opacity:.45;transition:opacity var(--smooth);pointer-events:none}\n.q.live{opacity:1;pointer-events:auto}\n.q.done{opacity:1}\n.q.qtext{font-weight:600;font-size:15.5px;margin-bottom:11px}\n.q.qtext.num{color:var(--accent);font-weight:800;margin-right:8px}\n.opts{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n.opt{\n  display:flex;align-items:center;justify-content:center;gap:8px;text-align:center;\n  padding:12px 14px;border-radius:var(--r-sm);font-weight:600;font-size:14.5px;color:var(--ink);\n  background:var(--surface-2);border:1.5px solid var(--border);\n  transition:transform var(--ease),border-color var(--ease),background var(--ease),color var(--ease);\n}\n.opt:hover{transform:translateY(-2px);border-color:var(--accent);background:rgba(37,99,235,.05)}\n.opt-ic{display:none;align-items:center;justify-content:center;width:18px;height:18px;flex:0 0 auto}\n.opt.correct.opt-ic,.opt.wrong.opt-ic{display:inline-flex}\n.opt.correct{background:rgba(16,185,129,.12);border-color:#10b981;color:#047857}\n.opt.wrong{background:rgba(239,68,68,.1);border-color:#ef4444;color:#b91c1c}\n.opt.locked{pointer-events:none}\n.opt.dim{opacity:.5}\n.explain{margin-top:11px;font-size:13.5px;color:var(--muted);background:var(--surface-2);\n  border-left:3px solid var(--accent);border-radius:0 var(--r-xs) var(--r-xs) 0;padding:10px 13px;\n  display:none}\n.explain.show{display:block;animation:fadeUp calc(.4s*var(--motion-scale)) ease}\n.explain b{color:var(--ink)}\n@keyframes fadeUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}\n.quiz-actions{display:flex;gap:12px;margin-top:24px}\n.qbtn{padding:11px 20px;border-radius:var(--r-sm);font-weight:700;font-size:14px;transition:transform var(--spring),box-shadow var(--smooth),background var(--ease)}\n.qbtn.primary{color:#fff;background:linear-gradient(100deg,var(--accent-deep),var(--accent-bright));box-shadow:var(--sh-glow)}\n.qbtn.primary:hover{transform:translateY(-2px)}\n.qbtn.ghost{color:var(--muted);background:var(--surface-2);border:1px solid var(--border)}\n.qbtn.ghost:hover{color:var(--ink);background:var(--app)}\n\/* quiz side *\/\n.quiz-side{background:linear-gradient(165deg,var(--dark-2),var(--dark-3));color:#fff;\n  padding:34px 28px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px}\n.ring-wrap{position:relative;width:168px;height:168px}\n.ring-wrap svg{transform:rotate(-90deg)}\n.ring-track{stroke:rgba(255,255,255,.12)}\n.ring-prog{stroke:url(#ringgrad);stroke-linecap:round;transition:stroke-dashoffset var(--smooth)}\n.ring-center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}\n.ring-center.score{font-family:var(--fraunces);font-size:46px;font-weight:700;line-height:1}\n.ring-center.of{font-size:13px;color:rgba(255,255,255,.6);font-weight:600;margin-top:2px}\n.quiz-side.label{font-size:13px;color:rgba(255,255,255,.66);font-weight:600;text-align:center;margin-top:14px}\n.quiz-side.est{font-size:12px;font-weight:700;letter-spacing:.04em;color:var(--cyan);margin-top:3px}\n\n\/* ============================ CAMBRIDGE TESTS ============================ *\/\n.tests{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,270px),1fr));gap:18px}\n.test{background:var(--surface);border:1px solid var(--border);border-radius:18px;padding:22px;box-shadow:var(--sh-card);\n  display:flex;flex-direction:column;transition:transform var(--spring),box-shadow var(--smooth)}\n.test:hover{transform:translateY(-4px);box-shadow:var(--sh-lg)}\n.test-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}\n.test-head.tt{font-weight:800;font-size:16px;letter-spacing:-.01em}\n.test-head.tt span{display:block;font-size:11px;font-weight:600;color:#64748B;letter-spacing:.04em}\n.bk{width:38px;height:38px;border-radius:var(--r-xs);display:grid;place-items:center;color:#fff;\n  background:linear-gradient(140deg,var(--accent-deep),var(--accent-bright))}\n.skill{display:flex;align-items:center;gap:12px;padding:12px 0;border-top:1px solid var(--border)}\n.skill-ic{flex:0 0 auto;width:34px;height:34px;border-radius:9px;display:grid;place-items:center;\n  background:rgba(37,99,235,.09);color:var(--accent)}\n.skill-meta{flex:1;min-width:0}\n.skill-meta.sn{font-weight:700;font-size:14px}\n.skill-meta.sd{font-size:12px;color:#64748B}\n.skill.soon{opacity:.7}\n.badge{font-size:10.5px;font-weight:800;letter-spacing:.06em;padding:4px 9px;border-radius:999px;text-transform:uppercase}\n.badge.live{color:#fff;background:linear-gradient(100deg,var(--accent),var(--accent-bright));box-shadow:0 4px 12px rgba(37,99,235,.4)}\n.badge.soon{color:#64748B;background:var(--surface-2);border:1px solid var(--border)}\n\n\/* ============================ WHY \/ FEATURES ============================ *\/\n.feats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr));gap:18px}\n.feat{background:var(--surface);border:1px solid var(--border);border-radius:18px;padding:28px 24px;box-shadow:var(--sh-card);\n  transition:transform var(--spring),box-shadow var(--smooth)}\n.feat:hover{transform:translateY(-4px);box-shadow:var(--sh-lg)}\n.feat-ic{width:52px;height:52px;border-radius:var(--r-sm);display:grid;place-items:center;color:#fff;margin-bottom:18px;\n  background:linear-gradient(140deg,var(--accent-deep),var(--accent-bright));box-shadow:var(--sh-glow)}\n.feat:nth-child(2) .feat-ic{background:linear-gradient(140deg,#0e7490,var(--cyan))}\n.feat:nth-child(4) .feat-ic{background:linear-gradient(140deg,var(--accent),var(--cyan))}\n.feat h3{font-size:17px;font-weight:700;margin-bottom:7px}\n.feat p{color:var(--muted);font-size:15px;line-height:1.6;text-wrap:pretty}\n\n\/* ============================ YOUTUBE BAND ============================ *\/\n.yt-sec{background:linear-gradient(165deg,var(--dark-1),var(--dark-3));color:#fff;border-radius:var(--r-xl);overflow:hidden}\n.yt-inner{padding:64px 0}\n.yt-top{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;flex-wrap:wrap;margin-bottom:38px}\n.yt-top h2{color:#fff}\n.sub-yt{display:inline-flex;align-items:center;gap:10px;font-weight:700;font-size:15px;color:#fff;\n  padding:13px 22px;border-radius:var(--r-sm);background:linear-gradient(100deg,#e11d48,#ef4444);\n  box-shadow:0 8px 24px rgba(239,68,68,.4);transition:transform var(--spring)}\n.sub-yt:hover{transform:translateY(-2px) scale(1.02)}\n.vids{display:grid;grid-template-columns:1fr 1fr;gap:20px}\n.vid{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);border-radius:var(--r-lg);overflow:hidden;\n  transition:transform var(--spring),background var(--smooth)}\n.vid:hover{transform:translateY(-5px);background:rgba(255,255,255,.07)}\n.vid-thumb{aspect-ratio:16\/9;position:relative;display:grid;place-items:center;\n  background:radial-gradient(400px 240px at 50% 40%,rgba(37,99,235,.4),transparent 70%),linear-gradient(160deg,var(--dark-2),var(--dark-3))}\n.vid-thumb::after{content:\"\";position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);background-size:32px 32px;opacity:.6}\n.play{position:relative;z-index:1;width:66px;height:66px;border-radius:50%;display:grid;place-items:center;\n  background:rgba(255,255,255,.95);color:#e11d48;box-shadow:0 10px 30px rgba(0,0,0,.4);transition:transform var(--spring)}\n.vid:hover.play{transform:scale(1.1)}\n.vid-meta{padding:18px 20px}\n.vid-meta.vt{font-weight:700;font-size:16px}\n.vid-meta.vd{font-size:13px;color:rgba(255,255,255,.6);margin-top:4px;display:flex;align-items:center;gap:8px}\n\n\/* ============================ FOOTER ============================ *\/\nfooter{background:var(--dark-1);color:#fff;padding:64px 0 30px;margin-top:30px}\n.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:40px;padding-bottom:40px;border-bottom:1px solid rgba(255,255,255,.1)}\n.foot-brand{display:flex;align-items:center;gap:11px;font-weight:800;font-size:17px;white-space:nowrap}\n.foot-brand img{width:40px;height:40px;border-radius:11px}\n.foot-tag{color:rgba(255,255,255,.6);font-size:14px;margin:16px 0 20px;max-width:280px}\n.socials{display:flex;gap:10px}\n.soc{width:40px;height:40px;border-radius:var(--r-xs);display:grid;place-items:center;color:rgba(255,255,255,.8);\n  background:rgba(255,255,255,.06);transition:background var(--ease),color var(--ease),transform var(--spring)}\n.soc:hover{background:var(--accent);color:#fff;transform:translateY(-3px)}\n.foot-col h4{font-size:13px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--subtle);margin-bottom:16px}\n.foot-col a{display:block;color:rgba(255,255,255,.72);font-size:14.5px;padding:6px 0;transition:color var(--ease),padding-left var(--ease)}\n.foot-col a:hover{color:#fff;padding-left:5px}\n.foot-bottom{padding-top:24px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;color:rgba(255,255,255,.5);font-size:13px}\n\n\/* ============================ TWEAK PANEL ============================ *\/\n.gear{position:fixed;right:22px;bottom:22px;z-index:120;width:54px;height:54px;border-radius:50%;\n  display:grid;place-items:center;color:#fff;background:linear-gradient(140deg,var(--accent-deep),var(--accent-bright));\n  box-shadow:var(--sh-glow);transition:transform var(--spring),box-shadow var(--smooth)}\n.gear:hover{transform:rotate(40deg) scale(1.06)}\n.gear svg{transition:transform var(--smooth)}\n.tweaks{position:fixed;right:22px;bottom:88px;z-index:120;width:300px;background:var(--surface);\n  border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--sh-lg);padding:20px;\n  transform:translateY(14px) scale(.96);opacity:0;pointer-events:none;transform-origin:bottom right;\n  transition:transform var(--spring),opacity var(--smooth)}\n.tweaks.open{transform:none;opacity:1;pointer-events:auto}\n.tweaks-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}\n.tweaks-head.tk{font-weight:800;font-size:14px;display:flex;align-items:center;gap:8px}\n.tweaks-head.tk svg{color:var(--accent)}\n.tweaks-head button{color:var(--subtle);width:28px;height:28px;border-radius:7px;display:grid;place-items:center}\n.tweaks-head button:hover{background:var(--surface-2);color:var(--ink)}\n.tk-row{margin-bottom:15px}\n.tk-row label{display:flex;justify-content:space-between;font-size:12.5px;font-weight:600;color:var(--muted);margin-bottom:7px}\n.tk-row label.val{color:var(--accent);font-weight:700}\n.tk-row input[type=range]{width:100%;-webkit-appearance:none;appearance:none;height:6px;border-radius:999px;\n  background:linear-gradient(90deg,var(--accent),var(--cyan));outline:none}\n.tk-row input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;\n  background:#fff;border:2px solid var(--accent);box-shadow:var(--sh-card);cursor:pointer;transition:transform var(--ease)}\n.tk-row input[type=range]::-webkit-slider-thumb:hover{transform:scale(1.15)}\n.tk-row input[type=range]::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--accent);cursor:pointer}\n.tk-toggle{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:var(--surface-2);border-radius:var(--r-sm);font-size:13px;font-weight:600;color:var(--ink)}\n.switch{position:relative;width:42px;height:24px;border-radius:999px;background:var(--border);transition:background var(--smooth);flex:0 0 auto}\n.switch.on{background:var(--accent)}\n.switch::after{content:\"\";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;box-shadow:var(--sh-card);transition:transform var(--spring)}\n.switch.on::after{transform:translateX(18px)}\n\n\/* ============================ RESPONSIVE ============================ *\/\n@media(max-width:980px){\n  .nav{display:none}\n  .hdr-right.pill{display:none}\n  .hdr-right.icon-btn:not(.hamb){display:none}\n  .hdr-right.hamb{display:grid}\n  .hero-inner{grid-template-columns:1fr;gap:40px}\n  .stage{max-width:380px;margin:0 auto;order:-1}\n  .quiz-card{grid-template-columns:1fr}\n  .quiz-side{flex-direction:row;justify-content:center;gap:24px;padding:26px}\n  .foot-grid{grid-template-columns:1fr 1fr}\n  .vids{grid-template-columns:1fr}\n}\n@media(max-width:760px){\n  .sec{padding:clamp(56px,12vw,72px) 0}\n  .hero{padding:120px 0 80px}\n  .hdr-inner{padding:14px 20px}\n  .icon-btn{width:44px;height:44px}\n  .quiz-side{flex-direction:column;gap:14px;padding:24px}\n  .mobile-menu a{min-height:44px;display:flex;align-items:center}\n  .quiz-main{padding:26px 22px}\n  .opts{grid-template-columns:1fr}\n  .foot-grid{grid-template-columns:1fr}\n  .yt-top{flex-direction:column;align-items:flex-start}\n}\n@media(max-width:430px){\n  .wrap,.hero-inner{padding-left:20px;padding-right:20px}\n  .stage{max-width:300px}\n  .chip{font-size:12px;padding:8px 12px}\n  .btn{width:100%;justify-content:center}\n  .hero-cta{gap:10px}\n}\n@media print{.gear,.tweaks{display:none}}\n<\/style>\n\n\n<!-- ============================ HEADER ============================ -->\n<header class=\"hdr\" id=\"hdr\">\n  <div class=\"hdr-inner\">\n    <a href=\"#top\" class=\"brand\">\n      <img decoding=\"async\" src=\"https:\/\/allenglish4u.com\/wp-content\/uploads\/2026\/04\/Transparent-background-MacBook-Pro-cua-Hang.png\" alt=\"All English 4U logo\" \/>\n      <span>All English 4U<\/span>\n    <\/a>\n    <nav class=\"nav\">\n      <a href=\"\/grammar\/\">Grammar<\/a>\n      <a href=\"\/ielts\/\" class=\"active\">IELTS<\/a>\n      <a href=\"\/toefl\/\">TOEFL<\/a>\n      <a href=\"\/cambridge\/\">Cambridge<\/a>\n      <a href=\"\/celpip\/\">CELPIP<\/a>\n      <a href=\"\/dictation\/\">Dictation<\/a>\n      <a href=\"\/contact\/\">Contact<\/a>\n    <\/nav>\n    <div class=\"hdr-right\">\n      <button class=\"icon-btn\" aria-label=\"Search\">\n        <svg width=\"19\" height=\"19\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"\/><path d=\"m21 21-4.3-4.3\"\/><\/svg>\n      <\/button>\n      <a href=\"#topics\" class=\"pill\">Start Free\n        <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\"><path d=\"M5 12h14M13 6l6 6-6 6\"\/><\/svg>\n      <\/a>\n      <button class=\"icon-btn hamb\" id=\"hamb\" aria-label=\"Menu\">\n        <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M3 6h18M3 12h18M3 18h18\"\/><\/svg>\n      <\/button>\n    <\/div>\n  <\/div>\n<\/header>\n\n<div class=\"menu-backdrop\" id=\"menuBackdrop\"><\/div>\n<aside class=\"mobile-menu\" id=\"mobileMenu\">\n  <button class=\"menu-close\" id=\"menuClose\" aria-label=\"Close\">\n    <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M6 6l12 12M18 6L6 18\"\/><\/svg>\n  <\/button>\n  <a href=\"\/grammar\/\">Grammar<\/a>\n  <a href=\"\/ielts\/\" class=\"active\">IELTS<\/a>\n  <a href=\"\/toefl\/\">TOEFL<\/a>\n  <a href=\"\/cambridge\/\">Cambridge<\/a>\n  <a href=\"\/celpip\/\">CELPIP<\/a>\n  <a href=\"\/dictation\/\">Dictation<\/a>\n  <a href=\"\/contact\/\">Contact<\/a>\n  <a href=\"#topics\" class=\"pill\" style=\"margin-top:14px;justify-content:center\">Start Free<\/a>\n<\/aside>\n\n<span id=\"top\"><\/span>\n<main id=\"main\">\n\n<!-- ============================ HERO ============================ -->\n<section class=\"hero\" aria-label=\"IELTS Vocabulary Practice introduction\">\n  <div class=\"hero-grid\"><\/div>\n  <div class=\"hero-inner\">\n    <div class=\"hero-copy\">\n      <div class=\"eyebrow reveal\">Check Your English Vocabulary for IELTS<\/div>\n      <h1 class=\"reveal\" style=\"--d:.05s\">IELTS <span class=\"grad\">Vocabulary<\/span> Practice<\/h1>\n      <p class=\"sub reveal\" style=\"--d:.12s\">Interactive exercises based on <em>Check Your English Vocabulary for IELTS<\/em>. Covers the vocabulary you need for Writing, Speaking and Reading \u2014 10 topics, instant feedback, 100% free.<\/p>\n      <div class=\"chips reveal\" style=\"--d:.18s\">\n        <span class=\"chip\"><span class=\"dot\"><\/span>10 Vocabulary Topics<\/span>\n        <span class=\"chip\"><span class=\"dot\"><\/span>13 Interactive Exercises<\/span>\n        <span class=\"chip\"><span class=\"dot\"><\/span>Fill-blank \/ MCQ \/ Drag &amp; Drop<\/span>\n        <span class=\"chip\"><span class=\"dot\"><\/span>Always Free<\/span>\n      <\/div>\n      <div class=\"hero-cta reveal\" style=\"--d:.24s\">\n        <a href=\"#topics\" class=\"btn btn-primary\">Start Topic 1\n          <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\"><path d=\"M5 12h14M13 6l6 6-6 6\"\/><\/svg>\n        <\/a>\n        <a href=\"#youtube\" class=\"btn btn-ghost\">\n          <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M21.6 7.2a2.7 2.7 0 0 0-1.9-1.9C18 4.8 12 4.8 12 4.8s-6 0-7.7.5A2.7 2.7 0 0 0 2.4 7.2 28 28 0 0 0 2 12a28 28 0 0 0 .4 4.8 2.7 2.7 0 0 0 1.9 1.9c1.7.5 7.7.5 7.7.5s6 0 7.7-.5a2.7 2.7 0 0 0 1.9-1.9A28 28 0 0 0 22 12a28 28 0 0 0-.4-4.8ZM10 15.3V8.7l5.2 3.3Z\"\/><\/svg>\n          Watch on YouTube\n        <\/a>\n      <\/div>\n    <\/div>\n    <div class=\"stage reveal\" id=\"stage\" style=\"--d:.1s\">\n      <canvas id=\"gauge-canvas\"><\/canvas>\n      <div class=\"static-gauge\" aria-hidden=\"true\">\n        <svg viewBox=\"0 0 220 220\">\n          <defs>\n            <linearGradient id=\"sg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n              <stop offset=\"0\" stop-color=\"#1245A8\"\/><stop offset=\".55\" stop-color=\"#3B82F6\"\/><stop offset=\"1\" stop-color=\"#06B6D4\"\/>\n            <\/linearGradient>\n            <radialGradient id=\"orbG\" cx=\".35\" cy=\".3\" r=\".85\">\n              <stop offset=\"0\" stop-color=\"#eef5ff\"\/><stop offset=\".5\" stop-color=\"#8bb6ff\"\/><stop offset=\"1\" stop-color=\"#1c4fb0\"\/>\n            <\/radialGradient>\n            <filter id=\"orbGlow\" x=\"-60%\" y=\"-60%\" width=\"220%\" height=\"220%\"><feGaussianBlur stdDeviation=\"2.4\" result=\"b\"\/><feMerge><feMergeNode in=\"b\"\/><feMergeNode in=\"SourceGraphic\"\/><\/feMerge><\/filter>\n          <\/defs>\n          <path d=\"M53.43,166.57 A80,80 0 1 1 166.57,166.57\" fill=\"none\" stroke=\"rgba(255,255,255,.10)\" stroke-width=\"13\" stroke-linecap=\"round\"\/>\n          <path d=\"M53.43,166.57 A80,80 0 1 1 166.57,166.57\" fill=\"none\" stroke=\"url(#sg)\" stroke-width=\"13\" stroke-linecap=\"round\"\/>\n          <g stroke=\"rgba(255,255,255,.30)\" stroke-width=\"2.4\" stroke-linecap=\"round\">\n            <line x1=\"47.78\" y1=\"172.22\" x2=\"42.12\" y2=\"177.88\"\/>\n            <line x1=\"25.00\" y1=\"132.77\" x2=\"17.27\" y2=\"134.84\"\/>\n            <line x1=\"25.00\" y1=\"87.23\" x2=\"17.27\" y2=\"85.16\"\/>\n            <line x1=\"47.78\" y1=\"47.78\" x2=\"42.12\" y2=\"42.12\"\/>\n            <line x1=\"87.23\" y1=\"25.00\" x2=\"85.16\" y2=\"17.27\"\/>\n            <line x1=\"132.77\" y1=\"25.00\" x2=\"134.84\" y2=\"17.27\"\/>\n            <line x1=\"172.22\" y1=\"47.78\" x2=\"177.88\" y2=\"42.12\"\/>\n            <line x1=\"195.00\" y1=\"87.23\" x2=\"202.73\" y2=\"85.16\"\/>\n            <line x1=\"195.00\" y1=\"132.77\" x2=\"202.73\" y2=\"134.84\"\/>\n            <line x1=\"172.22\" y1=\"172.22\" x2=\"177.88\" y2=\"177.88\"\/>\n          <\/g>\n          <g>\n            <circle cx=\"36.09\" cy=\"79.38\" r=\"11\" fill=\"url(#orbG)\" stroke=\"rgba(255,255,255,.55)\" stroke-width=\"1\" filter=\"url(#orbGlow)\"\/>\n            <circle cx=\"110\" cy=\"30\" r=\"11\" fill=\"url(#orbG)\" stroke=\"rgba(255,255,255,.55)\" stroke-width=\"1\" filter=\"url(#orbGlow)\"\/>\n            <circle cx=\"183.91\" cy=\"79.38\" r=\"11\" fill=\"url(#orbG)\" stroke=\"rgba(255,255,255,.55)\" stroke-width=\"1\" filter=\"url(#orbGlow)\"\/>\n          <\/g>\n          <g font-family=\"'Plus Jakarta Sans',sans-serif\" font-size=\"8\" font-weight=\"700\" fill=\"rgba(255,255,255,.78)\" text-anchor=\"middle\" letter-spacing=\".4\">\n            <text x=\"36\" y=\"100\">WRITING<\/text>\n            <text x=\"110\" y=\"16\">SPEAKING<\/text>\n            <text x=\"184\" y=\"100\">READING<\/text>\n          <\/g>\n        <\/svg>\n      <\/div>\n      <div class=\"stage-num\">\n        <div class=\"band\" id=\"bandNum\">9.0<\/div>\n        <div class=\"band-cap\">Target Band<\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============================ SECTION 1: TOPICS ============================ -->\n<section class=\"sec\" id=\"topics\">\n  <div class=\"wrap\">\n    <div class=\"sec-head reveal\">\n      <div class=\"eyebrow\">General Vocabulary \u2014 Units 1\u201310<\/div>\n      <h2>Ten topics, the exact vocabulary IELTS rewards<\/h2>\n      <p>Each unit drills the words and structures examiners look for, mapped to the Writing, Speaking and Reading tasks where they actually appear.<\/p>\n    <\/div>\n    <div class=\"topics\" id=\"topicGrid\"><\/div>\n  <\/div>\n<\/section>\n\n<!-- ============================ SECTION 2: QUIZ ============================ -->\n<section class=\"sec quiz-sec\" id=\"quiz\">\n  <div class=\"wrap\">\n    <div class=\"sec-head center reveal\">\n      <div class=\"eyebrow\">Interactive Vocabulary Demo<\/div>\n      <h2>Try a quick vocabulary check<\/h2>\n      <p>Four questions pulled straight from the topics above. Tap an answer for instant feedback \u2014 no sign-up, no catch.<\/p>\n    <\/div>\n    <div class=\"quiz-card reveal\" style=\"--d:.06s\">\n      <div class=\"quiz-main\">\n        <div class=\"quiz-kicker\">\n          <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M9 11l3 3L22 4\"\/><path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"\/><\/svg>\n          Mini Quiz \u00b7 4 questions\n        <\/div>\n        <h3>Check your IELTS vocabulary<\/h3>\n        <p class=\"lede\">Choose the word that fits each gap.<\/p>\n        <div id=\"quizBody\"><\/div>\n        <div class=\"quiz-actions\">\n          <button class=\"qbtn primary\" id=\"quizCheck\">Check answers<\/button>\n          <button class=\"qbtn ghost\" id=\"quizReset\">Reset<\/button>\n        <\/div>\n      <\/div>\n      <div class=\"quiz-side\">\n        <div class=\"ring-wrap\">\n          <svg width=\"168\" height=\"168\" viewBox=\"0 0 168 168\">\n            <defs><linearGradient id=\"ringgrad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n              <stop offset=\"0\" stop-color=\"#3B82F6\"\/><stop offset=\"1\" stop-color=\"#06B6D4\"\/>\n            <\/linearGradient><\/defs>\n            <circle class=\"ring-track\" cx=\"84\" cy=\"84\" r=\"72\" fill=\"none\" stroke-width=\"13\"\/>\n            <circle class=\"ring-prog\" id=\"ringProg\" cx=\"84\" cy=\"84\" r=\"72\" fill=\"none\" stroke-width=\"13\"\n              stroke-dasharray=\"452\" stroke-dashoffset=\"452\"\/>\n          <\/svg>\n          <div class=\"ring-center\"><div class=\"score\" id=\"quizScore\">0<\/div><div class=\"of\">of 4 correct<\/div><\/div>\n        <\/div>\n        <div class=\"label\">Answer all four to estimate your level<\/div>\n        <div class=\"est\" id=\"quizEst\">Let&#8217;s go \u2192<\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============================ SECTION 4: WHY ============================ -->\n<section class=\"sec\" id=\"why\" style=\"background:var(--surface-2)\">\n  <div class=\"wrap\">\n    <div class=\"sec-head center reveal\">\n      <div class=\"eyebrow\">Why practise with us<\/div>\n      <h2>Built for results, free<\/h2>\n    <\/div>\n    <div class=\"feats\">\n      <div class=\"feat reveal\">\n        <div class=\"feat-ic\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"\/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"\/><\/svg><\/div>\n        <h3>Based on the book<\/h3>\n        <p>Every exercise follows <em>Check Your English Vocabulary for IELTS<\/em> \u2014 the trusted Collins title.<\/p>\n      <\/div>\n      <div class=\"feat reveal\" style=\"--d:.06s\">\n        <div class=\"feat-ic\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13 2 3 14h9l-1 8 10-12h-9l1-8z\"\/><\/svg><\/div>\n        <h3>Instant feedback<\/h3>\n        <p>Auto-graded answers with one-line explanations, so you learn the moment you slip.<\/p>\n      <\/div>\n      <div class=\"feat reveal\" style=\"--d:.18s\">\n        <div class=\"feat-ic\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20.84 4.6a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.07a5.5 5.5 0 0 0-7.78 7.78L12 21.23l8.84-8.85a5.5 5.5 0 0 0 0-7.78z\"\/><\/svg><\/div>\n        <h3>100% free<\/h3>\n        <p>No paywalls, no accounts, no ads in your way. Quality practice, open to everyone.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============================ SECTION 5: YOUTUBE ============================ -->\n<section class=\"sec\" id=\"youtube\">\n  <div class=\"wrap\">\n    <div class=\"yt-sec reveal\">\n      <div class=\"wrap yt-inner\">\n        <div class=\"yt-top\">\n          <div>\n            <div class=\"eyebrow\" style=\"color:#fca5a5\">YouTube<\/div>\n            <h2>Watch free IELTS lessons on YouTube<\/h2>\n          <\/div>\n          <a href=\"#\" class=\"sub-yt\">\n            <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M21.6 7.2a2.7 2.7 0 0 0-1.9-1.9C18 4.8 12 4.8 12 4.8s-6 0-7.7.5A2.7 2.7 0 0 0 2.4 7.2 28 28 0 0 0 2 12a28 28 0 0 0 .4 4.8 2.7 2.7 0 0 0 1.9 1.9c1.7.5 7.7.5 7.7.5s6 0 7.7-.5a2.7 2.7 0 0 0 1.9-1.9A28 28 0 0 0 22 12a28 28 0 0 0-.4-4.8ZM10 15.3V8.7l5.2 3.3Z\"\/><\/svg>\n            Subscribe\n          <\/a>\n        <\/div>\n        <div class=\"vids\">\n          <a href=\"#\" class=\"vid\" aria-label=\"Play: Writing Task 2 \u2014 How to plan a 7+ essay\">\n            <div class=\"vid-thumb\"><div class=\"play\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8 5v14l11-7z\"\/><\/svg><\/div><\/div><div class=\"vd\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M21.6 7.2a2.7 2.7 0 0 0-1.9-1.9C18 4.8 12 4.8 12 4.8s-6 0-7.7.5A2.7 2.7 0 0 0 2.4 7.2 28 28 0 0 0 2 12a28 28 0 0 0 .4 4.8 2.7 2.7 0 0 0 1.9 1.9c1.7.5 7.7.5 7.7.5s6 0 7.7-.5a2.7 2.7 0 0 0 1.9-1.9A28 28 0 0 0 22 12a28 28 0 0 0-.4-4.8ZM10 15.3V8.7l5.2 3.3Z\"\/><\/svg>All English 4U<\/div><\/div>\n          <\/a>\n          <a href=\"#\" class=\"vid\" aria-label=\"Play: Band 9 vocabulary\">\n            <div class=\"vid-thumb\"><div class=\"play\"><svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8 5v14l11-7z\"\/><\/svg><\/div><\/div>\n            <div class=\"vid-meta\"><div class=\"vt\">Band 9 vocabulary<\/div><div class=\"vd\"><svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M21.6 7.2a2.7 2.7 0 0 0-1.9-1.9C18 4.8 12 4.8 12 4.8s-6 0-7.7.5A2.7 2.7 0 0 0 2.4 7.2 28 28 0 0 0 2 12a28 28 0 0 0 .4 4.8 2.7 2.7 0 0 0 1.9 1.9c1.7.5 7.7.5 7.7.5s6 0 7.7-.5a2.7 2.7 0 0 0 1.9-1.9A28 28 0 0 0 22 12a28 28 0 0 0-.4-4.8ZM10 15.3V8.7l5.2 3.3Z\"\/><\/svg>All English 4U<\/div><\/div>\n          <\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<\/main>\n\n<!-- ============================ FOOTER ============================ -->\n\n\n<!-- ============================ TWEAK PANEL ============================ -->\n<button class=\"gear\" id=\"gear\" aria-label=\"Customise\">\n  <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"\/><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\"\/><\/svg>\n<\/button>\n<div class=\"tweaks\" id=\"tweaks\">\n  <div class=\"tweaks-head\">\n    <div class=\"tk\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><path d=\"m12 3-1.9 5.8H4l4.8 3.5L7 18l5-3.6L17 18l-1.8-5.7L20 8.8h-6.1z\"\/><\/svg>Customise<\/div>\n    <button id=\"tweaksClose\" aria-label=\"Close\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M6 6l12 12M18 6L6 18\"\/><\/svg><\/button>\n  <\/div>\n  <div class=\"tk-row\">\n    <label>Accent hue <span class=\"val\" id=\"hueVal\">Blue<\/span><\/label>\n    <input type=\"range\" id=\"hue\" min=\"0\" max=\"100\" value=\"0\" \/>\n  <\/div>\n  <div class=\"tk-row\">\n    <label>Animation speed <span class=\"val\" id=\"speedVal\">1.0\u00d7<\/span><\/label>\n    <input type=\"range\" id=\"speed\" min=\"40\" max=\"180\" value=\"100\" \/>\n  <\/div>\n  <div class=\"tk-row\">\n    <label>3D gauge intensity <span class=\"val\" id=\"intVal\">100%<\/span><\/label>\n    <input type=\"range\" id=\"intensity\" min=\"0\" max=\"160\" value=\"100\" \/>\n  <\/div>\n  <div class=\"tk-toggle\" id=\"rmToggle\">\n    Reduce motion\n    <span class=\"switch\" id=\"rmSwitch\"><\/span>\n  <\/div>\n<\/div>\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\"><\/script>\n<script>\n\/* ============================ DATA ============================ *\/\nconst TOPICS=[\n {n:1,t:\"Condition\",d:\"Conditional expressions: unless, providing that, as long as, on condition that.\",tags:[[\"Fill-blank\"],[\"MCQ\"]],task:\"Writing Task 2\"},\n {n:2,t:\"Changes 1\",d:\"20 verbs of change: adapt, transform, renovate, dissolve, demote, replace.\",tags:[[\"Fill-blank\"]],task:\"Writing Tasks 1 & 2\"},\n {n:3,t:\"Describing Tables\",d:\"Graph & table language: rose, declined, remained constant, sharply, discrepancy.\",tags:[[\"Match\"]],task:\"Writing Task 1 (Academic)\"},\n {n:4,t:\"How Something Works\",d:\"Describing processes: thermostat, aerosol, aeroplane, camera.\",tags:[[\"MCQ\"]],task:\"Writing Task 1 (Process)\"},\n {n:5,t:\"Writing a Letter\",d:\"Formal letter conventions: I refer to, I look forward to, Yours faithfully vs sincerely.\",tags:[[\"MCQ\"],[\"True\/False\",\"cy\"]],task:\"Writing Task 1 (General)\"},\n {n:6,t:\"Presenting an Argument\",d:\"Discourse markers: First of all, On the other hand, Nevertheless, In my opinion.\",tags:[[\"Fill-blank\"]],task:\"Writing Task 2\"},\n {n:7,t:\"Contrast & Comparison\",d:\"differ, distinguish, discrepancy, identical, whereas, chalk and cheese.\",tags:[[\"MCQ\"]],task:\"Writing Tasks 1 & 2\"},\n {n:8,t:\"Location\",d:\"Map vocabulary: directly opposite, parallel to, in close proximity to, halfway between.\",tags:[[\"Fill-blank\"]],task:\"Writing Task 1 (Map)\"},\n {n:9,t:\"Joining & Becoming\",d:\"amalgamate, incorporate, assimilate, merger, coalition, alloy.\",tags:[[\"Drag & Drop\",\"cy\"],[\"Match\"]],task:\"Reading & Writing Task 2\"},\n {n:10,t:\"Reason & Result\",d:\"in order to, on account of, on the grounds that, so as not to, ensued.\",tags:[[\"Fill-blank\"]],task:\"Writing Task 2\"},\n];\n\nconst QUIZ=[\n {q:'The line ___ sharply in 2020.',opts:['rose','declined'],a:0,ex:'<b>Rose<\/b> \u2014 \u201crose sharply\u201d describes an upward trend in Writing Task 1 graphs.'},\n {q:'I am writing ___ to your advertisement in Saturday\u2019s paper.',opts:['with reference to','about'],a:0,ex:'<b>With reference to<\/b> \u2014 the formal letter convention from Unit 5.'},\n {q:'___ the rain, the match continued without delay.',opts:['Despite','Because of'],a:0,ex:'<b>Despite<\/b> signals contrast; \u201cbecause of\u201d would wrongly imply cause.'},\n {q:'Two or more metals combined together form an ___.',opts:['alloy','element'],a:0,ex:'<b>Alloy<\/b> \u2014 a joining word from Unit 9 (amalgamate, merger, alloy).'},\n];\n\n\n\/* ============================ RENDER: TOPICS ============================ *\/\nconst arrowSvg='<svg class=\"start\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M5 12h14M13 6l6 6-6 6\"\/><\/svg>';\nconst taskSvg='<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\/><path d=\"M14 2v6h6M9 13h6M9 17h4\"\/><\/svg>';\nconst ISLUG=[\"condition\",\"changes-1\",\"describing-tables\",\"how-something-works\",\"writing-a-letter\",\"presenting-an-argument\",\"contrast-and-comparison\",\"location\",\"joining-becoming\",\"reason-and-result\"];\ndocument.getElementById('topicGrid').innerHTML=TOPICS.map((t,i)=>`\n <a href=\"\/ielts\/${ISLUG[i]}\/\" class=\"topic reveal\" style=\"--d:${(i%3)*.06}s;text-decoration:none;color:inherit\">\n   ${arrowSvg}\n   <div class=\"topic-top\">\n     <div class=\"unit-no\">${t.n}<\/div>\n     <div><div class=\"unit-cap\">Unit ${t.n}<\/div><h3>${t.t}<\/h3><\/div>\n   <\/div>\n   <p class=\"desc\">${t.d}<\/p>\n   <div class=\"tagrow\">${t.tags.map(tg=>`<span class=\"tag ${tg[1]||''}\">${tg[0]}<\/span>`).join('')}<\/div>\n   <div class=\"task-chip\">${taskSvg}<span>${t.task}<\/span><\/div>\n <\/a>`).join('');\n\n\/* ============================ QUIZ LOGIC ============================ *\/\nconst quizBody=document.getElementById('quizBody');\nconst answered=new Array(QUIZ.length).fill(-1);\nfunction renderQuiz(){\n  quizBody.innerHTML=QUIZ.map((q,i)=>`\n    <div class=\"q ${i===0?'live':''}\" data-q=\"${i}\">\n      <div class=\"qtext\"><span class=\"num\">${i+1}<\/span>${q.q}<\/div>\n      <div class=\"opts\" role=\"group\" aria-label=\"Question ${i+1} options\">${q.opts.map((o,oi)=>`<button type=\"button\" class=\"opt\" data-o=\"${oi}\"><span class=\"opt-ic\" aria-hidden=\"true\"><\/span><span class=\"opt-label\">${o}<\/span><\/button>`).join('')}<\/div>\n      <div class=\"explain\" role=\"status\">${q.ex}<\/div>\n    <\/div>`).join('');\n  quizBody.querySelectorAll('.q').forEach(qEl=>{\n    const qi=+qEl.dataset.q;\n    qEl.querySelectorAll('.opt').forEach(btn=>{\n      btn.addEventListener('click',()=>pick(qi,+btn.dataset.o));\n    });\n  });\n}\nfunction pick(qi,oi){\n  if(answered[qi]!==-1) return;\n  answered[qi]=oi;\n  const qEl=quizBody.querySelector(`.q[data-q=\"${qi}\"]`);\n  const correct=QUIZ[qi].a;\n  const CHECK='<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 12l5 5L20 7\"\/><\/svg>';\n  const CROSS='<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\"><path d=\"M6 6l12 12M18 6L6 18\"\/><\/svg>';\n  qEl.querySelectorAll('.opt').forEach((b,bi)=>{\n    b.classList.add('locked');\n    b.setAttribute('aria-disabled','true');\n    const ic=b.querySelector('.opt-ic');\n    if(bi===correct){ b.classList.add('correct'); if(ic)ic.innerHTML=CHECK; }\n    else if(bi===oi){ b.classList.add('wrong'); if(ic)ic.innerHTML=CROSS; }\n    else b.classList.add('dim');\n  });\n  qEl.classList.add('done');\n  qEl.querySelector('.explain').classList.add('show');\n  \/\/ unlock next\n  const next=quizBody.querySelector(`.q[data-q=\"${qi+1}\"]`);\n  if(next) next.classList.add('live');\n  updateScore();\n}\nfunction updateScore(){\n  let correct=0,done=0;\n  answered.forEach((a,i)=>{if(a!==-1){done++;if(a===QUIZ[i].a)correct++;}});\n  document.getElementById('quizScore').textContent=correct;\n  const C=452, frac=done\/QUIZ.length;\n  document.getElementById('ringProg').style.strokeDashoffset=C*(1-frac);\n  const est=document.getElementById('quizEst');\n  if(done<QUIZ.length){ est.textContent=`${done}\/${QUIZ.length} answered`; }\n  else{\n    const band=['Band 4\u20135','Band 5\u20136','Band 6\u20137','Band 7\u20138','Band 8\u20139'][correct];\n    est.textContent=`Est. ${band}`;\n  }\n}\ndocument.getElementById('quizReset').addEventListener('click',()=>{\n  answered.fill(-1); renderQuiz(); updateScore();\n  document.getElementById('quizEst').textContent=\"Let's go \u2192\";\n});\ndocument.getElementById('quizCheck').addEventListener('click',()=>{\n  \/\/ reveal all remaining answers\n  QUIZ.forEach((q,i)=>{ if(answered[i]===-1) pick(i,q.a); });\n});\nrenderQuiz(); updateScore();\n\n\/* ============================ HEADER SCROLL ============================ *\/\nconst hdr=document.getElementById('hdr');\naddEventListener('scroll',()=>{ hdr.classList.toggle('solid',scrollY>40); },{passive:true});\n\n\/* ============================ MOBILE MENU ============================ *\/\nconst mm=document.getElementById('mobileMenu'),mb=document.getElementById('menuBackdrop');\nfunction openMenu(o){mm.classList.toggle('open',o);mb.classList.toggle('open',o);}\ndocument.getElementById('hamb').addEventListener('click',()=>openMenu(true));\ndocument.getElementById('menuClose').addEventListener('click',()=>openMenu(false));\nmb.addEventListener('click',()=>openMenu(false));\nmm.querySelectorAll('a').forEach(a=>a.addEventListener('click',()=>openMenu(false)));\n\n\/* ============================ REVEALS ============================ *\/\nconst io=new IntersectionObserver((es)=>{\n  es.forEach(e=>{ if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target);} });\n},{threshold:.12,rootMargin:'0px 0px -8% 0px'});\ndocument.querySelectorAll('.reveal').forEach(el=>io.observe(el));\n\n\/* ============================ TWEAK PANEL ============================ *\/\nconst root=document.documentElement;\nconst gear=document.getElementById('gear'),tweaks=document.getElementById('tweaks');\ngear.addEventListener('click',()=>tweaks.classList.toggle('open'));\ndocument.getElementById('tweaksClose').addEventListener('click',()=>tweaks.classList.remove('open'));\n\n\/\/ accent hue: mix blue -> cyan\nfunction mix(a,b,t){return a.map((v,i)=>Math.round(v+(b[i]-v)*t));}\nfunction rgb(c){return `rgb(${c[0]},${c[1]},${c[2]})`;}\nconst BLUE={deep:[18,69,168],main:[37,99,235],bright:[59,130,246]};\nconst CYAN={deep:[14,116,144],main:[8,145,178],bright:[6,182,212]};\nconst hue=document.getElementById('hue');\nhue.addEventListener('input',()=>{\n  const t=hue.value\/100;\n  root.style.setProperty('--accent-deep',rgb(mix(BLUE.deep,CYAN.deep,t)));\n  root.style.setProperty('--accent',rgb(mix(BLUE.main,CYAN.main,t)));\n  root.style.setProperty('--accent-bright',rgb(mix(BLUE.bright,CYAN.bright,t)));\n  document.getElementById('hueVal').textContent=t<.2?'Blue':t<.5?'Azure':t<.8?'Sky':'Cyan';\n  if(window.__setGaugeAccent)window.__setGaugeAccent(t);\n});\nconst speed=document.getElementById('speed');\nspeed.addEventListener('input',()=>{\n  const s=speed.value\/100;\n  \/\/ higher slider = faster = smaller scale\n  root.style.setProperty('--motion-scale',(1\/s).toFixed(2));\n  document.getElementById('speedVal').textContent=s.toFixed(1)+'\u00d7';\n  if(window.__setGaugeSpeed)window.__setGaugeSpeed(s);\n});\nconst intensity=document.getElementById('intensity');\nintensity.addEventListener('input',()=>{\n  const v=intensity.value\/100;\n  root.style.setProperty('--gauge-intensity',v);\n  document.getElementById('intVal').textContent=Math.round(v*100)+'%';\n  if(window.__setGaugeIntensity)window.__setGaugeIntensity(v);\n});\nconst rmToggle=document.getElementById('rmToggle'),rmSwitch=document.getElementById('rmSwitch');\nconst IS_MOBILE=matchMedia('(max-width:760px)').matches;\nconst HAS_WEBGL=!!window.WebGLRenderingContext;\nlet reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;\nfunction applyReduced(){\n  document.body.classList.toggle('no-motion',reduced);\n  rmSwitch.classList.toggle('on',reduced);\n  const useStatic = reduced || IS_MOBILE || !HAS_WEBGL;\n  document.body.classList.toggle('fallback-3d',useStatic);\n  if(useStatic){ window.__stopGauge&&window.__stopGauge(); }\n  else{ window.__startGauge&&window.__startGauge(); }\n}\nrmToggle.addEventListener('click',()=>{ reduced=!reduced; applyReduced(); });\n\n\/* ============================ THREE.JS GAUGE ============================ *\/\n(function(){\n  const canvas=document.getElementById('gauge-canvas');\n  let renderer,scene,camera,group,trackMesh,progMesh,orbs=[],glow,rafId=null,running=false,started=false;\n  let accentT=0,speedMul=1,intensity=1,targetProg=0.78,curProg=0,t0=0;\n  const ACCENT=()=>{const c=[ [0.07,0.27,0.92],[0.02,0.57,0.70] ]; return c[0].map((v,i)=>v+(c[1][i]-v)*accentT);};\n\n  function makeOrbLabel(text){\n    const c=document.createElement('canvas');c.width=256;c.height=64;\n    const x=c.getContext('2d');\n    x.fillStyle='rgba(255,255,255,.92)';x.font='bold 30px \"Plus Jakarta Sans\",sans-serif';\n    x.textAlign='center';x.textBaseline='middle';x.fillText(text,128,34);\n    const tex=new THREE.CanvasTexture(c);tex.anisotropy=4;\n    const mat=new THREE.SpriteMaterial({map:tex,transparent:true,depthTest:false});\n    const s=new THREE.Sprite(mat);s.scale.set(1.5,0.38,1);return s;\n  }\n\n  function init(){\n    renderer=new THREE.WebGLRenderer({canvas,antialias:true,alpha:true,preserveDrawingBuffer:true,powerPreference:'high-performance'});\n    renderer.setPixelRatio(Math.min(devicePixelRatio,2));\n    scene=new THREE.Scene();\n    camera=new THREE.PerspectiveCamera(42,1,0.1,100);camera.position.set(0,0,6.2);\n    resize();\n    group=new THREE.Group();scene.add(group);\n\n    const acc=ACCENT();\n    \/\/ track ring (270deg)\n    const trackGeo=new THREE.TorusGeometry(2,0.13,32,140,Math.PI*1.5);\n    const trackMat=new THREE.MeshStandardMaterial({color:0x27406e,metalness:.55,roughness:.4,emissive:0x12274d,emissiveIntensity:.55});\n    trackMesh=new THREE.Mesh(trackGeo,trackMat);\n    \/\/ progress ring\n    const progMat=new THREE.MeshStandardMaterial({color:new THREE.Color(acc[0],acc[1],acc[2]),metalness:.5,roughness:.18,emissive:new THREE.Color(acc[0]*.8,acc[1]*.9,acc[2]),emissiveIntensity:1.1});\n    progMesh=new THREE.Mesh(new THREE.TorusGeometry(2,0.15,32,140,0.01),progMat);\n    \/\/ rotate so gap sits at bottom (start at 225deg)\n    const startAngle=Math.PI*0.75;\n    trackMesh.rotation.z=startAngle;progMesh.rotation.z=startAngle;\n    group.add(trackMesh,progMesh);\n\n    \/\/ tick marks around ring\n    const tickMat=new THREE.MeshStandardMaterial({color:0x3b82f6,emissive:0x1e40af,emissiveIntensity:.6,metalness:.4,roughness:.4});\n    for(let i=0;i<=9;i++){\n      const a=startAngle - (i\/9)*Math.PI*1.5;\n      const tick=new THREE.Mesh(new THREE.BoxGeometry(0.06,0.22,0.06),tickMat);\n      tick.position.set(Math.cos(a)*2.32,Math.sin(a)*2.32,0);\n      tick.rotation.z=a-Math.PI\/2;group.add(tick);\n    }\n\n    \/\/ glass orbs\n    const labels=['WRITING','SPEAKING','READING'];\n    labels.forEach((lb,i)=>{\n      const orbMat=new THREE.MeshPhysicalMaterial({color:0x9ec5ff,metalness:0,roughness:0.06,\n        transmission:0.7,clearcoat:1,clearcoatRoughness:0.1,transparent:true,opacity:.92,\n        emissive:new THREE.Color(acc[0],acc[1],acc[2]),emissiveIntensity:.18});\n      const orb=new THREE.Mesh(new THREE.SphereGeometry(0.34,32,32),orbMat);\n      const label=makeOrbLabel(lb);label.position.y=0.62;\n      const holder=new THREE.Group();holder.add(orb,label);\n      holder.userData={phase:i*(Math.PI*2\/3)};\n      group.add(holder);orbs.push(holder);\n    });\n\n    \/\/ glow sprite behind\n    const gc=document.createElement('canvas');gc.width=gc.height=256;\n    const gx=gc.getContext('2d');const grd=gx.createRadialGradient(128,128,10,128,128,128);\n    grd.addColorStop(0,'rgba(59,130,246,.55)');grd.addColorStop(.5,'rgba(37,99,235,.18)');grd.addColorStop(1,'rgba(37,99,235,0)');\n    gx.fillStyle=grd;gx.fillRect(0,0,256,256);\n    glow=new THREE.Sprite(new THREE.SpriteMaterial({map:new THREE.CanvasTexture(gc),transparent:true,depthWrite:false,blending:THREE.AdditiveBlending}));\n    glow.scale.set(7,7,1);glow.position.z=-1;scene.add(glow);\n\n    \/\/ lights\n    scene.add(new THREE.AmbientLight(0x88aaff,.55));\n    const l1=new THREE.PointLight(0x3b82f6,1.6,30);l1.position.set(4,4,6);scene.add(l1);\n    const l2=new THREE.PointLight(0x06b6d4,1.3,30);l2.position.set(-5,-3,4);scene.add(l2);\n    const l3=new THREE.DirectionalLight(0xffffff,.5);l3.position.set(0,5,8);scene.add(l3);\n    window.__lights=[l1,l2,l3];\n  }\n\n  function setProgressArc(frac){\n    \/\/ rebuild progress torus arc length\n    const arc=Math.max(0.01,Math.PI*1.5*frac);\n    progMesh.geometry.dispose();\n    progMesh.geometry=new THREE.TorusGeometry(2,0.15,32,140,arc);\n  }\n\n  let mx=0,my=0,tx=0,ty=0;\n  addEventListener('mousemove',e=>{\n    if(document.body.classList.contains('no-motion'))return;\n    tx=(e.clientX\/innerWidth-0.5);ty=(e.clientY\/innerHeight-0.5);\n  });\n\n  function resize(){\n    const r=canvas.getBoundingClientRect();\n    const w=r.width||440,h=r.height||440;\n    renderer.setSize(w,h,false);\n    if(camera){camera.aspect=w\/h;camera.updateProjectionMatrix();}\n  }\n  addEventListener('resize',()=>{ if(renderer)resize(); });\n\n  function frame(ts){\n    if(!running)return;\n    if(!t0)t0=ts;const el=(ts-t0)\/1000;\n    \/\/ ease progress to target\n    curProg+=(targetProg-curProg)*0.04*speedMul;\n    setProgressArc(curProg);\n    \/\/ band number count\n    const band=(curProg\/0.78*9.0);\n    document.getElementById('bandNum').textContent=Math.min(9.0,band).toFixed(1);\n    \/\/ orbs orbit\n    orbs.forEach((h,i)=>{\n      const a=h.userData.phase+el*0.5*speedMul;\n      h.position.set(Math.cos(a)*2.0,Math.sin(a)*0.5,Math.sin(a)*2.0);\n      const sc=0.85+0.25*((Math.sin(a)+1)\/2);h.scale.setScalar(sc);\n      h.children[1].material.opacity=0.35+0.65*((Math.sin(a)+1)\/2);\n    });\n    \/\/ parallax\n    mx+=(tx-mx)*0.05;my+=(ty-my)*0.05;\n    group.rotation.y=mx*0.5;group.rotation.x=my*0.4;\n    \/\/ intensity\n    if(window.__lights){window.__lights[0].intensity=1.6*intensity;window.__lights[1].intensity=1.3*intensity;}\n    glow.material.opacity=Math.min(1,intensity);glow.scale.setScalar(6.5+intensity*0.8);\n    progMesh.material.emissiveIntensity=1.1*intensity;\n    renderer.render(scene,camera);\n    rafId=requestAnimationFrame(frame);\n  }\n\n  function start(){\n    if(document.body.classList.contains('fallback-3d'))return;\n    if(!started){init();started=true;}\n    if(running)return;running=true;t0=0;rafId=requestAnimationFrame(frame);\n  }\n  function stop(){running=false;if(rafId)cancelAnimationFrame(rafId);\n    document.getElementById('bandNum').textContent='9.0';}\n  function dispose(){\n    stop();\n    if(!renderer)return;\n    scene&&scene.traverse(o=>{ if(o.geometry)o.geometry.dispose();\n      if(o.material){ (Array.isArray(o.material)?o.material:[o.material]).forEach(m=>{ if(m.map)m.map.dispose(); m.dispose&&m.dispose(); }); } });\n    renderer.dispose();\n  }\n  addEventListener('pagehide',dispose,{once:true});\n\n  \/\/ lazy-init when hero stage visible\n  const stObs=new IntersectionObserver((es)=>{\n    es.forEach(e=>{ if(e.isIntersecting)start(); else stop(); });\n  },{threshold:.2});\n  stObs.observe(document.getElementById('stage'));\n\n  \/\/ expose to tweak panel\n  window.__startGauge=start;window.__stopGauge=stop;\n  window.__setGaugeAccent=(t)=>{accentT=t; if(progMesh){const a=ACCENT();\n    progMesh.material.color.setRGB(a[0],a[1],a[2]);progMesh.material.emissive.setRGB(a[0]*.8,a[1]*.9,a[2]);}};\n  window.__setGaugeSpeed=(s)=>{speedMul=s;};\n  window.__setGaugeIntensity=(v)=>{intensity=v;};\n})();\n\napplyReduced();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>All English 4U Grammar IELTS TOEFL Cambridge CELPIP Dictation Contact Start Free Grammar IELTS TOEFL Cambridge CELPIP Dictation Contact Start Free Check Your English Vocabulary for IELTS IELTS Vocabulary Practice Interactive exercises based on Check Your English Vocabulary for IELTS. Covers the vocabulary you need for Writing, Speaking and Reading \u2014 10 topics, instant feedback, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-with-title","meta":{"footnotes":""},"class_list":["post-113","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/113","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/comments?post=113"}],"version-history":[{"count":23,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/113\/revisions"}],"predecessor-version":[{"id":5977,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/113\/revisions\/5977"}],"wp:attachment":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/media?parent=113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}