{"id":835,"date":"2026-05-19T00:37:03","date_gmt":"2026-05-19T00:37:03","guid":{"rendered":"https:\/\/allenglish4u.com\/skills\/"},"modified":"2026-07-05T02:44:42","modified_gmt":"2026-07-05T02:44:42","slug":"skills","status":"publish","type":"page","link":"https:\/\/allenglish4u.com\/vi\/skills\/","title":{"rendered":"K\u1ef9 n\u0103ng"},"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:root{\n  \/* accent \u2014 tweakable purple <-> indigo *\/\n  --a1: #8B5CF6;\n  --a2: #6366F1;\n  --accent-glow: rgba(139,92,246,.32);\n\n  --light-1:#F0F7FF; --light-2:#F8FAFF; --white:#FFFFFF;\n  --text:#0F172A; --muted:#475569; --subtle:#94A3B8; --border:#E2E8F0;\n  --d1:#050E20; --d2:#0A1628; --d3:#0D2352;\n\n  --r-sm:6px; --r-md:10px; --r-lg:16px; --r-xl:22px; --r-2xl:32px;\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 var(--accent-glow);\n\n  --t-fast:160ms ease;\n  --t-mid:280ms cubic-bezier(.4,0,.2,1);\n  --t-spring:400ms cubic-bezier(.34,1.56,.64,1);\n  --speed:1;\n}\n*{box-sizing:border-box;margin:0;padding:0}\nhtml{scroll-behavior:smooth}\nbody{\n  font-family:'Plus Jakarta Sans',system-ui,sans-serif;\n  color:var(--text);\n  background:var(--light-2);\n  -webkit-font-smoothing:antialiased;\n  overflow-x:hidden;\n}\n.serif{font-family:'Fraunces',Georgia,serif}\na{color:inherit;text-decoration:none}\nimg{display:block;max-width:100%}\n:focus-visible{outline:2px solid var(--a2);outline-offset:2px;border-radius:4px}\nheader.solid :focus-visible,.quiz-main :focus-visible,.tweak-panel :focus-visible{outline-color:var(--a2)}\n.hero :focus-visible,.yt-band :focus-visible,footer :focus-visible{outline-color:#C4B5FD}\n.wrap{width:min(1200px,92vw);margin:0 auto}\n.grad-text{\n  background:linear-gradient(100deg,var(--a1),var(--a2));\n  -webkit-background-clip:text;background-clip:text;\n  -webkit-text-fill-color:transparent;color:transparent;\n}\n.btn{\n  display:inline-flex;align-items:center;gap:.55em;\n  font-family:inherit;font-weight:700;font-size:15px;\n  padding:13px 22px;border-radius:999px;cursor:pointer;border:none;\n  transition:transform var(--t-spring),box-shadow var(--t-mid),background var(--t-fast);\n  white-space:nowrap;\n}\n.btn-grad{\n  background:linear-gradient(100deg,var(--a1),var(--a2));color:#fff;\n  box-shadow:var(--sh-glow);\n}\n.btn-grad:hover{transform:translateY(-2px) scale(1.025);box-shadow:0 12px 30px var(--accent-glow)}\n.btn-ghost{\n  background:rgba(255,255,255,.06);color:#fff;border:1.5px solid rgba(255,255,255,.22);\n}\n.btn-ghost:hover{transform:translateY(-2px);background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.4)}\n.btn-light{background:var(--text);color:#fff}\n.btn-light:hover{transform:translateY(-2px) scale(1.02);box-shadow:var(--sh-lg)}\n.btn-soft{\n  background:color-mix(in srgb,var(--a1) 12%,#fff);\n  color:var(--a2);\n}\n.btn-soft:hover{transform:translateY(-2px);background:color-mix(in srgb,var(--a1) 18%,#fff)}\n.btn-disabled{background:#EEF1F6;color:var(--subtle);cursor:not-allowed;box-shadow:none}\n.btn-disabled:hover{transform:none}\n\n\/* ===== HEADER ===== *\/\nheader{\n  position:fixed;top:0;left:0;right:0;z-index:80;\n  transition:background var(--t-mid),box-shadow var(--t-mid),border-color var(--t-mid);\n  border-bottom:1px solid transparent;\n}\nheader.solid{\n  background:rgba(255,255,255,.82);\n  backdrop-filter:blur(16px) saturate(1.4);\n  -webkit-backdrop-filter:blur(16px) saturate(1.4);\n  border-bottom:1px solid var(--border);\n  box-shadow:0 1px 0 rgba(0,0,0,.02);\n}\n.nav{display:flex;align-items:center;gap:22px;height:72px}\n.brand{display:flex;align-items:center;gap:11px;font-weight:800;font-size:18px;letter-spacing:-.02em;flex-shrink:0}\n.brand img{width:40px;height:40px;border-radius:11px;box-shadow:var(--sh-card);flex-shrink:0}\n.brand.bt{color:#fff;transition:color var(--t-mid);white-space:nowrap}\nheader.solid.brand.bt{color:var(--text)}\n.nav-links{display:flex;align-items:center;gap:4px;margin-left:auto}\n.nav-links a{\n  font-size:14.5px;font-weight:600;color:rgba(255,255,255,.78);\n  padding:9px 13px;border-radius:var(--r-md);position:relative;\n  transition:color var(--t-fast),background var(--t-fast);\n}\n.nav-links a:hover{color:#fff;background:rgba(255,255,255,.08)}\nheader.solid.nav-links a{color:var(--muted)}\nheader.solid.nav-links a:hover{color:var(--text);background:var(--light-1)}\n.nav-links a.active{color:#fff;font-weight:700}\nheader.solid.nav-links a.active{color:var(--a2)}\n.nav-links 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(--a1),var(--a2));\n}\n.nav-tools{display:flex;align-items:center;gap:12px}\n.icon-btn{\n  width:40px;height:40px;border-radius:var(--r-md);border:none;cursor:pointer;\n  display:grid;place-items:center;background:rgba(255,255,255,.08);color:#fff;\n  transition:background var(--t-fast),transform var(--t-fast);\n}\n.icon-btn:hover{background:rgba(255,255,255,.16);transform:translateY(-1px)}\nheader.solid.icon-btn{background:var(--light-1);color:var(--muted)}\nheader.solid.icon-btn:hover{background:var(--border)}\n.hamburger{display:none}\n\n\/* ===== HERO ===== *\/\n.hero{\n  position:relative;\n  background:\n    radial-gradient(1100px 600px at 72% 34%,rgba(99,102,241,.30),transparent 60%),\n    radial-gradient(900px 520px at 78% 18%,rgba(139,92,246,.28),transparent 55%),\n    linear-gradient(165deg,var(--d1) 0%,var(--d2) 48%,var(--d3) 100%);\n  color:#fff;overflow:hidden;padding:150px 0 90px;\n}\n.hero-grid{display:grid;grid-template-columns:1.04fr.96fr;gap:40px;align-items:center}\n.eyebrow{\n  display:inline-flex;align-items:center;gap:9px;\n  font-size:12.5px;font-weight:700;letter-spacing:.12em;\n  color:#fff;padding:7px 15px;border-radius:999px;\n  background:rgba(139,92,246,.16);border:1px solid rgba(139,92,246,.4);\n  margin-bottom:24px;\n}\n.eyebrow.dot{width:7px;height:7px;border-radius:50%;background:var(--a1);box-shadow:0 0 12px var(--a1)}\n.hero h1{\n  font-size:clamp(40px,5.6vw,72px);line-height:1.02;letter-spacing:-.025em;\n  font-weight:700;margin-bottom:22px;text-wrap:balance;\n}\n.hero p.sub{font-size:clamp(16px,1.5vw,19px);line-height:1.6;color:rgba(226,232,240,.86);max-width:560px;margin-bottom:28px}\n.chips{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:30px}\n.chip{\n  display:inline-flex;align-items:center;gap:8px;font-size:13.5px;font-weight:600;\n  padding:9px 15px;border-radius:999px;\n  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);color:#E2E8F0;\n}\n.chip svg{color:var(--a1)}\n.hero-cta{display:flex;flex-wrap:wrap;gap:14px}\n.hero-visual{position:relative;height:min(560px,62vw);min-height:420px}\n#gem-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}\n.gem-glow{\n  position:absolute;inset:6% 6%;border-radius:50%;\n  background:radial-gradient(circle,rgba(139,92,246,.5),rgba(99,102,241,.18) 45%,transparent 70%);\n  filter:blur(26px);z-index:-1;animation:pulse calc(5200ms \/ var(--speed)) ease-in-out infinite;\n}\n@keyframes pulse{0%,100%{opacity:.65;transform:scale(.95)}50%{opacity:1;transform:scale(1.05)}}\n.gem-fallback{\n  position:absolute;inset:0;display:none;place-items:center;\n}\n.gem-fallback.show{display:grid}\n.gem-stage{position:relative;width:min(400px,86%);aspect-ratio:1;display:grid;place-items:center}\n.gem-crystal{\n  width:58%;aspect-ratio:1;position:relative;\n  border-radius:46% 54% 50% 50%\/52% 48% 52% 48%;\n  background:conic-gradient(from 210deg at 50% 44%,#C4B5FD,#8B5CF6,#6366F1,#818CF8,#A78BFA,#C4B5FD);\n  box-shadow:0 26px 70px var(--accent-glow),inset 0 -16px 42px rgba(8,14,32,.45),inset 0 12px 30px rgba(255,255,255,.5);\n  animation:floaty calc(6500ms \/ var(--speed)) ease-in-out infinite;\n}\n@keyframes floaty{0%,100%{transform:translateY(-9px) rotate(-3deg)}50%{transform:translateY(9px) rotate(3deg)}}\n.gem-crystal::before{\n  content:\"\";position:absolute;top:13%;left:19%;width:40%;height:28%;border-radius:50%;\n  background:radial-gradient(circle,rgba(255,255,255,.9),transparent 68%);filter:blur(2px);\n}\n.gem-crystal::after{\n  content:\"\";position:absolute;inset:0;border-radius:inherit;\n  background:\n    linear-gradient(135deg,transparent 47%,rgba(255,255,255,.28) 49%,transparent 52%),\n    linear-gradient(40deg,transparent 47%,rgba(255,255,255,.18) 49%,transparent 52%),\n    linear-gradient(95deg,transparent 47%,rgba(8,14,32,.16) 49%,transparent 52%);\n}\n.gem-stage.lab{\n  position:absolute;font-size:11.5px;font-weight:800;letter-spacing:.1em;color:#fff;z-index:2;\n  background:rgba(13,35,82,.5);padding:7px 13px;border-radius:999px;\n  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);\n  border:1px solid rgba(196,181,253,.5);box-shadow:0 6px 18px rgba(8,14,32,.35);\n}\n.gem-stage.lab.l-top{top:4%;left:50%;transform:translateX(-50%)}\n.gem-stage.lab.l-right{top:50%;right:0;transform:translateY(-50%)}\n.gem-stage.lab.l-bottom{bottom:4%;left:50%;transform:translateX(-50%)}\n.gem-stage.lab.l-left{top:50%;left:0;transform:translateY(-50%)}\n.gem-stage.spk{position:absolute;width:5px;height:5px;border-radius:50%;background:#E9D5FF;box-shadow:0 0 10px 2px rgba(196,181,253,.8);animation:twk calc(3000ms \/ var(--speed)) ease-in-out infinite}\n.gem-stage.spk.s1{top:20%;left:24%;animation-delay:.2s}\n.gem-stage.spk.s2{top:30%;right:18%;animation-delay:1.1s}\n.gem-stage.spk.s3{bottom:24%;left:30%;animation-delay:.6s}\n.gem-stage.spk.s4{bottom:30%;right:26%;animation-delay:1.6s}\n@keyframes twk{0%,100%{opacity:.2;transform:scale(.7)}50%{opacity:1;transform:scale(1.3)}}\n.scroll-cue{\n  position:absolute;left:50%;bottom:26px;transform:translateX(-50%);\n  display:flex;flex-direction:column;align-items:center;gap:7px;\n  font-size:11px;letter-spacing:.18em;color:rgba(255,255,255,.5);font-weight:600;\n}\n.scroll-cue.mouse{width:22px;height:34px;border:2px solid rgba(255,255,255,.35);border-radius:12px;position:relative}\n.scroll-cue.mouse::after{content:\"\";position:absolute;left:50%;top:7px;width:3px;height:6px;border-radius:2px;background:rgba(255,255,255,.6);transform:translateX(-50%);animation:scrolly 1.6s ease-in-out infinite}\n@keyframes scrolly{0%,100%{opacity:0;transform:translate(-50%,0)}45%{opacity:1;transform:translate(-50%,8px)}}\n\n\/* ===== SECTIONS ===== *\/\nsection.block{padding:clamp(64px,9vw,128px) 0}\n.sec-head{text-align:center;max-width:660px;margin:0 auto 56px}\n.kicker{\n  display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:700;letter-spacing:.12em;\n  color:var(--a2);margin-bottom:14px;text-transform:uppercase;\n}\n.kicker::before{content:\"\";width:7px;height:7px;border-radius:50%;background:linear-gradient(135deg,var(--a1),var(--a2));box-shadow:0 0 10px var(--accent-glow);flex-shrink:0}\n.sec-head h2{font-size:clamp(30px,3.6vw,46px);line-height:1.05;letter-spacing:-.02em;font-weight:700;margin-bottom:14px;text-wrap:balance}\n.sec-head p{font-size:17px;line-height:1.6;color:var(--muted);text-wrap:pretty;max-width:60ch;margin-inline:auto}\n\n\/* skill cards *\/\n.skills-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:24px}\n.skill-card{\n  position:relative;background:var(--white);border:1px solid var(--border);\n  border-radius:18px;padding:32px;overflow:hidden;\n  transition:transform var(--t-spring),box-shadow var(--t-mid),border-color var(--t-mid);\n  box-shadow:var(--sh-card);display:flex;flex-direction:column;\n}\n.skill-card::before{\n  content:\"\";position:absolute;inset:0;opacity:0;transition:opacity var(--t-mid);\n  background:radial-gradient(420px 220px at 90% -10%,var(--sc),transparent 70%);\n}\n.skill-card:hover{transform:translateY(-4px);box-shadow:var(--sh-lg);border-color:transparent}\n.skill-card:hover::before{opacity:.1}\n.skill-card.num{position:absolute;top:26px;right:30px;font-size:54px;font-weight:800;color:var(--light-1);line-height:1}\n.sk-ico{\n  width:60px;height:60px;border-radius:var(--r-lg);display:grid;place-items:center;color:#fff;\n  margin-bottom:22px;box-shadow:0 8px 20px color-mix(in srgb,var(--sc) 40%,transparent);\n  background:linear-gradient(135deg,var(--sc),var(--sc2));\n}\n.skill-card h3{font-size:24px;font-weight:700;letter-spacing:-.01em;margin-bottom:10px}\n.skill-card p.desc{font-size:15.5px;line-height:1.6;color:var(--muted);margin-bottom:18px}\n.sk-chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:24px}\n.skill-card>.btn{margin-top:auto;align-self:flex-start}\n.sk-chip{\n  font-size:12.5px;font-weight:600;color:var(--muted);\n  padding:6px 12px;border-radius:999px;background:var(--light-1);border:1px solid var(--border);\n}\n.sk-chip.soon{color:var(--a2);background:color-mix(in srgb,var(--a1) 10%,#fff);border-color:color-mix(in srgb,var(--a1) 25%,#fff)}\n\n\/* Coming-soon (Speaking) card \u2014 visibly differentiated *\/\n.skill-card.coming{\n  background:repeating-linear-gradient(135deg,#F8FAFF,#F8FAFF 12px,#F4F7FE 12px,#F4F7FE 24px);\n  border:1.5px dashed #CBD5E1;box-shadow:none;\n}\n.skill-card.coming:hover{transform:translateY(-4px);box-shadow:var(--sh-card);border-color:#B4C0D3}\n.skill-card.coming.sk-ico{filter:saturate(.5) opacity(.85)}\n.skill-card.coming h3,.skill-card.coming p.desc{color:var(--muted)}\n.skill-card.coming h3{color:#334155}\n.soon-badge{\n  position:absolute;top:24px;right:26px;display:inline-flex;align-items:center;gap:6px;\n  font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--a2);\n  padding:6px 11px;border-radius:999px;background:color-mix(in srgb,var(--a1) 12%,#fff);\n  border:1px solid color-mix(in srgb,var(--a1) 28%,#fff);\n}\n.soon-badge.sd{width:7px;height:7px;border-radius:50%;background:var(--a1);animation:sbpulse 2s ease-in-out infinite}\n@keyframes sbpulse{0%,100%{opacity:.4}50%{opacity:1}}\n\n\/* quiz *\/\n.quiz-wrap{\n  background:linear-gradient(170deg,#fff,var(--light-2));\n  border:1px solid var(--border);border-radius:var(--r-2xl);\n  box-shadow:var(--sh-lg);overflow:hidden;display:grid;grid-template-columns:.85fr 1.15fr;\n}\n.quiz-side{\n  background:linear-gradient(165deg,var(--d2),var(--d3));color:#fff;padding:44px 38px;\n  display:flex;flex-direction:column;\n}\n.quiz-side.kicker{color:#C4B5FD}\n.quiz-side h3{font-size:28px;font-weight:700;letter-spacing:-.01em;margin-bottom:12px;line-height:1.12}\n.quiz-side p{font-size:15px;line-height:1.6;color:rgba(226,232,240,.8);margin-bottom:30px}\n.rings{display:grid;grid-template-columns:repeat(2,1fr);gap:18px;margin-top:auto}\n.ring{display:flex;align-items:center;gap:12px}\n.ring svg{width:52px;height:52px;flex-shrink:0;transform:rotate(-90deg)}\n.ring.rt{transition:stroke-dashoffset 600ms cubic-bezier(.34,1.56,.64,1)}\n.ring.rl{font-size:12.5px;font-weight:700;letter-spacing:.04em}\n.ring.rl small{display:block;font-size:11px;font-weight:600;color:rgba(226,232,240,.6);letter-spacing:.02em}\n.quiz-main{padding:42px 40px;display:flex;flex-direction:column}\n.q-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:22px}\n.q-counter{font-size:13px;font-weight:700;color:#64748B;letter-spacing:.04em;white-space:nowrap}\n.q-score{font-size:14px;font-weight:700;color:var(--a2);background:color-mix(in srgb,var(--a1) 10%,#fff);padding:7px 14px;border-radius:999px;white-space:nowrap}\n.q-tag{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--a2);margin-bottom:12px}\n.q-tag.qd{width:8px;height:8px;border-radius:50%;background:linear-gradient(135deg,var(--a1),var(--a2))}\n.q-text{font-size:20px;font-weight:700;line-height:1.4;letter-spacing:-.01em;margin-bottom:22px;min-height:56px}\n.q-text em{font-style:normal;background:color-mix(in srgb,var(--a1) 14%,#fff);padding:1px 8px;border-radius:6px;color:var(--a2);font-weight:700}\n.opts{display:flex;flex-direction:column;gap:11px;margin-bottom:18px}\n.opt{\n  display:flex;align-items:center;gap:14px;text-align:left;cursor:pointer;\n  font-family:inherit;font-size:15.5px;font-weight:600;color:var(--text);\n  padding:15px 18px;border-radius:var(--r-lg);background:var(--white);\n  border:1.5px solid var(--border);transition:all var(--t-fast);\n}\n.opt:hover:not(.locked){border-color:var(--a1);background:color-mix(in srgb,var(--a1) 5%,#fff);transform:translateX(3px)}\n.opt.key{\n  width:28px;height:28px;border-radius:8px;flex-shrink:0;display:grid;place-items:center;\n  font-size:13px;font-weight:800;background:var(--light-1);color:var(--muted);transition:all var(--t-fast);\n}\n.opt.locked{cursor:default}\n.opt.correct{border-color:#16A34A;background:#F0FDF4}\n.opt.correct.key{background:#16A34A;color:#fff}\n.opt.wrong{border-color:#DC2626;background:#FEF2F2}\n.opt.wrong.key{background:#DC2626;color:#fff}\n.opt.mark{margin-left:auto;opacity:0;transition:opacity var(--t-fast)}\n.opt.correct.mark,.opt.wrong.mark{opacity:1}\n.explain{\n  font-size:14px;line-height:1.55;color:var(--muted);padding:14px 16px;border-radius:var(--r-md);\n  background:var(--light-1);border-left:3px solid var(--a1);margin-bottom:20px;\n  max-height:0;opacity:0;overflow:hidden;padding-top:0;padding-bottom:0;\n  transition:max-height var(--t-mid),opacity var(--t-mid),padding var(--t-mid);\n}\n.explain.show{max-height:160px;opacity:1;padding-top:14px;padding-bottom:14px}\n.explain b{color:var(--text)}\n.q-actions{display:flex;gap:12px;margin-top:auto}\n.quiz-done{text-align:center;padding:20px 0 6px}\n.quiz-done.big{font-size:46px;font-weight:800;line-height:1;margin-bottom:8px}\n.quiz-done.msg{font-size:16px;color:var(--muted);margin-bottom:20px}\n\n\/* tips *\/\n.tips-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}\n.tip{\n  background:var(--white);border:1px solid var(--border);border-radius:18px;padding:28px;\n  box-shadow:var(--sh-card);transition:transform var(--t-spring),box-shadow var(--t-mid);\n}\n.tip:hover{transform:translateY(-4px);box-shadow:var(--sh-lg)}\n.tip.ti{width:46px;height:46px;border-radius:13px;display:grid;place-items:center;color:#fff;margin-bottom:16px;background:linear-gradient(135deg,var(--sc),var(--sc2))}\n.tip h4{font-size:17px;font-weight:700;margin-bottom:9px}\n.tip p{font-size:14px;line-height:1.6;color:var(--muted)}\n\n\/* youtube band *\/\n.yt-band{background:linear-gradient(165deg,var(--d1),var(--d3));color:#fff}\n.yt-grid{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}\n.yt-left.kicker{color:#C4B5FD}\n.yt-left h2{font-size:clamp(28px,3.4vw,42px);line-height:1.1;font-weight:700;letter-spacing:-.02em;margin-bottom:16px}\n.yt-left p{font-size:16px;line-height:1.6;color:rgba(226,232,240,.8);margin-bottom:26px;max-width:460px}\n.btn-yt{background:#FF0000;color:#fff;box-shadow:0 8px 24px rgba(255,0,0,.3)}\n.btn-yt:hover{transform:translateY(-2px) scale(1.02);box-shadow:0 12px 30px rgba(255,0,0,.4)}\n.yt-cards{display:flex;flex-direction:column;gap:18px}\n.yt-card{\n  display:flex;gap:18px;align-items:center;background:rgba(255,255,255,.05);\n  border:1px solid rgba(255,255,255,.1);border-radius:var(--r-lg);padding:14px;\n  transition:background var(--t-fast),transform var(--t-fast);cursor:pointer;\n}\n.yt-card:hover{background:rgba(255,255,255,.1);transform:translateX(4px)}\n.yt-thumb{\n  width:120px;height:74px;flex-shrink:0;border-radius:var(--r-md);position:relative;overflow:hidden;\n  background:linear-gradient(135deg,var(--a1),var(--a2));display:grid;place-items:center;\n}\n.yt-thumb::after{content:\"\";position:absolute;inset:0;background:radial-gradient(circle at 70% 30%,rgba(255,255,255,.25),transparent 60%)}\n.yt-thumb.play{width:38px;height:38px;border-radius:50%;background:rgba(255,255,255,.92);display:grid;place-items:center;z-index:1;color:#FF0000}\n.yt-card.info h5{font-size:15.5px;font-weight:700;margin-bottom:5px;line-height:1.3}\n.yt-card.info span{font-size:13px;color:rgba(226,232,240,.6);font-weight:600}\n\n\/* footer *\/\nfooter{background:var(--d1);color:#fff;padding:72px 0 32px}\n.foot-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:40px;margin-bottom:48px}\n.foot-brand.brand{margin-bottom:16px}\n.foot-brand.brand.bt{color:#fff}\n.foot-brand p{font-size:14.5px;line-height:1.6;color:rgba(226,232,240,.6);max-width:280px;margin-bottom:20px}\n.socials{display:flex;gap:10px}\n.socials a{width:40px;height:40px;border-radius:11px;display:grid;place-items:center;background:rgba(255,255,255,.07);transition:all var(--t-fast)}\n.socials a:hover{background:linear-gradient(135deg,var(--a1),var(--a2));transform:translateY(-2px)}\n.foot-col h6{font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);margin-bottom:16px}\n.foot-col a{display:block;font-size:14.5px;color:rgba(226,232,240,.72);padding:7px 0;transition:color var(--t-fast)}\n.foot-col a:hover{color:#fff}\n.foot-bottom{border-top:1px solid rgba(255,255,255,.08);padding-top:26px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px;font-size:13.5px;color:rgba(226,232,240,.5)}\n\n\/* reveal *\/\n.reveal{opacity:0;transform:translateY(30px);transition:opacity.7s cubic-bezier(.4,0,.2,1),transform.7s cubic-bezier(.4,0,.2,1)}\n.reveal.in{opacity:1;transform:none}\n.reveal.d1{transition-delay:.08s}.reveal.d2{transition-delay:.16s}.reveal.d3{transition-delay:.24s}.reveal.d4{transition-delay:.32s}\n\n\/* ===== TWEAK PANEL ===== *\/\n.tweak-gear{\n  position:fixed;right:22px;bottom:22px;z-index:90;width:52px;height:52px;border-radius:50%;\n  border:none;cursor:pointer;display:grid;place-items:center;color:#fff;\n  background:linear-gradient(135deg,var(--a1),var(--a2));box-shadow:var(--sh-glow);\n  transition:transform var(--t-spring);\n}\n.tweak-gear:hover{transform:rotate(40deg) scale(1.08)}\n.tweak-gear svg{animation:spin 14s linear infinite}\n@keyframes spin{to{transform:rotate(360deg)}}\n.tweak-panel{\n  position:fixed;right:22px;bottom:86px;z-index:91;width:288px;\n  background:rgba(255,255,255,.92);backdrop-filter:blur(20px);\n  border:1px solid var(--border);border-radius:var(--r-xl);box-shadow:var(--sh-lg);\n  padding:20px;transform:translateY(16px) scale(.96);opacity:0;pointer-events:none;\n  transition:transform var(--t-spring),opacity var(--t-mid);\n}\n.tweak-panel.open{transform:none;opacity:1;pointer-events:auto}\n.tp-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px}\n.tp-head strong{font-size:15px;font-weight:800;letter-spacing:-.01em}\n.tp-close{border:none;background:var(--light-1);width:28px;height:28px;border-radius:8px;cursor:pointer;color:var(--muted);display:grid;place-items:center}\n.tp-close:hover{background:var(--border)}\n.tp-row{margin-bottom:18px}\n.tp-row:last-child{margin-bottom:0}\n.tp-row label{display:flex;justify-content:space-between;font-size:13px;font-weight:700;color:var(--text);margin-bottom:9px}\n.tp-row label span{color:var(--a2);font-weight:600}\ninput[type=range]{\n  -webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:99px;\n  background:var(--border);outline:none;cursor:pointer;\n}\ninput[type=range]::-webkit-slider-thumb{\n  -webkit-appearance:none;width:18px;height:18px;border-radius:50%;\n  background:linear-gradient(135deg,var(--a1),var(--a2));cursor:pointer;box-shadow:0 2px 6px var(--accent-glow);\n}\ninput[type=range]::-moz-range-thumb{width:18px;height:18px;border:none;border-radius:50%;background:var(--a1);cursor:pointer}\n.hue-track{height:8px;border-radius:99px;background:linear-gradient(90deg,#8B5CF6,#6366F1);margin-bottom:9px}\n.tp-toggle{display:flex;align-items:center;justify-content:space-between}\n.tp-toggle.sw{width:44px;height:25px;border-radius:99px;background:var(--border);position:relative;cursor:pointer;transition:background var(--t-fast)}\n.tp-toggle.sw::after{content:\"\";position:absolute;top:3px;left:3px;width:19px;height:19px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.2);transition:transform var(--t-spring)}\n.tp-toggle.sw.on{background:linear-gradient(90deg,var(--a1),var(--a2))}\n.tp-toggle.sw.on::after{transform:translateX(19px)}\n\n\/* ===== RESPONSIVE ===== *\/\n@media(max-width:920px){\n  .hero-grid{grid-template-columns:1fr;gap:0}\n  .hero-visual{height:360px;min-height:340px;order:-1;margin-bottom:8px}\n  .hero{padding:128px 0 70px}\n  .quiz-wrap{grid-template-columns:1fr}\n  .yt-grid{grid-template-columns:1fr;gap:34px}\n  .tips-grid{grid-template-columns:repeat(2,1fr)}\n  .foot-grid{grid-template-columns:1fr 1fr}\n}\n@media(max-width:680px){\n  .nav-links,.nav-tools.srch{display:none}\n  .hamburger{display:grid}\n  .skills-grid{grid-template-columns:1fr}\n  .tips-grid{grid-template-columns:1fr}\n  .foot-grid{grid-template-columns:1fr}\n  .quiz-main,.quiz-side{padding:30px 24px}\n  section.block{padding:72px 0}\n  .rings{grid-template-columns:1fr}\n}\n\n\/* mobile menu *\/\n.mobile-menu{\n  position:fixed;inset:0;z-index:85;background:rgba(5,14,32,.97);backdrop-filter:blur(8px);\n  display:flex;flex-direction:column;padding:90px 32px 32px;gap:6px;\n  transform:translateX(100%);transition:transform var(--t-mid);\n}\n.mobile-menu.open{transform:none}\n.mobile-menu a{font-size:20px;font-weight:700;color:#fff;padding:14px 0;border-bottom:1px solid rgba(255,255,255,.08)}\n.mobile-menu a.active{color:var(--a1)}\n.mobile-menu.mclose{position:absolute;top:24px;right:24px;width:44px;height:44px;border-radius:12px;border:none;background:rgba(255,255,255,.1);color:#fff;cursor:pointer;display:grid;place-items:center}\n\n@media(prefers-reduced-motion:reduce){\n  *{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}\n  .reveal{opacity:1;transform:none}\n}\n<\/style>\n\n\n<!-- ===== HEADER ===== -->\n<header id=\"header\">\n  <div class=\"wrap nav\">\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 class=\"bt\">All English 4U<\/span>\n    <\/a>\n    <nav class=\"nav-links\">\n      <a href=\"\/grammar\/\">Grammar<\/a>\n      <a href=\"\/ielts\/\">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=\"nav-tools\">\n      <button class=\"icon-btn srch\" aria-label=\"Search\">\n        <svg width=\"18\" height=\"18\" 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      <button class=\"btn btn-grad\" style=\"padding:10px 18px;font-size:14px\" onclick=\"document.getElementById('skills').scrollIntoView()\">Start Free<\/button>\n      <button class=\"icon-btn hamburger\" aria-label=\"Menu\" onclick=\"document.getElementById('mmenu').classList.add('open')\">\n        <svg width=\"20\" height=\"20\" 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=\"mobile-menu\" id=\"mmenu\">\n  <button class=\"mclose\" onclick=\"document.getElementById('mmenu').classList.remove('open')\" aria-label=\"Close\">\n    <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M18 6 6 18M6 6l12 12\"\/><\/svg>\n  <\/button>\n  <a href=\"\/grammar\/\">Grammar<\/a><a href=\"\/ielts\/\">IELTS<\/a><a href=\"\/toefl\/\">TOEFL<\/a><a href=\"\/cambridge\/\">Cambridge<\/a>\n  <a href=\"\/celpip\/\">CELPIP<\/a>\n  <a href=\"\/dictation\/\">Dictation<\/a><a href=\"\/contact\/\">Contact<\/a>\n<\/div>\n\n<!-- ===== HERO ===== -->\n<div id=\"top\"><\/div>\n<section class=\"hero\">\n  <div class=\"wrap hero-grid\">\n    <div class=\"hero-copy\">\n      <span class=\"eyebrow\"><span class=\"dot\"><\/span>FOUR CORE SKILLS<\/span>\n      <h1 class=\"serif\">Master <span class=\"grad-text\">Every English Skill<\/span><\/h1>\n      <p class=\"sub\">Listening, Speaking, Reading and Writing \u2014 build all four with focused, interactive practice. Pick a skill and start improving today.<\/p>\n      <div class=\"chips\">\n        <span class=\"chip\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M9 18V5l12-2v13\"\/><circle cx=\"6\" cy=\"18\" r=\"3\"\/><circle cx=\"18\" cy=\"16\" r=\"3\"\/><\/svg>4 Core Skills<\/span>\n        <span class=\"chip\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"m13 2-3 8h7l-3 8\"\/><path d=\"M5 13h.01M5 8h.01\"\/><\/svg>Interactive Practice<\/span>\n        <span class=\"chip\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M3 17l6-6 4 4 8-8\"\/><\/svg>All Levels (A1\u2013C1)<\/span>\n        <span class=\"chip\"><svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\"><path d=\"M20 6 9 17l-5-5\"\/><\/svg>100% Free<\/span>\n      <\/div>\n      <div class=\"hero-cta\">\n        <button class=\"btn btn-grad\" onclick=\"document.getElementById('skills').scrollIntoView()\">Explore the skills\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><\/button>\n        <a class=\"btn btn-ghost\" href=\"https:\/\/www.youtube.com\" target=\"_blank\" rel=\"noopener\">\n          <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M23.5 6.2a3 3 0 0 0-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 0 0 .5 6.2 31 31 0 0 0 0 12a31 31 0 0 0 .5 5.8 3 3 0 0 0 2.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2.1A31 31 0 0 0 24 12a31 31 0 0 0-.5-5.8ZM9.6 15.6V8.4l6.3 3.6Z\"\/><\/svg>\n          Watch on YouTube<\/a>\n      <\/div>\n    <\/div>\n    <div class=\"hero-visual\">\n      <div class=\"gem-glow\"><\/div>\n      <canvas id=\"gem-canvas\"><\/canvas>\n      <div class=\"gem-fallback\" id=\"gemFallback\">\n        <div class=\"gem-stage\">\n          <span class=\"spk s1\"><\/span><span class=\"spk s2\"><\/span><span class=\"spk s3\"><\/span><span class=\"spk s4\"><\/span>\n          <div class=\"gem-crystal\"><\/div>\n          <span class=\"lab l-top\">LISTENING<\/span>\n          <span class=\"lab l-right\">SPEAKING<\/span>\n          <span class=\"lab l-bottom\">READING<\/span>\n          <span class=\"lab l-left\">WRITING<\/span>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n  <div class=\"scroll-cue\"><div class=\"mouse\"><\/div>SCROLL<\/div>\n<\/section>\n\n<!-- ===== SKILLS ===== -->\n<section class=\"block\" id=\"skills\">\n  <div class=\"wrap\">\n    <div class=\"sec-head reveal\">\n      <span class=\"kicker\">The four skills<\/span>\n      <h2 class=\"serif\">Four skills, one path to fluency<\/h2>\n      <p>Each skill has its own focused practice. Master them together and English clicks into place.<\/p>\n    <\/div>\n    <div class=\"skills-grid\">\n      <!-- LISTENING -->\n      <div class=\"skill-card reveal\" style=\"--sc:#8B5CF6;--sc2:#6366F1\">\n        <span class=\"num\">01<\/span>\n        <div class=\"sk-ico\"><svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 12a9 9 0 0 1 18 0v6a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3M3 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\"\/><\/svg><\/div>\n        <h3>Listening<\/h3>\n        <p class=\"desc\">Train your ear with dictation and real audio passages. Hear it, understand it.<\/p>\n        <div class=\"sk-chips\"><span class=\"sk-chip\">Dictation B1\u2013C1<\/span><span class=\"sk-chip\">IELTS Listening<\/span><\/div>\n        <button class=\"btn btn-grad\">Practise Listening\n          <svg width=\"16\" height=\"16\" 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><\/button>\n      <\/div>\n      <!-- SPEAKING -->\n      <div class=\"skill-card coming reveal d1\" style=\"--sc:#A78BFA;--sc2:#7C3AED\">\n        <span class=\"soon-badge\"><span class=\"sd\"><\/span>Coming Soon<\/span>\n        <div class=\"sk-ico\"><svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2a3 3 0 0 1 3 3v6a3 3 0 0 1-6 0V5a3 3 0 0 1 3-3Z\"\/><path d=\"M19 10a7 7 0 0 1-14 0M12 17v4M8 21h8\"\/><\/svg><\/div>\n        <h3>Speaking<\/h3>\n        <p class=\"desc\">Build fluency and pronunciation with shadowing and speaking drills.<\/p>\n        <div class=\"sk-chips\"><span class=\"sk-chip\">Pronunciation<\/span><span class=\"sk-chip soon\">Shadowing \u2014 Coming Soon<\/span><\/div>\n        <button class=\"btn btn-disabled\" disabled>Coming Soon<\/button>\n      <\/div>\n      <!-- READING -->\n      <div class=\"skill-card reveal d2\" style=\"--sc:#6366F1;--sc2:#4F46E5\">\n        <span class=\"num\">03<\/span>\n        <div class=\"sk-ico\"><svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 7v14M3 5a2 2 0 0 1 2-2h5a2 2 0 0 1 2 2v14a2 2 0 0 0-2-2H5a2 2 0 0 1-2-2Z\"\/><path d=\"M21 5a2 2 0 0 0-2-2h-5a2 2 0 0 0-2 2v14a2 2 0 0 1 2-2h5a2 2 0 0 0 2-2Z\"\/><\/svg><\/div>\n        <h3>Reading<\/h3>\n        <p class=\"desc\">Read faster and smarter \u2014 skimming, scanning, inference and academic vocabulary.<\/p>\n        <div class=\"sk-chips\"><span class=\"sk-chip\">IELTS Reading<\/span><span class=\"sk-chip\">Cambridge<\/span><span class=\"sk-chip\">Vocabulary<\/span><\/div>\n        <button class=\"btn btn-grad\">Practise Reading\n          <svg width=\"16\" height=\"16\" 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><\/button>\n      <\/div>\n      <!-- WRITING -->\n      <div class=\"skill-card reveal d3\" style=\"--sc:#818CF8;--sc2:#6366F1\">\n        <span class=\"num\">04<\/span>\n        <div class=\"sk-ico\"><svg width=\"28\" height=\"28\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z\"\/><\/svg><\/div>\n        <h3>Writing<\/h3>\n        <p class=\"desc\">Plan and write Task 1 &amp; Task 2, letters and essays with model structures.<\/p>\n        <div class=\"sk-chips\"><span class=\"sk-chip\">IELTS Writing<\/span><span class=\"sk-chip\">Letters<\/span><span class=\"sk-chip\">Essays<\/span><\/div>\n        <button class=\"btn btn-grad\">Practise Writing\n          <svg width=\"16\" height=\"16\" 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><\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ===== QUIZ ===== -->\n<section class=\"block\" id=\"quiz\" style=\"background:var(--light-1)\">\n  <div class=\"wrap\">\n    <div class=\"sec-head reveal\">\n      <span class=\"kicker\">Interactive<\/span>\n      <h2 class=\"serif\">Quick skills check<\/h2>\n      <p>Four questions, one per skill. Answer each and watch your skill rings fill up.<\/p>\n    <\/div>\n    <div class=\"quiz-wrap reveal\">\n      <div class=\"quiz-side\">\n        <span class=\"kicker\">Your progress<\/span>\n        <h3>How sharp are<br>your four skills?<\/h3>\n        <p>Tap an answer to lock it in. You&#8217;ll get instant feedback and a quick explanation for every question.<\/p>\n        <div class=\"rings\" id=\"rings\"><\/div>\n      <\/div>\n      <div class=\"quiz-main\">\n        <div class=\"q-top\">\n          <span class=\"q-counter\" id=\"qCounter\">Question 1 of 4<\/span>\n          <span class=\"q-score\" id=\"qScore\">Score 0 \/ 4<\/span>\n        <\/div>\n        <div id=\"qBody\">\n          <span class=\"q-tag\"><span class=\"qd\"><\/span><span id=\"qSkill\">Listening<\/span><\/span>\n          <div class=\"q-text\" id=\"qText\"><\/div>\n          <div class=\"opts\" id=\"qOpts\"><\/div>\n          <div class=\"explain\" id=\"qExplain\"><\/div>\n        <\/div>\n        <div class=\"q-actions\" id=\"qActions\">\n          <button class=\"btn btn-light\" id=\"nextBtn\" disabled style=\"opacity:.5\">Next question\n            <svg width=\"16\" height=\"16\" 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><\/button>\n          <button class=\"btn btn-soft\" id=\"resetBtn\">Reset<\/button>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ===== TIPS ===== -->\n<section class=\"block\">\n  <div class=\"wrap\">\n    <div class=\"sec-head reveal\">\n      <span class=\"kicker\">How to improve each skill<\/span>\n      <h2 class=\"serif\">One smart habit per skill<\/h2>\n      <p>Small, consistent actions beat cramming. Start with one tip from each skill this week.<\/p>\n    <\/div>\n    <div class=\"tips-grid\">\n      <div class=\"tip reveal\" style=\"--sc:#8B5CF6;--sc2:#6366F1\">\n        <div class=\"ti\"><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 12a9 9 0 0 1 18 0v6a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3\"\/><\/svg><\/div>\n        <h4>Listening<\/h4>\n        <p>Do one short dictation daily \u2014 listen, write what you hear, then check. Re-listening to your mistakes trains your ear fastest.<\/p>\n      <\/div>\n      <div class=\"tip reveal d1\" style=\"--sc:#A78BFA;--sc2:#7C3AED\">\n        <div class=\"ti\"><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2a3 3 0 0 1 3 3v6a3 3 0 0 1-6 0V5a3 3 0 0 1 3-3Z\"\/><path d=\"M19 10a7 7 0 0 1-14 0\"\/><\/svg><\/div>\n        <h4>Speaking<\/h4>\n        <p>Shadow native audio: play a sentence, pause, and repeat it copying the rhythm and stress. Record yourself once a week to hear progress.<\/p>\n      <\/div>\n      <div class=\"tip reveal d2\" style=\"--sc:#6366F1;--sc2:#4F46E5\">\n        <div class=\"ti\"><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 7v14M3 5a2 2 0 0 1 2-2h5a2 2 0 0 1 2 2v14a2 2 0 0 0-2-2H5a2 2 0 0 1-2-2Z\"\/><\/svg><\/div>\n        <h4>Reading<\/h4>\n        <p>Skim for the main idea first, then scan for detail. Note 5 new words per article and use each in your own sentence to make it stick.<\/p>\n      <\/div>\n      <div class=\"tip reveal d3\" style=\"--sc:#818CF8;--sc2:#6366F1\">\n        <div class=\"ti\"><svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 20h9M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z\"\/><\/svg><\/div>\n        <h4>Writing<\/h4>\n        <p>Plan before you write: spend two minutes outlining your main points. A clear structure scores higher than fancy words with no flow.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ===== YOUTUBE BAND ===== -->\n<section class=\"block yt-band\">\n  <div class=\"wrap yt-grid\">\n    <div class=\"yt-left reveal\">\n      <span class=\"kicker\">Free lessons<\/span>\n      <h2 class=\"serif\">Watch free English skills lessons on YouTube<\/h2>\n      <p>New videos every week \u2014 listening drills, speaking tips, reading strategies and full IELTS writing walkthroughs. Subscribe so you never miss one.<\/p>\n      <a class=\"btn btn-yt\" href=\"https:\/\/www.youtube.com\" target=\"_blank\" rel=\"noopener\">\n        <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M23.5 6.2a3 3 0 0 0-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 0 0 .5 6.2 31 31 0 0 0 0 12a31 31 0 0 0 .5 5.8 3 3 0 0 0 2.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2.1A31 31 0 0 0 24 12a31 31 0 0 0-.5-5.8ZM9.6 15.6V8.4l6.3 3.6Z\"\/><\/svg>\n        Subscribe on YouTube<\/a>\n    <\/div>\n    <div class=\"yt-cards reveal d1\">\n      <div class=\"yt-card\">\n        <div class=\"yt-thumb\"><div class=\"play\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7Z\"\/><\/svg><\/div><\/div>\n        <div class=\"info\"><h5>Top listening tips<\/h5><span>12:04 \u00b7 Listening<\/span><\/div>\n      <\/div>\n      <div class=\"yt-card\">\n        <div class=\"yt-thumb\"><div class=\"play\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7Z\"\/><\/svg><\/div><\/div>\n        <div class=\"info\"><h5>IELTS Writing Task 2 structure<\/h5><span>18:37 \u00b7 Writing<\/span><\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ===== FOOTER ===== -->\n\n\n<!-- ===== TWEAK PANEL ===== -->\n<button class=\"tweak-gear\" id=\"gear\" aria-label=\"Customise\">\n  <svg width=\"22\" height=\"22\" 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.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-1.8-.3 1.6 1.6 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.6 1.6 0 0 0-1-1.5 1.6 1.6 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.6 1.6 0 0 0 .3-1.8 1.6 1.6 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.6 1.6 0 0 0 1.5-1 1.6 1.6 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.6 1.6 0 0 0 1.8.3H9a1.6 1.6 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.6 1.6 0 0 0 1 1.5 1.6 1.6 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.6 1.6 0 0 0-.3 1.8V9a1.6 1.6 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.6 1.6 0 0 0-1.5 1Z\"\/><\/svg>\n<\/button>\n<div class=\"tweak-panel\" id=\"tweakPanel\">\n  <div class=\"tp-head\"><strong>Customise<\/strong>\n    <button class=\"tp-close\" id=\"tpClose\" 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=\"M18 6 6 18M6 6l12 12\"\/><\/svg><\/button>\n  <\/div>\n  <div class=\"tp-row\">\n    <label>Accent hue <span id=\"hueVal\">Purple<\/span><\/label>\n    <div class=\"hue-track\"><\/div>\n    <input type=\"range\" id=\"hue\" min=\"0\" max=\"100\" value=\"0\" \/>\n  <\/div>\n  <div class=\"tp-row\">\n    <label>Animation speed <span id=\"speedVal\">1.0\u00d7<\/span><\/label>\n    <input type=\"range\" id=\"speed\" min=\"0\" max=\"200\" value=\"100\" \/>\n  <\/div>\n  <div class=\"tp-row\">\n    <label>3D intensity <span id=\"intVal\">100%<\/span><\/label>\n    <input type=\"range\" id=\"intensity\" min=\"0\" max=\"100\" value=\"100\" \/>\n  <\/div>\n  <div class=\"tp-row tp-toggle\">\n    <label style=\"margin:0\">Reduce motion<\/label>\n    <div class=\"sw\" id=\"reduceSw\" role=\"switch\" aria-checked=\"false\"><\/div>\n  <\/div>\n<\/div>\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\"><\/script>\n<script>\n\/* ===== HEADER scroll ===== *\/\nconst header=document.getElementById('header');\nconst onScroll=()=>header.classList.toggle('solid',window.scrollY>40);\nonScroll();window.addEventListener('scroll',onScroll,{passive:true});\n\n\/* ===== Scroll reveal ===== *\/\nconst io=new IntersectionObserver((es)=>{es.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target);}})},{threshold:.12});\ndocument.querySelectorAll('.reveal').forEach(el=>io.observe(el));\n\n\/* ===== QUIZ ===== *\/\nconst QUESTIONS=[\n  {skill:'Listening',\n   q:'You hear: \"The meeting has been <em>put off<\/em> until Friday.\" What happened to the meeting?',\n   opts:['It was cancelled completely','It was postponed to a later time','It started earlier than planned','It was made shorter'],\n   answer:1,\n   exp:'<b>\"Put off\"<\/b> is a phrasal verb meaning to postpone or delay something to a later time.'},\n  {skill:'Reading',\n   q:'\"Despite the rain, turnout at the festival exceeded all expectations.\" What can you infer?',\n   opts:['Few people attended the festival','The festival was cancelled','More people came than predicted','It did not rain after all'],\n   answer:2,\n   exp:'<b>\"Exceeded all expectations\"<\/b> means the result was higher than predicted \u2014 so attendance was surprisingly large.'},\n  {skill:'Writing',\n   q:'Which sentence is the clearest and most correct for an essay?',\n   opts:['The reason is because of pollution it happens.','Pollution is one of the main causes of this problem.','This problem, pollution causes it mainly happening.','Because pollution, the problem happens by it.'],\n   answer:1,\n   exp:'Option B is concise and grammatical. \"The reason is because\" is redundant, and the others are awkward or ungrammatical.'},\n  {skill:'Vocabulary',\n   q:'Choose the best word: \"Her argument was so <em>____<\/em> that nobody could disagree.\"',\n   opts:['compelling','reluctant','vacant','tedious'],\n   answer:0,\n   exp:'<b>\"Compelling\"<\/b> means convincing and persuasive \u2014 exactly what makes an argument hard to disagree with.'},\n];\nconst RING_SKILLS=['Listening','Reading','Writing','Vocabulary'];\nlet cur=0,score=0,answered=Array(4).fill(false),correctArr=Array(4).fill(false);\n\n\/* build rings *\/\nconst ringsEl=document.getElementById('rings');\nRING_SKILLS.forEach((s,i)=>{\n  const d=document.createElement('div');d.className='ring';\n  d.innerHTML=`<svg viewBox=\"0 0 52 52\"><circle cx=\"26\" cy=\"26\" r=\"22\" fill=\"none\" stroke=\"rgba(255,255,255,.14)\" stroke-width=\"5\"\/><circle class=\"rt\" id=\"ring${i}\" cx=\"26\" cy=\"26\" r=\"22\" fill=\"none\" stroke=\"url(#rg)\" stroke-width=\"5\" stroke-linecap=\"round\" stroke-dasharray=\"138.2\" stroke-dashoffset=\"138.2\"\/><\/svg><div class=\"rl\">${s}<small id=\"rs${i}\">\u2014<\/small><\/div>`;\n  ringsEl.appendChild(d);\n});\n\/* gradient def *\/\nconst grad=document.createElementNS('http:\/\/www.w3.org\/2000\/svg','svg');\ngrad.setAttribute('width','0');grad.setAttribute('height','0');grad.style.position='absolute';\ngrad.innerHTML='<defs><linearGradient id=\"rg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#A78BFA\"\/><stop offset=\"1\" stop-color=\"#818CF8\"\/><\/linearGradient><\/defs>';\ndocument.body.appendChild(grad);\n\nconst qSkill=document.getElementById('qSkill'),qText=document.getElementById('qText'),\nqOpts=document.getElementById('qOpts'),qExplain=document.getElementById('qExplain'),\nqCounter=document.getElementById('qCounter'),qScore=document.getElementById('qScore'),\nnextBtn=document.getElementById('nextBtn'),qBody=document.getElementById('qBody');\n\nfunction setRing(i,filled){\n  const r=document.getElementById('ring'+i);\n  r.style.strokeDashoffset=filled?'0':'138.2';\n  document.getElementById('rs'+i).textContent=answered[i]?(correctArr[i]?'Correct':'Try again'):'\u2014';\n}\nfunction renderQ(){\n  const Q=QUESTIONS[cur];\n  qSkill.textContent=Q.skill;\n  qText.innerHTML=Q.q;\n  qCounter.textContent=`Question ${cur+1} of 4`;\n  qOpts.innerHTML='';\n  qExplain.className='explain';\n  Q.opts.forEach((o,i)=>{\n    const b=document.createElement('button');b.className='opt';\n    b.innerHTML=`<span class=\"key\">${'ABCD'[i]}<\/span><span>${o}<\/span><span class=\"mark\"><\/span>`;\n    b.onclick=()=>pick(i,b);\n    qOpts.appendChild(b);\n  });\n  if(answered[cur]) replayAnswer();\n  nextBtn.disabled=!answered[cur];\n  nextBtn.style.opacity=answered[cur]?'1':'.5';\n  nextBtn.querySelector('span')?.remove();\n  nextBtn.childNodes[0].nodeValue=cur===3?'See result ':'Next question ';\n}\nfunction lockOpts(chosen){\n  const Q=QUESTIONS[cur];\n  [...qOpts.children].forEach((b,i)=>{\n    b.classList.add('locked');\n    const mark=b.querySelector('.mark');\n    if(i===Q.answer){b.classList.add('correct');mark.innerHTML='<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#16A34A\" stroke-width=\"2.6\" stroke-linecap=\"round\"><path d=\"M20 6 9 17l-5-5\"\/><\/svg>';}\n    else if(i===chosen){b.classList.add('wrong');mark.innerHTML='<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#DC2626\" stroke-width=\"2.6\" stroke-linecap=\"round\"><path d=\"M18 6 6 18M6 6l12 12\"\/><\/svg>';}\n  });\n  qExplain.innerHTML=Q.exp;qExplain.classList.add('show');\n}\nfunction pick(i,b){\n  if(answered[cur])return;\n  const Q=QUESTIONS[cur];\n  answered[cur]=true;\n  correctArr[cur]=(i===Q.answer);\n  if(correctArr[cur])score++;\n  lockOpts(i);\n  setRing(cur,true);\n  qScore.textContent=`Score ${score} \/ 4`;\n  nextBtn.disabled=false;nextBtn.style.opacity='1';\n}\nfunction replayAnswer(){\n  \/* re-show a previously answered question *\/\n  const Q=QUESTIONS[cur];\n  [...qOpts.children].forEach((b,i)=>{\n    b.classList.add('locked');\n    const mark=b.querySelector('.mark');\n    if(i===Q.answer){b.classList.add('correct');mark.innerHTML='<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#16A34A\" stroke-width=\"2.6\" stroke-linecap=\"round\"><path d=\"M20 6 9 17l-5-5\"\/><\/svg>';}\n  });\n  qExplain.innerHTML=Q.exp;qExplain.classList.add('show');\n}\nnextBtn.onclick=()=>{\n  if(!answered[cur])return;\n  if(cur<3){cur++;renderQ();}\n  else showResult();\n};\nfunction showResult(){\n  const pct=Math.round(score\/4*100);\n  let msg='Keep practising \u2014 every skill grows with reps.';\n  if(score===4)msg='Outstanding! All four skills firing. \ud83c\udfaf';\n  else if(score===3)msg='Great work \u2014 just one to polish.';\n  else if(score===2)msg='Solid start. Pick a skill and dig in.';\n  qBody.innerHTML=`<div class=\"quiz-done\"><div class=\"big grad-text\">${score} \/ 4<\/div><div class=\"msg\">${msg}<\/div>\n    <div style=\"font-size:14px;color:var(--muted)\">You scored ${pct}% across Listening, Reading, Writing and Vocabulary.<\/div><\/div>`;\n  qCounter.textContent='Complete';\n  nextBtn.style.display='none';\n}\ndocument.getElementById('resetBtn').onclick=()=>{\n  cur=0;score=0;answered=Array(4).fill(false);correctArr=Array(4).fill(false);\n  qScore.textContent='Score 0 \/ 4';nextBtn.style.display='';\n  RING_SKILLS.forEach((_,i)=>setRing(i,false));\n  renderQ();\n};\nrenderQ();\n\n\/* ===== TWEAK PANEL ===== *\/\nconst root=document.documentElement;\nconst gear=document.getElementById('gear'),panel=document.getElementById('tweakPanel');\ngear.onclick=()=>panel.classList.toggle('open');\ndocument.getElementById('tpClose').onclick=()=>panel.classList.remove('open');\n\nfunction lerp(a,b,t){return a+(b-a)*t;}\nfunction hex(r,g,b){return '#'+[r,g,b].map(v=>Math.round(v).toString(16).padStart(2,'0')).join('');}\n\/* purple #8B5CF6 (139,92,246) -> indigo #6366F1 (99,102,241) *\/\nconst hueEl=document.getElementById('hue');\nhueEl.oninput=()=>{\n  const t=hueEl.value\/100;\n  \/\/ a1 from 8B5CF6 -> 6366F1 ; a2 from 6366F1 -> 4F46E5\n  const a1=hex(lerp(139,99,t),lerp(92,102,t),lerp(246,241,t));\n  const a2=hex(lerp(99,79,t),lerp(102,70,t),lerp(241,229,t));\n  root.style.setProperty('--a1',a1);\n  root.style.setProperty('--a2',a2);\n  const gl=`rgba(${Math.round(lerp(139,99,t))},${Math.round(lerp(92,102,t))},${Math.round(lerp(246,241,t))},.32)`;\n  root.style.setProperty('--accent-glow',gl);\n  document.getElementById('hueVal').textContent=t<.33?'Purple':t<.66?'Violet':'Indigo';\n  if(window.__setGemColor)window.__setGemColor(a1,a2);\n};\nconst speedEl=document.getElementById('speed');\nspeedEl.oninput=()=>{\n  const v=speedEl.value\/100;\n  root.style.setProperty('--speed',v||0.001);\n  document.getElementById('speedVal').textContent=v.toFixed(1)+'\u00d7';\n  window.__animSpeed=v;\n};\nconst intEl=document.getElementById('intensity');\nintEl.oninput=()=>{\n  document.getElementById('intVal').textContent=intEl.value+'%';\n  window.__gemIntensity=intEl.value\/100;\n};\nconst reduceSw=document.getElementById('reduceSw');\nreduceSw.onclick=()=>{\n  const on=reduceSw.classList.toggle('on');\n  reduceSw.setAttribute('aria-checked',on);\n  window.__reduceMotion=on;\n  if(on){window.__stopGem&&window.__stopGem();document.getElementById('gemFallback').classList.add('show');}\n  else{document.getElementById('gemFallback').classList.remove('show');window.__startGem&&window.__startGem();}\n};\n\n\/* ===== 3D HERO GEM ===== *\/\nwindow.__animSpeed=1;window.__gemIntensity=1;window.__reduceMotion=false;\n(function(){\n  const canvas=document.getElementById('gem-canvas');\n  const fallback=document.getElementById('gemFallback');\n  const prefersReduce=window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n  const isMobile=window.matchMedia('(max-width:680px)').matches;\n  if(typeof THREE==='undefined'\/*REDUCEGUARD*\/){fallback.classList.add('show');return;}\n\n  let renderer,scene,camera,crystal,orbs=[],particles,raf,running=false;\n  const mouse={x:0,y:0},target={x:0,y:0};\n  let A1=new THREE.Color('#8B5CF6'),A2=new THREE.Color('#6366F1');\n\n  function makeLabel(text){\n    const c=document.createElement('canvas');c.width=256;c.height=64;\n    const ctx=c.getContext('2d');\n    ctx.font='bold 30px \"Plus Jakarta Sans\", sans-serif';\n    ctx.textAlign='center';ctx.textBaseline='middle';\n    ctx.fillStyle='#fff';ctx.shadowColor='#A78BFA';ctx.shadowBlur=16;\n    ctx.fillText(text,128,34);\n    const tex=new THREE.CanvasTexture(c);tex.anisotropy=2;\n    const mat=new THREE.SpriteMaterial({map:tex,transparent:true,depthWrite:false});\n    const sp=new THREE.Sprite(mat);sp.scale.set(1.9,0.48,1);\n    return sp;\n  }\n\n  function init(){\n    renderer=new THREE.WebGLRenderer({canvas,alpha:true,antialias:true});\n    renderer.setClearColor(0x000000,0);\n    renderer.setPixelRatio(Math.min(window.devicePixelRatio,2));\n    scene=new THREE.Scene();\n    camera=new THREE.PerspectiveCamera(45,1,0.1,100);\n    camera.position.set(0,0,9.6);\n\n    \/* env map for glossy reflections *\/\n    const ec=document.createElement('canvas');ec.width=ec.height=128;\n    const ex=ec.getContext('2d');\n    const g=ex.createLinearGradient(0,0,0,128);\n    g.addColorStop(0,'#1b2a5e');g.addColorStop(.5,'#8B5CF6');g.addColorStop(1,'#0A1628');\n    ex.fillStyle=g;ex.fillRect(0,0,128,128);\n    const envTex=new THREE.CanvasTexture(ec);envTex.mapping=THREE.EquirectangularReflectionMapping;\n    scene.environment=envTex;\n\n    \/* lights *\/\n    scene.add(new THREE.AmbientLight(0xb3a8ff,0.6));\n    const d1=new THREE.DirectionalLight(0xffffff,1.1);d1.position.set(5,6,5);scene.add(d1);\n    const p1=new THREE.PointLight(0x8B5CF6,2.2,30);p1.position.set(-4,2,4);scene.add(p1);\n    const p2=new THREE.PointLight(0x6366F1,2.0,30);p2.position.set(4,-3,3);scene.add(p2);\n\n    \/* central crystal \u2014 glossy purple jelly *\/\n    const geo=new THREE.IcosahedronGeometry(1.5,0);\n    const mat=new THREE.MeshPhysicalMaterial({\n      color:0x8B5CF6,metalness:0.0,roughness:0.05,\n      transmission:0.5,thickness:2.2,ior:1.4,\n      attenuationColor:new THREE.Color(0x7c3aed),attenuationDistance:1.1,\n      clearcoat:1,clearcoatRoughness:0.06,\n      reflectivity:0.8,envMap:envTex,envMapIntensity:1.8,\n      emissive:0x6d28d9,emissiveIntensity:0.34,transparent:true,\n    });\n    crystal=new THREE.Mesh(geo,mat);scene.add(crystal);\n    \/* wire overlay for sparkle facets *\/\n    const wire=new THREE.LineSegments(new THREE.EdgesGeometry(geo),\n      new THREE.LineBasicMaterial({color:0xffffff,transparent:true,opacity:0.35}));\n    crystal.add(wire);\n\n    \/* four orbiting label orbs *\/\n    const labels=['LISTENING','SPEAKING','READING','WRITING'];\n    labels.forEach((lab,i)=>{\n      const grp=new THREE.Group();\n      const ang=i\/4*Math.PI*2;\n      const om=new THREE.MeshPhysicalMaterial({\n        color:i%2?0x6366F1:0x8B5CF6,roughness:0.12,metalness:0.0,\n        transmission:0.3,thickness:1.0,clearcoat:1,emissive:i%2?0x4338ca:0x6d28d9,\n        emissiveIntensity:0.6,envMap:envTex,envMapIntensity:1.6,transparent:true,\n      });\n      const orb=new THREE.Mesh(new THREE.SphereGeometry(0.32,32,32),om);\n      const sprite=makeLabel(lab);sprite.position.set(0,0.6,0);\n      grp.add(orb);grp.add(sprite);\n      grp.userData={ang,radius:2.35,speed:0.18+i*0.01,bob:i*1.3};\n      scene.add(grp);orbs.push(grp);\n    });\n\n    \/* particles *\/\n    const pcount=70;const pg=new THREE.BufferGeometry();\n    const pos=new Float32Array(pcount*3);\n    for(let i=0;i<pcount;i++){\n      pos[i*3]=(Math.random()-0.5)*11;\n      pos[i*3+1]=(Math.random()-0.5)*8;\n      pos[i*3+2]=(Math.random()-0.5)*6-1;\n    }\n    pg.setAttribute('position',new THREE.BufferAttribute(pos,3));\n    particles=new THREE.Points(pg,new THREE.PointsMaterial({\n      color:0xc4b5fd,size:0.06,transparent:true,opacity:0.7,\n      blending:THREE.AdditiveBlending,depthWrite:false,\n    }));\n    scene.add(particles);\n\n    resize();window.addEventListener('resize',resize);\n    \/* robust sizing: retry next frames + observe container *\/\n    requestAnimationFrame(resize);setTimeout(resize,120);setTimeout(resize,400);\n    if(window.ResizeObserver){const ro=new ResizeObserver(()=>resize());ro.observe(canvas.parentElement);}\n    canvas.parentElement.addEventListener('pointermove',e=>{\n      const r=canvas.getBoundingClientRect();\n      target.x=((e.clientX-r.left)\/r.width-0.5)*2;\n      target.y=((e.clientY-r.top)\/r.height-0.5)*2;\n    });\n  }\n\n  function resize(){\n    if(!renderer)return;\n    const p=canvas.parentElement;\n    const r=canvas.getBoundingClientRect();\n    let w=r.width||p.clientWidth||canvas.clientWidth;\n    let h=r.height||p.clientHeight||canvas.clientHeight;\n    if(!w||!h)return;\n    renderer.setSize(w,h,false);\n    camera.aspect=w\/h;camera.updateProjectionMatrix();\n  }\n\n  let t=0;\n  function loop(){\n    raf=requestAnimationFrame(loop);\n    const sp=window.__animSpeed||1;const intensity=window.__gemIntensity!=null?window.__gemIntensity:1;\n    t+=0.016*sp;\n    mouse.x+=(target.x-mouse.x)*0.05;\n    mouse.y+=(target.y-mouse.y)*0.05;\n    if(crystal){\n      crystal.rotation.y+=0.004*sp;\n      crystal.rotation.x=Math.sin(t*0.4)*0.2+mouse.y*0.3*intensity;\n      crystal.rotation.z=mouse.x*0.15*intensity;\n      crystal.position.y=Math.sin(t*0.8)*0.18*intensity;\n      crystal.scale.setScalar(0.55+intensity*0.42);\n    }\n    orbs.forEach((g)=>{\n      const u=g.userData;const a=u.ang+t*u.speed;\n      const rad=u.radius*(0.6+intensity*0.4);\n      g.position.x=Math.cos(a)*rad;\n      g.position.z=Math.sin(a)*rad*0.6;\n      g.position.y=Math.sin(t*0.9+u.bob)*0.4+mouse.y*0.2;\n      g.lookAt(camera.position);\n    });\n    if(particles){particles.rotation.y+=0.0006*sp;particles.position.y=Math.sin(t*0.3)*0.2;}\n    renderer.render(scene,camera);\n  }\n  function start(){if(running)return;if(!renderer)init();running=true;loop();}\n  function stop(){running=false;cancelAnimationFrame(raf);}\n  function dispose(){\n    stop();\n    if(!renderer)return;\n    scene&&scene.traverse(o=>{\n      if(o.geometry)o.geometry.dispose();\n      if(o.material){(Array.isArray(o.material)?o.material:[o.material]).forEach(m=>{\n        for(const k in m){const v=m[k];if(v&&v.isTexture)v.dispose();}\n        m.dispose();\n      });}\n    });\n    renderer.dispose();renderer=null;scene=null;\n  }\n  window.addEventListener('pagehide',dispose);\n\n  window.__startGem=start;window.__stopGem=stop;\n  window.__setGemColor=(a1,a2)=>{\n    if(!crystal)return;\n    crystal.material.color.set(a1);\n    orbs.forEach((g,i)=>{g.children[0].material.color.set(i%2?a2:a1);});\n  };\n\n  \/* lazy init + pause when scrolled away *\/\n  const heroVis=canvas.parentElement;\n  let started=false;\n  function kick(){\n    if(window.__reduceMotion){fallback.classList.add('show');return;}\n    started=true;start();requestAnimationFrame(resize);\n  }\n  const vio=new IntersectionObserver((es)=>{\n    es.forEach(e=>{\n      if(e.isIntersecting){if(!started)kick();else if(!window.__reduceMotion)start();}\n      else stop();\n    });\n  },{threshold:0.01});\n  vio.observe(heroVis);\n  \/* explicit fallback kick after layout settles, in case observer is slow *\/\n  if(document.readyState==='complete')requestAnimationFrame(kick);\n  else window.addEventListener('load',()=>requestAnimationFrame(kick));\n  setTimeout(()=>{if(!started)kick();},600);\n})();\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>All English 4U Grammar IELTS TOEFL Cambridge CELPIP Dictation Contact Start Free GrammarIELTSTOEFLCambridge CELPIP DictationContact FOUR CORE SKILLS Master Every English Skill Listening, Speaking, Reading and Writing \u2014 build all four with focused, interactive practice. Pick a skill and start improving today. 4 Core Skills Interactive Practice All Levels (A1\u2013C1) 100% Free Explore the skills [&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-835","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/835","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=835"}],"version-history":[{"count":12,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/835\/revisions"}],"predecessor-version":[{"id":5971,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/835\/revisions\/5971"}],"wp:attachment":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/media?parent=835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}