{"id":977,"date":"2026-05-24T22:29:53","date_gmt":"2026-05-24T22:29:53","guid":{"rendered":"https:\/\/allenglish4u.com\/cambridge\/"},"modified":"2026-07-06T01:46:18","modified_gmt":"2026-07-06T01:46:18","slug":"cambridge","status":"publish","type":"page","link":"https:\/\/allenglish4u.com\/vi\/cambridge\/","title":{"rendered":"Cambridge English Tests"},"content":{"rendered":"\ufeff\n<!-- Cambridge Hub redesign \u2014 deployed 2026-06-03 -->\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\" \/>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin \/>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:ital,wght@0,400;0,500;0,600;0,700;0,800;1,500;1,600;1,700&#038;display=swap\" rel=\"stylesheet\" \/>\n<style id=\"cambridge-hub-styles\">\n\/* Force show theme site-header + site-footer (match homepage). Override page-977 hide rule from CCSS\/cache. *\/\nhtml body.page-id-977 header.wp-block-template-part,\nhtml body.page-id-977 footer.wp-block-template-part,\nhtml body.page-id-977 .site-header,\nhtml body.page-id-977 .site-footer { display: block !important; }\nhtml body.page-id-977 { padding-top: revert !important; margin-top: revert !important; }\nhtml body.page-id-977 .ae4u-fv2 { display: none !important; }\n\n\/* Cambridge Hub redesign \u2014 namespaced under .cambridge-hub *\/\n\/* Auto-generated by namespace_css.py \u2014 DO NOT EDIT MANUALLY *\/\n\n\/* ============================================================\n   All English 4U \u2014 Cambridge hub\n   Design tokens\n   ============================================================ *\/\n:root {\n  \/* paper + ink *\/\n  --paper:      #FAF6EE;\n  --paper-2:    #F3ECDF;\n  --card:       #FFFFFF;\n  --ink:        #14213D;\n  --ink-2:      #3A4868;\n  --ink-soft:   #6B7796;\n  --line:       #E7DECE;\n  --line-2:     #DED3BF;\n\n  \/* brand *\/\n  --navy:       #14213D;\n  --navy-deep:  #0C1730;\n  --blue:       #0161FF;   \/* logo brand blue *\/\n  --blue-deep:  #0A4ED0;\n  --blue-soft:  #E2ECFF;\n  --red:        #0161FF;   \/* accent now blue *\/\n  --red-deep:   #0A4ED0;\n\n  \/* CEFR level spectrum *\/\n  --starters:   #18A777;   \/* Pre-A1 mint  *\/\n  --movers:     #0CA7B8;   \/* A1 teal      *\/\n  --flyers:     #7A5BE3;   \/* A2 violet    *\/\n  --ket:        #E68A1E;   \/* A2 Key amber *\/\n  --pet:        #0161FF;   \/* B1 brand blue*\/\n\n  --starters-soft: #E3F4ED;\n  --movers-soft:   #D9F3F6;\n  --flyers-soft:   #ECE6FB;\n  --ket-soft:      #FBEFDC;\n  --pet-soft:      #E2ECFF;\n\n  \/* status *\/\n  --live:       #18A777;\n  --progress:   #E68A1E;\n  --soon:       #98A0B4;\n\n  \/* type *\/\n  --display: \"Plus Jakarta Sans\", system-ui, sans-serif;\n  --body:    \"Plus Jakarta Sans\", system-ui, -apple-system, sans-serif;\n\n  \/* shape *\/\n  --r-sm: 10px;\n  --r:    16px;\n  --r-lg: 24px;\n  --r-xl: 32px;\n\n  --shadow-sm: 0 1px 2px rgba(20,33,61,.06), 0 2px 6px rgba(20,33,61,.05);\n  --shadow:    0 4px 14px rgba(20,33,61,.08), 0 12px 32px rgba(20,33,61,.07);\n  --shadow-lg: 0 12px 28px rgba(20,33,61,.12), 0 28px 64px rgba(20,33,61,.12);\n\n  --maxw: 1200px;\n}\n\n.cambridge-hub * { box-sizing: border-box; }\n.cambridge-hub { scroll-behavior: smooth; }\n.cambridge-hub {\n  margin: 0;\n  font-family: var(--body);\n  background: var(--paper);\n  color: var(--ink);\n  font-size: 17px;\n  line-height: 1.55;\n  -webkit-font-smoothing: antialiased;\n  text-rendering: optimizeLegibility;\n  overflow-x: hidden;\n}\n.cambridge-hub img { max-width: 100%; display: block; }\n.cambridge-hub a { color: inherit; text-decoration: none; }\n.cambridge-hub button { font-family: inherit; cursor: pointer; }\n.cambridge-hub h1, .cambridge-hub h2, .cambridge-hub h3, .cambridge-hub h4 { font-family: var(--display); font-weight: 700; line-height: 1.04; margin: 0; letter-spacing: -0.02em; }\n\n.cambridge-hub .wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 28px; }\n\n\/* paper texture *\/\n.cambridge-hub::before {\n  content: \"\";\n  position: fixed; inset: 0; z-index: -2;\n  background:\n    radial-gradient(1100px 600px at 82% -8%, rgba(1,97,255,.08), transparent 60%),\n    radial-gradient(900px 520px at -6% 4%, rgba(1,97,255,.05), transparent 58%);\n  pointer-events: none;\n}\n.cambridge-hub::after {\n  content: \"\";\n  position: fixed; inset: 0; z-index: -1; opacity: .5;\n  background-image: radial-gradient(rgba(20,33,61,.045) 1px, transparent 1px);\n  background-size: 22px 22px;\n  pointer-events: none;\n}\n\n\/* ============================================================\n   Header\n   ============================================================ *\/\n.cambridge-hub .site-header {\n  position: sticky; top: 0; z-index: 60;\n  background: color-mix(in srgb, var(--paper) 82%, transparent);\n  backdrop-filter: saturate(140%) blur(14px);\n  border-bottom: 1px solid transparent;\n  transition: border-color .25s, box-shadow .25s, background .25s;\n}\n.cambridge-hub .site-header.scrolled {\n  border-bottom-color: var(--line);\n  box-shadow: 0 6px 20px rgba(20,33,61,.05);\n}\n.cambridge-hub .header-inner {\n  display: flex; align-items: center; gap: 28px;\n  height: 70px;\n}\n.cambridge-hub .brand { display: flex; align-items: center; gap: 11px; white-space: nowrap; font-family: var(--display); font-weight: 800; font-size: 19px; letter-spacing: -.02em; }\n.cambridge-hub .brand .mark {\n  width: 42px; height: 42px; border-radius: 50%; flex: 0 0 auto;\n  object-fit: cover; box-shadow: var(--shadow-sm);\n  background: var(--blue);\n}\n.cambridge-hub .brand .mark-fallback {\n  color: #fff; display: grid; place-items: center;\n  font-size: 15px; font-weight: 800; letter-spacing: -.04em;\n  box-shadow: var(--shadow-sm);\n  position: relative; overflow: hidden;\n}\n.cambridge-hub .brand .mark::after {\n  content: \"\"; position: absolute; inset: 0;\n  background: linear-gradient(135deg, transparent 55%, rgba(255,255,255,.22));\n}\n.cambridge-hub .brand b { color: var(--red); }\n.cambridge-hub .main-nav { display: flex; gap: 4px; margin-left: auto; }\n.cambridge-hub .main-nav a {\n  padding: 8px 13px; border-radius: 999px; font-weight: 600; font-size: 15px;\n  color: var(--ink-2); transition: background .18s, color .18s;\n}\n.cambridge-hub .main-nav a:hover { background: var(--paper-2); color: var(--ink); }\n.cambridge-hub .main-nav a.active { color: var(--navy); background: #fff; box-shadow: var(--shadow-sm); }\n.cambridge-hub .btn-cta {\n  display: inline-flex; align-items: center; gap: 8px;\n  background: var(--red); color: #fff; font-weight: 700; font-size: 15px;\n  padding: 10px 18px; border-radius: 999px; border: 0;\n  box-shadow: 0 6px 16px rgba(1,97,255,.32);\n  transition: transform .16s, box-shadow .16s, background .16s;\n}\n.cambridge-hub .btn-cta:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(1,97,255,.42); background: var(--red-deep); }\n.cambridge-hub .btn-cta svg { width: 16px; height: 16px; }\n.cambridge-hub .nav-toggle { display: none; }\n\n\/* ============================================================\n   Hero\n   ============================================================ *\/\n.cambridge-hub .hero { position: relative; padding: 74px 0 40px; }\n.cambridge-hub .hero-grid {\n  display: grid; grid-template-columns: 1.05fr .95fr; gap: 56px; align-items: center;\n}\n.cambridge-hub .eyebrow {\n  display: inline-flex; align-items: center; gap: 9px; white-space: nowrap;\n  font-size: 13.5px; font-weight: 700; letter-spacing: .02em;\n  color: var(--ink-2); background: #fff; border: 1px solid var(--line);\n  padding: 7px 14px 7px 11px; border-radius: 999px; box-shadow: var(--shadow-sm);\n}\n.cambridge-hub .eyebrow .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--red); box-shadow: 0 0 0 4px rgba(1,97,255,.16); }\n.cambridge-hub .hero h1 {\n  font-size: clamp(40px, 6vw, 74px); margin: 22px 0 0; letter-spacing: -.03em;\n}\n.cambridge-hub .hero h1 em { font-style: normal; color: var(--red); position: relative; white-space: nowrap; }\n.cambridge-hub .hero h1 em::after {\n  content: \"\"; position: absolute; left: 2%; right: 2%; bottom: .06em; height: .14em;\n  background: var(--ket); border-radius: 999px; opacity: .55; z-index: -1;\n  transform: scaleX(0); transform-origin: left; animation: underline 1s .5s cubic-bezier(.2,.8,.2,1) forwards;\n}\n@keyframes underline { to { transform: scaleX(1); } }\n.cambridge-hub .hero .lead { font-size: 19px; color: var(--ink-2); margin: 22px 0 0; max-width: 33ch; }\n.cambridge-hub .hero .lead b { color: var(--ink); font-weight: 700; }\n.cambridge-hub .hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; }\n.cambridge-hub .btn-lg {\n  display: inline-flex; align-items: center; gap: 10px; font-weight: 700; font-size: 16.5px;\n  padding: 14px 24px; border-radius: 14px; border: 0; transition: transform .16s, box-shadow .16s, background .16s;\n}\n.cambridge-hub .btn-primary { background: var(--blue); color: #fff; box-shadow: 0 8px 22px rgba(1,97,255,.34); }\n.cambridge-hub .btn-primary:hover { transform: translateY(-3px); box-shadow: 0 14px 30px rgba(1,97,255,.42); background: var(--blue-deep); }\n.cambridge-hub .btn-ghost { background: #fff; color: var(--navy); border: 1px solid var(--line-2); box-shadow: var(--shadow-sm); }\n.cambridge-hub .btn-ghost:hover { transform: translateY(-3px); box-shadow: var(--shadow); }\n.cambridge-hub .btn-lg svg { width: 19px; height: 19px; }\n\n\/* stat chips *\/\n.cambridge-hub .stats { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }\n.cambridge-hub .stat {\n  background: #fff; border: 1px solid var(--line); border-radius: var(--r);\n  padding: 13px 18px; box-shadow: var(--shadow-sm); min-width: 116px;\n}\n.cambridge-hub .stat .n { font-family: var(--display); font-weight: 800; font-size: 26px; letter-spacing: -.03em; line-height: 1; }\n.cambridge-hub .stat .l { font-size: 13px; color: var(--ink-soft); font-weight: 600; margin-top: 5px; }\n.cambridge-hub .stat:nth-child(1) .n { color: var(--movers); }\n.cambridge-hub .stat:nth-child(2) .n { color: var(--flyers); }\n.cambridge-hub .stat:nth-child(3) .n { color: var(--ket); }\n.cambridge-hub .stat:nth-child(4) .n { color: var(--live); }\n\n\/* hero visual: book stack card *\/\n.cambridge-hub .hero-visual { position: relative; }\n.cambridge-hub .bookcard {\n  background: linear-gradient(165deg, var(--navy), var(--navy-deep));\n  border-radius: var(--r-xl); padding: 30px; color: #fff; position: relative; overflow: hidden;\n  box-shadow: var(--shadow-lg);\n}\n.cambridge-hub .bookcard::before {\n  content: \"\"; position: absolute; inset: 0; opacity: .5;\n  background:\n    radial-gradient(420px 220px at 110% -10%, rgba(46,124,214,.55), transparent 60%),\n    radial-gradient(360px 220px at -10% 120%, rgba(1,97,255,.4), transparent 60%);\n}\n.cambridge-hub .bookcard-head { position: relative; display: flex; align-items: center; justify-content: space-between; }\n.cambridge-hub .bookcard-head .badge-live {\n  display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 700; white-space: nowrap;\n  background: rgba(24,167,119,.18); color: #7CF0C0; border: 1px solid rgba(24,167,119,.45);\n  padding: 5px 11px; border-radius: 999px;\n}\n.cambridge-hub .bookcard-head .pulse { width: 8px; height: 8px; border-radius: 50%; background: #36E29C; box-shadow: 0 0 0 0 rgba(54,226,156,.7); animation: pulse 1.8s infinite; }\n@keyframes pulse { 0%{box-shadow:0 0 0 0 rgba(54,226,156,.6)} 70%{box-shadow:0 0 0 9px rgba(54,226,156,0)} 100%{box-shadow:0 0 0 0 rgba(54,226,156,0)} }\n.cambridge-hub .bookcard h3 { position: relative; font-size: 25px; margin: 18px 0 6px; letter-spacing: -.02em; }\n.cambridge-hub .bookcard .sub { position: relative; color: rgba(255,255,255,.7); font-size: 14.5px; }\n.cambridge-hub .testgrid { position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin-top: 20px; }\n.cambridge-hub .testgrid a {\n  display: flex; align-items: center; justify-content: space-between; gap: 8px; white-space: nowrap;\n  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.12);\n  border-radius: 12px; padding: 11px 13px; font-size: 13.5px; font-weight: 600;\n  transition: background .16s, transform .16s, border-color .16s;\n}\n.cambridge-hub .testgrid a:hover { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.3); transform: translateY(-2px); }\n.cambridge-hub .testgrid a span.kind { font-size: 11px; color: rgba(255,255,255,.55); font-weight: 700; letter-spacing: .04em; }\n.cambridge-hub .testgrid a .arr { opacity: .6; }\n.cambridge-hub .bookcard-foot {\n  position: relative; margin-top: 18px; display: flex; align-items: center; gap: 8px;\n  font-size: 13px; color: rgba(255,255,255,.62);\n}\n.cambridge-hub .float-pill {\n  position: absolute; z-index: 3; white-space: nowrap;\n  font-family: var(--display); font-weight: 800; font-size: 13px;\n  padding: 8px 14px; border-radius: 999px; color: #fff; box-shadow: var(--shadow);\n  border: 2px solid rgba(255,255,255,.8);\n}\n.cambridge-hub .float-pill.p1 { top: -16px; left: -18px; background: var(--starters); transform: rotate(-7deg); }\n.cambridge-hub .float-pill.p2 { bottom: 26px; right: -22px; background: var(--ket); transform: rotate(6deg); }\n\n\/* ============================================================\n   Section primitives\n   ============================================================ *\/\n.cambridge-hub .section { padding: 64px 0; position: relative; scroll-margin-top: 130px; }\n.cambridge-hub .section-head { max-width: 760px; margin-bottom: 36px; }\n.cambridge-hub .kicker {\n  display: inline-flex; align-items: center; gap: 9px; font-weight: 700; font-size: 13.5px;\n  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft);\n}\n.cambridge-hub .kicker .tick { width: 26px; height: 3px; border-radius: 3px; background: currentColor; }\n.cambridge-hub .section h2 { font-size: clamp(30px, 4.2vw, 46px); margin: 14px 0 0; }\n.cambridge-hub .section h2 em { font-style: normal; }\n.cambridge-hub .section .desc { color: var(--ink-2); font-size: 17.5px; margin: 16px 0 0; max-width: 70ch; }\n\n\/* legend *\/\n.cambridge-hub .legend { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 22px; font-size: 13.5px; color: var(--ink-2); font-weight: 600; }\n.cambridge-hub .legend span { display: inline-flex; align-items: center; gap: 8px; }\n.cambridge-hub .legend i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }\n.cambridge-hub .legend .l-live { background: var(--live); }\n.cambridge-hub .legend .l-prog { background: var(--progress); }\n.cambridge-hub .legend .l-soon { background: var(--soon); }\n\n\/* ============================================================\n   Staircase (learning path)\n   ============================================================ *\/\n.cambridge-hub .path { background: var(--paper-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }\n.cambridge-hub .stairs {\n  display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; align-items: end;\n  margin-top: 40px;\n}\n.cambridge-hub .step {\n  position: relative; background: var(--card); border: 1px solid var(--line);\n  border-radius: var(--r-lg); padding: 20px 18px 22px; box-shadow: var(--shadow-sm);\n  cursor: pointer; transition: transform .2s cubic-bezier(.2,.8,.2,1), box-shadow .2s, border-color .2s;\n  border-top: 4px solid var(--lc, var(--movers));\n}\n.cambridge-hub .step:nth-child(1) { margin-bottom: 0; }\n.cambridge-hub .step:nth-child(2) { margin-bottom: 26px; }\n.cambridge-hub .step:nth-child(3) { margin-bottom: 52px; }\n.cambridge-hub .step:nth-child(4) { margin-bottom: 78px; }\n.cambridge-hub .step:nth-child(5) { margin-bottom: 104px; }\n.cambridge-hub .step:hover { transform: translateY(-6px); box-shadow: var(--shadow); border-color: var(--lc); }\n.cambridge-hub .step .lvl {\n  display: inline-flex; align-items: center; white-space: nowrap; font-family: var(--display); font-weight: 800;\n  font-size: 13px; letter-spacing: -.01em; color: #fff; background: var(--lc);\n  padding: 4px 11px; border-radius: 999px;\n}\n.cambridge-hub .step h4 { font-size: 19px; margin: 14px 0 2px; }\n.cambridge-hub .step .who { font-size: 13.5px; color: var(--ink-soft); }\n.cambridge-hub .step .st {\n  display: inline-flex; align-items: center; gap: 7px; margin-top: 14px; white-space: nowrap;\n  font-size: 12.5px; font-weight: 700;\n}\n.cambridge-hub .step .st .d { width: 8px; height: 8px; border-radius: 50%; }\n.cambridge-hub .st.live { color: var(--live);   } .cambridge-hub .st.live .d { background: var(--live); box-shadow: 0 0 0 0 rgba(24,167,119,.6); animation: pulse 1.8s infinite; }\n.cambridge-hub .st.prog { color: var(--progress);} .cambridge-hub .st.prog .d { background: var(--progress); }\n.cambridge-hub .st.soon { color: var(--soon);   } .cambridge-hub .st.soon .d { background: var(--soon); }\n.cambridge-hub .step .num {\n  position: absolute; top: 16px; right: 18px; font-family: var(--display); font-weight: 800;\n  font-size: 30px; color: var(--paper-2); -webkit-text-stroke: 1.4px var(--line-2);\n}\n.cambridge-hub .stairs-base { height: 0; }\n.cambridge-hub .path-note { margin-top: 30px; font-size: 14px; color: var(--ink-soft); display: flex; align-items: center; gap: 9px; }\n\n\/* ============================================================\n   Filter tabs\n   ============================================================ *\/\n.cambridge-hub .filterbar {\n  position: sticky; top: 70px; z-index: 50; padding: 14px 0;\n  background: color-mix(in srgb, var(--paper) 86%, transparent);\n  backdrop-filter: saturate(140%) blur(12px);\n  border-bottom: 1px solid var(--line);\n}\n.cambridge-hub .filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }\n.cambridge-hub .filters .fb {\n  border: 1px solid var(--line-2); background: #fff; color: var(--ink-2);\n  font-weight: 700; font-size: 14.5px; padding: 9px 17px; border-radius: 999px;\n  transition: all .16s; box-shadow: var(--shadow-sm); display: inline-flex; align-items: center; gap: 8px;\n}\n.cambridge-hub .filters .fb .c { width: 9px; height: 9px; border-radius: 50%; }\n.cambridge-hub .filters .fb:hover { transform: translateY(-2px); }\n.cambridge-hub .filters .fb.active { color: #fff; border-color: transparent; }\n.cambridge-hub .filters .fb[data-f=\"all\"].active { background: var(--navy); }\n.cambridge-hub .filters .fb[data-f=\"yle\"].active { background: var(--flyers); }\n.cambridge-hub .filters .fb[data-f=\"ket\"].active { background: var(--ket); }\n.cambridge-hub .filters .fb[data-f=\"pet\"].active { background: var(--pet); }\n.cambridge-hub .filters .count { margin-left: auto; font-size: 13.5px; color: var(--ink-soft); font-weight: 600; }\n\n\/* ============================================================\n   Catalog cards\n   ============================================================ *\/\n.cambridge-hub .cat-section { padding: 60px 0; scroll-margin-top: 150px; }\n.cambridge-hub .cat-section.hide { display: none; }\n\n.cambridge-hub .band {\n  display: inline-flex; align-items: center; gap: 10px; padding: 6px 14px 6px 8px;\n  border-radius: 999px; font-weight: 700; font-size: 13px; letter-spacing: .03em; text-transform: uppercase;\n}\n.cambridge-hub .band .bb { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; color:#fff; font-family: var(--display); font-size: 12px; }\n\n\/* YLE: three big level cards *\/\n.cambridge-hub .yle-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; margin-top: 30px; }\n.cambridge-hub .level-card {\n  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);\n  padding: 26px; box-shadow: var(--shadow-sm); position: relative; overflow: hidden;\n  transition: transform .2s, box-shadow .2s;\n  border-top: 5px solid var(--lc);\n}\n.cambridge-hub .level-card:hover { transform: translateY(-5px); box-shadow: var(--shadow); }\n.cambridge-hub .level-card .lc-top { display: flex; align-items: center; justify-content: space-between; }\n.cambridge-hub .level-card .lvl-badge {\n  font-family: var(--display); font-weight: 800; font-size: 13px; color: #fff; white-space: nowrap;\n  background: var(--lc); padding: 5px 12px; border-radius: 999px;\n}\n.cambridge-hub .level-card h3 { font-size: 26px; margin: 16px 0 4px; }\n.cambridge-hub .level-card .meta { font-size: 14px; color: var(--ink-soft); }\n.cambridge-hub .level-card .count {\n  display: flex; align-items: baseline; gap: 7px; margin: 18px 0 6px;\n  font-family: var(--display);\n}\n.cambridge-hub .level-card .count b { font-size: 30px; color: var(--lc); letter-spacing: -.03em; }\n.cambridge-hub .level-card .count span { font-size: 14px; color: var(--ink-2); font-weight: 600; }\n.cambridge-hub .chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }\n.cambridge-hub .chip {\n  width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center;\n  font-family: var(--display); font-weight: 800; font-size: 15px;\n  background: var(--lc-soft); color: var(--lc); border: 1px solid color-mix(in srgb, var(--lc) 22%, transparent);\n  transition: transform .14s, background .14s, color .14s;\n}\n.cambridge-hub .chip:hover { transform: translateY(-3px) scale(1.04); background: var(--lc); color: #fff; }\n.cambridge-hub .status-tag {\n  display: inline-flex; align-items: center; gap: 7px; margin-top: 20px; white-space: nowrap;\n  font-size: 12.5px; font-weight: 700; padding: 6px 12px; border-radius: 999px;\n}\n.cambridge-hub .status-tag .d { width: 8px; height: 8px; border-radius: 50%; }\n.cambridge-hub .status-tag.live { background: var(--starters-soft); color: var(--live); } .cambridge-hub .status-tag.live .d { background: var(--live); }\n.cambridge-hub .status-tag.prog { background: var(--ket-soft); color: var(--progress); }    .cambridge-hub .status-tag.prog .d { background: var(--progress); }\n.cambridge-hub .status-tag.soon { background: var(--paper-2); color: var(--ink-soft); }      .cambridge-hub .status-tag.soon .d { background: var(--soon); }\n\n\/* ============================================================\n   Series cards (KET \/ PET full-width boxes, in order)\n   ============================================================ *\/\n.cambridge-hub .series-list { display: grid; gap: 18px; margin-top: 28px; }\n.cambridge-hub .series-card {\n  display: grid; grid-template-columns: 1fr 1.05fr; gap: 38px;\n  background: var(--card); border: 1px solid var(--line); border-top: 5px solid var(--lc);\n  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);\n  padding: 30px 32px;\n  transition: transform .2s, box-shadow .2s;\n}\n.cambridge-hub .series-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }\n.cambridge-hub .series-card.is-live { border-color: color-mix(in srgb, var(--live) 32%, var(--line)); }\n.cambridge-hub .sc-info { min-width: 0; }\n.cambridge-hub .sc-info .status-tag { margin-top: 0; }\n.cambridge-hub .sc-info h3 { font-size: 25px; margin: 13px 0 7px; letter-spacing: -.02em; }\n.cambridge-hub .sc-info p { color: var(--ink-2); font-size: 14.5px; max-width: 46ch; }\n.cambridge-hub .sc-stats { display: flex; gap: 26px; margin: 18px 0 20px; flex-wrap: wrap; }\n.cambridge-hub .sc-stats .ks b { font-family: var(--display); font-weight: 800; font-size: 23px; white-space: nowrap; color: var(--lc); display: block; line-height: 1.1; letter-spacing: -.02em; }\n.cambridge-hub .sc-stats .ks span { font-size: 12px; color: var(--ink-soft); font-weight: 600; margin-top: 5px; display: block; }\n.cambridge-hub .sc-start { padding: 12px 20px; font-size: 15px; }\n.cambridge-hub .sc-right { display: grid; align-content: center; min-width: 0; }\n\n.cambridge-hub .sc-tests { display: grid; gap: 9px; }\n.cambridge-hub .test-row {\n  display: grid; grid-template-columns: 26px 1fr 1fr; gap: 10px; align-items: center;\n}\n.cambridge-hub .test-row .tn {\n  font-family: var(--display); font-weight: 800; font-size: 14px; color: var(--ink-soft); opacity: .5; text-align: center;\n}\n.cambridge-hub .test-link {\n  display: flex; align-items: center; gap: 9px; white-space: nowrap;\n  background: var(--paper-2); border: 1px solid var(--line-2);\n  border-radius: 11px; padding: 10px 13px; font-size: 13.5px; font-weight: 700; color: var(--ink);\n  transition: background .16s, transform .16s, border-color .16s, color .16s;\n}\n.cambridge-hub .test-link .tl-ico { width: 18px; height: 18px; flex: 0 0 auto; color: var(--lc); }\n.cambridge-hub .test-link .tl-label { flex: 1; overflow: hidden; text-overflow: ellipsis; }\n.cambridge-hub .test-link .arr { width: 16px; height: 16px; flex: 0 0 auto; opacity: .45; }\n.cambridge-hub .test-link:hover { background: var(--blue); border-color: var(--blue); color: #fff; transform: translateX(3px); }\n.cambridge-hub .test-link:hover .tl-ico, .cambridge-hub .test-link:hover .arr { color: #fff; opacity: 1; }\n\/* locked (coming soon) papers *\/\n.cambridge-hub .test-link.locked {\n  background: transparent; border-style: dashed; border-color: var(--line-2);\n  color: var(--ink-soft); cursor: default;\n}\n.cambridge-hub .test-link.locked .tl-ico { color: var(--soon); opacity: .7; }\n.cambridge-hub .test-link.locked .lock { width: 14px; height: 14px; flex: 0 0 auto; opacity: .5; }\n.cambridge-hub .test-link.locked:hover { background: transparent; border-color: var(--line-2); color: var(--ink-soft); transform: none; }\n.cambridge-hub .test-link.locked:hover .tl-ico { color: var(--soon); }\n\n\/* resource books: chips instead of test rows *\/\n.cambridge-hub .sc-items { display: flex; flex-wrap: wrap; gap: 9px; align-content: center; }\n.cambridge-hub .sc-item {\n  display: inline-flex; align-items: center; white-space: nowrap;\n  background: var(--lc-soft); color: var(--lc);\n  border: 1px solid color-mix(in srgb, var(--lc) 22%, transparent);\n  border-radius: 999px; padding: 9px 15px; font-size: 13px; font-weight: 700;\n}\n\n\/* generic level badge (used in YLE boxes) *\/\n.cambridge-hub .lvl-badge {\n  font-family: var(--display); font-weight: 800; font-size: 12px; color: #fff; white-space: nowrap;\n  background: var(--lc); padding: 4px 11px; border-radius: 999px; align-self: flex-start;\n}\n\n\/* YLE boxes (Starters \/ Movers \/ Flyers) *\/\n.cambridge-hub .yle-card .sc-info { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; }\n.cambridge-hub .yle-title { display: flex; align-items: center; gap: 15px; margin-top: 13px; }\n.cambridge-hub .yle-mascot {\n  width: 52px; height: 52px; border-radius: 16px; flex: 0 0 auto; display: grid; place-items: center;\n  background: var(--lc-soft); color: var(--lc); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--lc) 16%, transparent);\n}\n.cambridge-hub .yle-mascot svg { width: 30px; height: 30px; }\n.cambridge-hub .yle-head { display: flex; flex-direction: column; gap: 5px; align-items: flex-start; }\n.cambridge-hub .yle-head h3 { font-size: 25px; margin: 0; letter-spacing: -.02em; }\n.cambridge-hub .yle-card .sc-info p { margin-top: 14px; }\n.cambridge-hub .yle-papers { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }\n.cambridge-hub .yle-papers span {\n  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;\n  font-size: 12.5px; font-weight: 700; color: var(--ink-2);\n  background: var(--paper-2); border: 1px solid var(--line); border-radius: 999px; padding: 6px 12px;\n}\n.cambridge-hub .yle-papers svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--lc); }\n.cambridge-hub .yle-books-label { font-size: 12.5px; font-weight: 700; color: var(--ink-soft); margin-bottom: 12px; letter-spacing: .01em; }\n.cambridge-hub .yle-books { display: flex; flex-wrap: wrap; gap: 10px; align-content: center; }\n.cambridge-hub .yle-card .chip { width: 46px; height: 46px; border-radius: 13px; font-size: 16px; }\n\n\/* generic book grid (coming soon) *\/\n.cambridge-hub .book-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 16px; margin-top: 26px; }\n.cambridge-hub .book {\n  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);\n  padding: 20px; box-shadow: var(--shadow-sm); position: relative;\n  transition: transform .18s, box-shadow .18s, border-color .18s;\n  display: flex; flex-direction: column; min-height: 168px;\n}\n.cambridge-hub .book:hover { transform: translateY(-4px); box-shadow: var(--shadow); }\n.cambridge-hub .book.is-live { border-color: color-mix(in srgb, var(--live) 40%, transparent); }\n.cambridge-hub .book .spine { width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; color: #fff; font-family: var(--display); font-weight: 800; font-size: 13px; }\n.cambridge-hub .book h4 { font-size: 17px; margin: 14px 0 5px; }\n.cambridge-hub .book .bmeta { font-size: 13.5px; color: var(--ink-soft); line-height: 1.45; flex: 1; }\n.cambridge-hub .book .tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }\n.cambridge-hub .book .tags span { font-size: 11.5px; font-weight: 600; white-space: nowrap; color: var(--ink-2); background: var(--paper-2); padding: 4px 9px; border-radius: 999px; }\n.cambridge-hub .book .bfoot { margin-top: 14px; }\n\n\/* ============================================================\n   Final CTA\n   ============================================================ *\/\n.cambridge-hub .cta {\n  margin: 30px 0 0; position: relative; overflow: hidden;\n  background: linear-gradient(160deg, var(--red), var(--red-deep));\n  border-radius: var(--r-xl); padding: 56px 48px; color: #fff; text-align: center;\n  box-shadow: var(--shadow-lg);\n}\n.cambridge-hub .cta::before { content:\"\"; position:absolute; inset:0; opacity:.4; background: radial-gradient(600px 300px at 80% -20%, rgba(255,255,255,.3), transparent 60%); }\n.cambridge-hub .cta h2 { position: relative; font-size: clamp(28px, 4vw, 44px); }\n.cambridge-hub .cta p { position: relative; color: rgba(255,255,255,.9); font-size: 18px; margin: 16px auto 0; max-width: 54ch; }\n.cambridge-hub .cta-actions { position: relative; display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-top: 30px; }\n.cambridge-hub .cta .btn-white { background: #fff; color: var(--red-deep); font-weight: 800; padding: 14px 26px; border-radius: 13px; box-shadow: var(--shadow); transition: transform .16s; }\n.cambridge-hub .cta .btn-white:hover { transform: translateY(-3px); }\n.cambridge-hub .cta .btn-outline { background: rgba(255,255,255,.12); color: #fff; border: 1px solid rgba(255,255,255,.5); font-weight: 700; padding: 14px 26px; border-radius: 13px; transition: background .16s; }\n.cambridge-hub .cta .btn-outline:hover { background: rgba(255,255,255,.22); }\n\n\/* ============================================================\n   Footer\n   ============================================================ *\/\n.cambridge-hub .site-footer { margin-top: 72px; background: var(--navy); color: rgba(255,255,255,.7); padding: 56px 0 30px; }\n.cambridge-hub .footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.3fr; gap: 40px; }\n.cambridge-hub .footer-brand .brand { color: #fff; }\n.cambridge-hub .footer-brand p { font-size: 14.5px; margin-top: 16px; max-width: 40ch; color: rgba(255,255,255,.6); }\n.cambridge-hub .footer-social { display: flex; gap: 10px; margin-top: 18px; }\n.cambridge-hub .footer-social a { width: 38px; height: 38px; border-radius: 10px; background: rgba(255,255,255,.08); display: grid; place-items: center; transition: background .16s; }\n.cambridge-hub .footer-social a:hover { background: var(--red); }\n.cambridge-hub .footer-social svg { width: 18px; height: 18px; fill: #fff; }\n.cambridge-hub .footer-col h5 { color: #fff; font-family: var(--display); font-size: 14px; letter-spacing: .04em; text-transform: uppercase; margin: 0 0 16px; }\n.cambridge-hub .footer-col a { display: block; font-size: 14.5px; padding: 6px 0; color: rgba(255,255,255,.66); transition: color .16s; }\n.cambridge-hub .footer-col a:hover { color: #fff; }\n.cambridge-hub .news input { width: 100%; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.16); color: #fff; padding: 12px 14px; border-radius: 11px; font-family: inherit; font-size: 14px; }\n.cambridge-hub .news input::placeholder { color: rgba(255,255,255,.4); }\n.cambridge-hub .news button { margin-top: 10px; width: 100%; background: var(--red); color: #fff; border: 0; padding: 12px; border-radius: 11px; font-weight: 700; transition: background .16s; }\n.cambridge-hub .news button:hover { background: var(--red-deep); }\n.cambridge-hub .footer-bottom { margin-top: 44px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.12); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; font-size: 13.5px; color: rgba(255,255,255,.5); }\n.cambridge-hub .footer-bottom a { color: rgba(255,255,255,.66); }\n\n\/* ============================================================\n   Reveal animation\n   ============================================================ *\/\n\/* Resting state is fully visible (capture- and no-JS-safe).\n   The entrance is a play-once animation, only when .in is added. *\/\n.cambridge-hub .reveal { opacity: 1; transform: none; }\n@media (prefers-reduced-motion: no-preference) {\n  .cambridge-hub .reveal.in { animation: rise .72s cubic-bezier(.2,.8,.2,1) both; }\n}\n@keyframes rise { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }\n@media (prefers-reduced-motion: reduce) {\n  .cambridge-hub * { animation: none !important; scroll-behavior: auto; }\n}\n\n\/* ============================================================\n   Responsive\n   ============================================================ *\/\n@media (max-width: 1000px) {\n  .cambridge-hub .hero-grid { grid-template-columns: 1fr; gap: 40px; }\n  .cambridge-hub .hero-visual { max-width: 520px; }\n  .cambridge-hub .series-card { grid-template-columns: 1fr; gap: 22px; }\n  .cambridge-hub .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; }\n}\n@media (max-width: 860px) {\n  .cambridge-hub .main-nav, .cambridge-hub .header-inner .btn-cta { display: none; }\n  .cambridge-hub .nav-toggle { display: grid; margin-left: auto; }\n  .cambridge-hub .stairs { grid-template-columns: 1fr 1fr; gap: 14px; }\n  .cambridge-hub .step { margin-bottom: 0 !important; }\n  .cambridge-hub .yle-grid { grid-template-columns: 1fr; }\n  .cambridge-hub .stats .stat { flex: 1; min-width: 0; }\n}\n@media (max-width: 560px) {\n  .cambridge-hub .wrap { padding: 0 18px; }\n  .cambridge-hub .hero { padding: 44px 0 20px; }\n  .cambridge-hub .stairs { grid-template-columns: 1fr; }\n  .cambridge-hub .test-row { grid-template-columns: 1fr; gap: 8px; }\n  .cambridge-hub .test-row .tn { display: none; }\n  .cambridge-hub .footer-grid { grid-template-columns: 1fr; }\n  .cambridge-hub .cta { padding: 40px 24px; }\n}\n\n\/* hamburger *\/\n.cambridge-hub .nav-toggle {\n  width: 44px; height: 44px; border-radius: 12px; border: 1px solid var(--line-2);\n  background: #fff; place-items: center; gap: 4px; box-shadow: var(--shadow-sm);\n}\n.cambridge-hub .nav-toggle span { width: 20px; height: 2px; background: var(--ink); border-radius: 2px; display: block; }\n.cambridge-hub .mobile-nav { display: none; }\n.cambridge-hub .mobile-nav.open { display: block; padding: 8px 0 18px; border-top: 1px solid var(--line); }\n.cambridge-hub .mobile-nav a { display: block; padding: 11px 4px; font-weight: 600; color: var(--ink-2); border-bottom: 1px solid var(--line); }\n\n<\/style>\n<div class=\"cambridge-hub\">\n<!-- HEADER stripped: WP theme nav -->\n\n<!-- ============ HERO ============ -->\n<section class=\"hero\">\n  <div class=\"wrap hero-grid\">\n    <div class=\"hero-copy\">\n      <span class=\"eyebrow reveal\"><i class=\"dot\"><\/i> Cambridge English \u00b7 Official Test Series<\/span>\n      <h1 class=\"reveal\">Practice <em>Cambridge<\/em> the right way<\/h1>\n      <p class=\"lead reveal\">A complete Cambridge pathway \u2014 from <b>YLE<\/b> (Starters, Movers, Flyers) to <b>KET<\/b> and <b>PET<\/b>. Authentic audio, detailed answer keys, and interactive online exercises.<\/p>\n      <div class=\"hero-actions reveal\">\n        <a class=\"btn-lg btn-primary\" href=\"https:\/\/allenglish4u.com\/cambridge-ket-2-test-1-listening\/\">\n          Start with KET 2 \u2014 free\n          <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 12h14M13 6l6 6-6 6\"\/><\/svg>\n        <\/a>\n        <a class=\"btn-lg btn-ghost\" href=\"#path\">See the learning path<\/a>\n      <\/div>\n      <div class=\"stats reveal\">\n        <div class=\"stat\"><div class=\"n\">30+<\/div><div class=\"l\">Books available<\/div><\/div>\n        <div class=\"stat\"><div class=\"n\">160+<\/div><div class=\"l\">Full tests<\/div><\/div>\n        <div class=\"stat\"><div class=\"n\">Pre-A1\u2192B1<\/div><div class=\"l\">CEFR levels<\/div><\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"hero-visual reveal\">\n      <span class=\"float-pill p1\">Pre-A1 \u2192 B1<\/span>\n      <span class=\"float-pill p2\">Authentic audio<\/span>\n      <div class=\"bookcard\">\n        <div class=\"bookcard-head\">\n          <span class=\"badge-live\"><i class=\"pulse\"><\/i> Live now<\/span>\n          <span style=\"font-size:13px;color:rgba(255,255,255,.55);font-weight:600\">A2 Key<\/span>\n        <\/div>\n        <h3>Cambridge KET 2<\/h3>\n        <div class=\"sub\">4 full tests \u00b7 Listening + Reading\/Writing \u00b7 Detailed answer keys<\/div>\n        <div class=\"testgrid\">\n          <a href=\"https:\/\/allenglish4u.com\/cambridge-ket-2-test-1-listening\/\"><span>Test 1 <span class=\"kind\">LISTENING<\/span><\/span><span class=\"arr\">\u2192<\/span><\/a>\n          <a href=\"https:\/\/allenglish4u.com\/cambridge-ket-2-test-1-rw\/\"><span>Test 1 <span class=\"kind\">R\/W<\/span><\/span><span class=\"arr\">\u2192<\/span><\/a>\n          <a href=\"https:\/\/allenglish4u.com\/cambridge-ket-2-test-2-listening\/\"><span>Test 2 <span class=\"kind\">LISTENING<\/span><\/span><span class=\"arr\">\u2192<\/span><\/a>\n          <a href=\"https:\/\/allenglish4u.com\/cambridge-ket-2-test-2-rw\/\"><span>Test 2 <span class=\"kind\">R\/W<\/span><\/span><span class=\"arr\">\u2192<\/span><\/a>\n        <\/div>\n        <div class=\"bookcard-foot\">\n          <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"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          Check answers instantly after each test\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ LEARNING PATH (STAIRCASE) ============ -->\n<section class=\"section path\" id=\"path\">\n  <div class=\"wrap\">\n    <div class=\"section-head reveal\">\n      <span class=\"kicker\"><i class=\"tick\"><\/i> The Cambridge ladder<\/span>\n      <h2>Climb from <em>Pre-A1<\/em> to <em>B1<\/em>, one level at a time<\/h2>\n      <p class=\"desc\">Every Cambridge qualification builds on the last. Start where your learner is today and follow the steps up.<\/p>\n      <div class=\"legend\">\n        <span><i class=\"l-live\"><\/i> Live now<\/span>\n        <span><i class=\"l-prog\"><\/i> In progress<\/span>\n        <span><i class=\"l-soon\"><\/i> Coming soon<\/span>\n      <\/div>\n    <\/div>\n    <div class=\"stairs\" id=\"stairs\"><\/div>\n    <div class=\"path-note reveal\">\n      <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><path d=\"M12 16v-4M12 8h.01\"\/><\/svg>\n      Tap any step to jump to that section below.\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ FILTER BAR ============ -->\n<div class=\"filterbar\">\n  <div class=\"wrap filters\">\n    <button class=\"fb active\" data-f=\"all\">All series<\/button>\n    <button class=\"fb\" data-f=\"yle\"><span class=\"c\" style=\"background:var(--flyers)\"><\/span> YLE \u00b7 Young Learners<\/button>\n    <button class=\"fb\" data-f=\"ket\"><span class=\"c\" style=\"background:var(--ket)\"><\/span> KET \u00b7 A2 Key<\/button>\n    <button class=\"fb\" data-f=\"pet\"><span class=\"c\" style=\"background:var(--pet)\"><\/span> PET \u00b7 B1<\/button>\n    <span class=\"count\">48 series<\/span>\n  <\/div>\n<\/div>\n\n<!-- ============ YLE ============ -->\n<section class=\"cat-section\" id=\"yle\">\n  <div class=\"wrap\">\n    <div class=\"section-head reveal\">\n      <span class=\"band\" style=\"background:var(--flyers-soft);color:var(--flyers)\"><span class=\"bb\" style=\"background:var(--flyers)\">Y<\/span> Cambridge YLE \u2014 Young Learners English<\/span>\n      <h2 style=\"margin-top:18px\">For <em style=\"color:var(--flyers)\">primary school<\/em> students<\/h2>\n      <p class=\"desc\">Cambridge Young Learners English tests are designed for children aged 6\u201312. Each level focuses on reading, writing, listening and speaking in a fun, age-appropriate format \u2014 with no pass or fail.<\/p>\n    <\/div>\n    <div class=\"series-list\" id=\"yle-list\"><\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ KET ============ -->\n<section class=\"cat-section\" id=\"ket\">\n  <div class=\"wrap\">\n    <div class=\"section-head reveal\">\n      <span class=\"band\" style=\"background:var(--ket-soft);color:var(--ket)\"><span class=\"bb\" style=\"background:var(--ket)\">K<\/span> Cambridge KET \u2014 A2 Key English Test<\/span>\n      <h2 style=\"margin-top:18px\"><em style=\"color:var(--ket)\">KET \/ A2 Key<\/em> \u2014 lower secondary<\/h2>\n      <p class=\"desc\">A2 Key (formerly KET) is the first step in the Cambridge English Qualifications pathway. It shows you can use English in simple, everyday situations \u2014 the ideal foundation for moving towards B1 Preliminary.<\/p>\n    <\/div>\n\n    <div class=\"series-list\" id=\"ket-list\"><\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ PET ============ -->\n<section class=\"cat-section\" id=\"pet\">\n  <div class=\"wrap\">\n    <div class=\"section-head reveal\">\n      <span class=\"band\" style=\"background:var(--pet-soft);color:var(--pet)\"><span class=\"bb\" style=\"background:var(--pet)\">P<\/span> Cambridge PET \u2014 B1 Preliminary English Test<\/span>\n      <h2 style=\"margin-top:18px\"><em style=\"color:var(--pet)\">PET \/ B1 Preliminary<\/em> \u2014 upper secondary<\/h2>\n      <p class=\"desc\">B1 Preliminary (formerly PET) proves you can use English independently in work, study and travel. At CEFR B1 you understand the main points of clear, standard input and produce simple connected text on familiar topics.<\/p>\n    <\/div>\n    <div class=\"series-list\" id=\"pet-list\"><\/div>\n  <\/div>\n<\/section>\n\n<!-- ============ FINAL CTA ============ -->\n<section class=\"section\" style=\"padding-top:20px\">\n  <div class=\"wrap\">\n    <div class=\"cta reveal\">\n      <h2>Start with KET 2 \u2014 completely free<\/h2>\n      <p>All 4 tests are live. Authentic Cambridge audio, online practice, and detailed answers the instant you submit. No sign-up required.<\/p>\n      <div class=\"cta-actions\">\n        <a class=\"btn-white\" href=\"https:\/\/allenglish4u.com\/cambridge-ket-2-test-1-listening\/\">Practise KET 2 Test 1 now<\/a>\n        <a class=\"btn-outline\" href=\"#path\">View full learning path<\/a>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- FOOTER stripped: WP theme footer -->\n<\/div>\n<script id=\"cambridge-hub-script\">\n\/* ============================================================\n   All English 4U \u2014 Cambridge hub  \u00b7  data + render + interactions\n   ============================================================ *\/\nconst BASE = \"https:\/\/allenglish4u.com\";\n\n\/* ---- KET 2 live test links (real URLs) ---- *\/\nconst KET2_TESTS = [\n  { n: 1, listen: BASE + \"\/cambridge-ket-2-test-1-listening\/\", rw: BASE + \"\/cambridge-ket-2-test-1-rw\/\" },\n  { n: 2, listen: BASE + \"\/cambridge-ket-2-test-2-listening\/\", rw: BASE + \"\/cambridge-ket-2-test-2-rw\/\" },\n  { n: 3, listen: BASE + \"\/cambridge-ket-2-test-3-listening\/\", rw: BASE + \"\/cambridge-ket-2-test-3-rw\/\" },\n  { n: 4, listen: BASE + \"\/cambridge-ket-2-test-4-listening\/\", rw: BASE + \"\/cambridge-ket-2-test-4-rw\/\" },\n];\n\n\/* ---- YLE levels (Starters \/ Movers \/ Flyers) ---- *\/\nconst YLE = [\n  { lvl: \"Pre-A1\", name: \"Starters\", color: \"var(--starters)\", soft: \"var(--starters-soft)\",\n    ages: \"Ages 6\u20138\",\n    blurb: \"A gentle first taste of English through games, songs and pictures \u2014 no pass or fail, just fun and stars for trying.\",\n    books: 9, status: \"live\", statusLabel: \"Live\", url: \"#yle\" },\n  { lvl: \"A1\", name: \"Movers\", color: \"var(--movers)\", soft: \"var(--movers-soft)\",\n    ages: \"Ages 8\u201310\",\n    blurb: \"The next step up \u2014 short stories and everyday situations that build real confidence and curiosity.\",\n    books: 9, status: \"live\", statusLabel: \"Live\", url: \"\/cambridge-movers-1-test-1-listening\/\" },\n  { lvl: \"A2\", name: \"Flyers\", color: \"var(--flyers)\", soft: \"var(--flyers-soft)\",\n    ages: \"Ages 10\u201312\",\n    blurb: \"The highest Young Learners level \u2014 longer texts and conversations that get learners ready for KET.\",\n    books: 9, status: \"prog\", statusLabel: \"In progress\" },\n];\n\n\/* ---- helpers ---- *\/\nconst T4 = () => [1, 2, 3, 4].map(n => ({ n, listen: null, rw: null }));\nconst TEST_STATS = [\n  { n: \"4\", label: \"Full tests\" },\n  { n: \"8\", label: \"Practice papers\" },\n  { n: \"L + R\/W\", label: \"Skills covered\" },\n];\n\n\/* ---- KET series (in order) ---- *\/\nconst KET_SERIES = [\n  { title: \"KET 1\", status: \"live\",\n    blurb: \"All 4 tests are LIVE \u2014 Listening + Reading\/Writing \u0111\u1ea7y \u0111\u1ee7. Audio embedded \u00b7 auto-grade \u00b7 transcripts.\",\n    stats: TEST_STATS,\n    tests: [\n      { n: 1, listen: BASE + \"\/cambridge-ket-1-test-1-listening\/\", rw: BASE + \"\/cambridge-ket-1-test-1-rw\/\" },\n      { n: 2, listen: BASE + \"\/cambridge-ket-1-test-2-listening\/\", rw: BASE + \"\/cambridge-ket-1-test-2-rw\/\" }, { n: 3, listen: BASE + \"\/cambridge-ket-1-test-3-listening\/\", rw: BASE + \"\/cambridge-ket-1-test-3-rw\/\" }, { n: 4, listen: BASE + \"\/cambridge-ket-1-test-4-listening\/\", rw: BASE + \"\/cambridge-ket-1-test-4-rw\/\" },\n    ],\n    start: { url: BASE + \"\/cambridge-ket-1-test-1-listening\/\", label: \"Try Test 1 Listening\" } },\n  { title: \"KET 2\", status: \"live\", statusLabel: \"Live now \u00b7 completely free\",\n    blurb: \"All four tests are live with authentic Cambridge audio. Practise online and check detailed answers the moment you submit \u2014 no sign-up required.\",\n    stats: TEST_STATS, tests: KET2_TESTS,\n    start: { url: BASE + \"\/cambridge-ket-2-test-1-listening\/\", label: \"Start Test 1 now\" } },\n  { title: \"KET 3\", status: \"live\",\n    blurb: \"Reading & Writing AND Listening tests are all LIVE \u2014 55 auto-graded R&W questions + 25 auto-graded Listening questions each, with YouTube audio and full transcripts.\",\n    stats: TEST_STATS,\n    tests: [\n      { n: 1, listen: BASE + \"\/cambridge-ket-3-test-1-listening\/\", rw: BASE + \"\/cambridge-ket-3-test-1-rw\/\" },\n      { n: 2, listen: BASE + \"\/cambridge-ket-3-test-2-listening\/\", rw: BASE + \"\/cambridge-ket-3-test-2-rw\/\" },\n      { n: 3, listen: BASE + \"\/cambridge-ket-3-test-3-listening\/\", rw: BASE + \"\/cambridge-ket-3-test-3-rw\/\" },\n      { n: 4, listen: BASE + \"\/cambridge-ket-3-test-4-listening\/\", rw: BASE + \"\/cambridge-ket-3-test-4-rw\/\" },\n    ],\n    start: { url: BASE + \"\/cambridge-ket-3-test-1-rw\/\", label: \"Try Test 1 Reading and Writing\" } },\n  { title: \"KET 4\", status: \"live\",\n    blurb: \"Tests 1-4 Reading and Writing are all LIVE - 55 auto-graded questions each + real Cambridge writing samples.\",\n    stats: TEST_STATS,\n    tests: [\n      { n: 1, listen: BASE + \"\/cambridge-ket-4-test-1-listening\/\", rw: BASE + \"\/cambridge-ket-4-test-1-rw\/\" },\n      { n: 2, listen: BASE + \"\/cambridge-ket-4-test-2-listening\/\", rw: BASE + \"\/cambridge-ket-4-test-2-rw\/\" }, { n: 3, listen: BASE + \"\/cambridge-ket-4-test-3-listening\/\", rw: BASE + \"\/cambridge-ket-4-test-3-rw\/\" }, { n: 4, listen: BASE + \"\/cambridge-ket-4-test-4-listening\/\", rw: BASE + \"\/cambridge-ket-4-test-4-rw\/\" },\n    ],\n    start: { url: BASE + \"\/cambridge-ket-4-test-1-rw\/\", label: \"Try Test 1 Reading and Writing\" } },\n  { title: \"KET 6\", status: \"live\",\n    blurb: \"All four Reading and Writing tests are LIVE - 55 auto-graded questions + real Cambridge writing samples.\",\n    stats: TEST_STATS,\n    tests: [\n      { n: 1, listen: null, rw: BASE + \"\/cambridge-ket-6-test-1-rw\/\" },\n      { n: 2, listen: null, rw: BASE + \"\/cambridge-ket-6-test-2-rw\/\" },\n      { n: 3, listen: null, rw: BASE + \"\/cambridge-ket-6-test-3-rw\/\" },\n      { n: 4, listen: null, rw: BASE + \"\/cambridge-ket-6-test-4-rw\/\" },\n    ],\n    start: { url: BASE + \"\/cambridge-ket-6-test-1-rw\/\", label: \"Start KET 6 Reading and Writing\" } },\n  { title: \"KET 5\", status: \"live\",\n    blurb: \"Tests 1-4 Reading and Writing are all LIVE - 55 auto-graded questions each + real Cambridge writing samples.\",\n    stats: TEST_STATS,\n    tests: [\n      { n: 1, listen: BASE + \"\/cambridge-ket-5-test-1-listening\/\", rw: BASE + \"\/cambridge-ket-5-test-1-rw\/\" },\n      { n: 2, listen: BASE + \"\/cambridge-ket-5-test-2-listening\/\", rw: BASE + \"\/cambridge-ket-5-test-2-rw\/\" },\n      { n: 3, listen: null, rw: BASE + \"\/cambridge-ket-5-test-3-rw\/\" },\n      { n: 4, listen: null, rw: BASE + \"\/cambridge-ket-5-test-4-rw\/\" },\n    ],\n    start: { url: BASE + \"\/cambridge-ket-5-test-1-rw\/\", label: \"Try Test 1 Reading and Writing\" } },\n  { title: \"KET 7\", status: \"live\",\n    blurb: \"All four Reading and Writing tests are LIVE - 55 auto-graded questions + real Cambridge writing samples.\",\n    stats: TEST_STATS,\n    tests: [\n      { n: 1, listen: null, rw: BASE + \"\/cambridge-ket-7-test-1-rw\/\" },\n      { n: 2, listen: null, rw: BASE + \"\/cambridge-ket-7-test-2-rw\/\" },\n      { n: 3, listen: null, rw: BASE + \"\/cambridge-ket-7-test-3-rw\/\" },\n      { n: 4, listen: null, rw: BASE + \"\/cambridge-ket-7-test-4-rw\/\" },\n    ],\n    start: { url: BASE + \"\/cambridge-ket-7-test-1-rw\/\", label: \"Start KET 7 Reading and Writing\" } },\n  { title: \"KET Extra\", status: \"live\",\n    blurb: \"All four Reading and Writing tests are LIVE - 55 auto-graded questions + real Cambridge writing samples.\",\n    stats: TEST_STATS,\n    tests: [\n      { n: 1, listen: null, rw: BASE + \"\/cambridge-ket-extra-test-1-rw\/\" },\n      { n: 2, listen: null, rw: BASE + \"\/cambridge-ket-extra-test-2-rw\/\" },\n      { n: 3, listen: null, rw: BASE + \"\/cambridge-ket-extra-test-3-rw\/\" },\n      { n: 4, listen: null, rw: BASE + \"\/cambridge-ket-extra-test-4-rw\/\" },\n    ],\n    start: { url: BASE + \"\/cambridge-ket-extra-test-1-rw\/\", label: \"Start KET Extra Reading and Writing\" } },\n  { start: { url: BASE + \"\/complete-ket-unit-1-rw\/\", label: \"Start Complete KET Unit 1\" },\n    title: \"Complete KET\", status: \"live\",\n    blurb: \"All 14 units are live \u2014 Reading and Writing practice, unit by unit.\",\n    tests: [\n      { n: 1, listen: null, rw: BASE + \"\/complete-ket-unit-1-rw\/\" },\n      { n: 2, listen: null, rw: BASE + \"\/complete-ket-unit-2-rw\/\" },\n      { n: 3, listen: null, rw: BASE + \"\/complete-ket-unit-3-rw\/\" },\n      { n: 4, listen: null, rw: BASE + \"\/complete-ket-unit-4-rw\/\" },\n      { n: 5, listen: null, rw: BASE + \"\/complete-ket-unit-5-rw\/\" },\n      { n: 6, listen: null, rw: BASE + \"\/complete-ket-unit-6-rw\/\" },\n      { n: 7, listen: null, rw: BASE + \"\/complete-ket-unit-7-rw\/\" },\n      { n: 8, listen: null, rw: BASE + \"\/complete-ket-unit-8-rw\/\" },\n      { n: 9, listen: null, rw: BASE + \"\/complete-ket-unit-9-rw\/\" },\n      { n: 10, listen: null, rw: BASE + \"\/complete-ket-unit-10-rw\/\" },\n      { n: 11, listen: null, rw: BASE + \"\/complete-ket-unit-11-rw\/\" },\n      { n: 12, listen: null, rw: BASE + \"\/complete-ket-unit-12-rw\/\" },\n      { n: 13, listen: null, rw: BASE + \"\/complete-ket-unit-13-rw\/\" },\n      { n: 14, listen: null, rw: BASE + \"\/complete-ket-unit-14-rw\/\" },\n    ] },\n  { title: \"KET Objective\", status: \"soon\", blurb: \"Topic-based practice \u00b7 Book + Audio \u00b7 Cambridge Official.\",\n    items: [\"Unit Exercises\", \"Practice Tests\", \"Audio\"] },\n  { title: \"Target KET for Schools\", status: \"soon\", blurb: \"Student + Workbook + Teacher Book + Audio \u00b7 Designed for school students.\",\n    items: [\"Practice Tests\", \"Skills Training\", \"Workbook\"] },\n];\n\n\/* ---- PET series (Cambridge Preliminary 1\u20138 + supplements, in order) ---- *\/\nconst PET_SERIES = [\n  { title: \"Cambridge Preliminary 1\", status: \"prog\", blurb: \"Audio fully extracted (4 parts per test) \u00b7 Book PDF + Key. Tests are being prepared for online practice.\", stats: TEST_STATS, tests: [{n:1,listen:null,rw:BASE+\"\/cambridge-pet-1-test-1-rw\/\"},{n:2,listen:null,rw:BASE+\"\/cambridge-pet-1-test-2-rw\/\"},{n:3,listen:null,rw:BASE+\"\/cambridge-pet-1-test-3-rw\/\"},{n:4,listen:null,rw:BASE+\"\/cambridge-pet-1-test-4-rw\/\"}] },\n  { title: \"Cambridge Preliminary 2\", status: \"prog\", blurb: \"Book PDF + Audio \u00b7 Detailed answer keys.\", stats: TEST_STATS, tests: [{n:1,listen:null,rw:BASE+\"\/cambridge-pet-2-test-1-rw\/\"},{n:2,listen:null,rw:BASE+\"\/cambridge-pet-2-test-2-rw\/\"},{n:3,listen:null,rw:BASE+\"\/cambridge-pet-2-test-3-rw\/\"},{n:4,listen:null,rw:BASE+\"\/cambridge-pet-2-test-4-rw\/\"}] },\n  { title: \"Cambridge Preliminary 3\", status: \"soon\", blurb: \"Book PDF + Audio \u00b7 Detailed answer keys.\", stats: TEST_STATS, tests: T4() },\n  { title: \"Cambridge Preliminary 4\", status: \"soon\", blurb: \"Book PDF + Audio \u00b7 Detailed answer keys.\", stats: TEST_STATS, tests: T4() },\n  { title: \"Cambridge Preliminary 5\", status: \"soon\", blurb: \"Book PDF + Audio \u00b7 Detailed answer keys.\", stats: TEST_STATS, tests: T4() },\n  { title: \"Cambridge Preliminary 6\", status: \"soon\", blurb: \"Book PDF + Audio \u00b7 Detailed answer keys.\", stats: TEST_STATS, tests: T4() },\n  { title: \"Cambridge Preliminary 7\", status: \"soon\", blurb: \"Book PDF + Audio \u00b7 Detailed answer keys.\", stats: TEST_STATS, tests: T4() },\n  { title: \"Cambridge Preliminary 8\", status: \"soon\", blurb: \"Book PDF + Audio \u00b7 Detailed answer keys.\", stats: TEST_STATS, tests: T4() },\n  { title: \"Simply PET\", status: \"soon\", blurb: \"8 Practice Tests \u00b7 Self-study Guide \u00b7 Audio \u00b7 Updated exam format.\",\n    items: [\"Practice Tests 1\u20134\", \"Tests 5\u20138\", \"Self-study Guide\", \"Audio\"] },\n  { title: \"Grammar For PET\", status: \"soon\", blurb: \"Cambridge Official \u00b7 Comprehensive grammar practice \u00b7 PDF + Answers + CD Audio.\",\n    items: [\"Grammar Units\", \"Practice Exercises\", \"CD1 + CD2 Audio\", \"Answer Key\"] },\n];\n\n\/* ---- staircase ---- *\/\nconst STAIRS = [\n  { lvl: \"Pre-A1\", name: \"YLE Starters\", color: \"var(--starters)\", who: \"Young Learners\", status: \"live\",  label: \"Tests 1-3 ready\", target: \"#yle-starters\" },\n  { lvl: \"A1\",     name: \"YLE Movers\",   color: \"var(--movers)\",   who: \"Young Learners\", status: \"live\",  label: \"Listening & R\/W 1\u20139 ready\", target: \"#yle-movers\" },\n  { lvl: \"A2\",     name: \"YLE Flyers\",   color: \"var(--flyers)\",   who: \"Young Learners\", status: \"prog\",  label: \"In progress\",  target: \"#yle-flyers\" },\n  { lvl: \"A2\",     name: \"KET \u00b7 A2 Key\", color: \"var(--ket)\",      who: \"Lower secondary\", status: \"live\", label: \"Live now\",    target: \"#ket\" },\n  { lvl: \"B1\",     name: \"PET \u00b7 B1 Prelim\", color: \"var(--pet)\",   who: \"Upper secondary\", status: \"prog\", label: \"In progress\",  target: \"#pet\" },\n];\n\nconst STATUS_TEXT = { live: \"Live now\", prog: \"In progress\", soon: \"Coming soon\" };\nconst arrowSvg = '<svg class=\"arr\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 12h14M13 6l6 6-6 6\"\/><\/svg>';\n\/\/ lively contextual icons\nconst icoHeadphones = '<svg class=\"tl-ico\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 14v-2a9 9 0 0 1 18 0v2\"\/><rect x=\"3\" y=\"13\" width=\"4.2\" height=\"7\" rx=\"1.6\"\/><rect x=\"16.8\" y=\"13\" width=\"4.2\" height=\"7\" rx=\"1.6\"\/><\/svg>';\nconst icoPen = '<svg class=\"tl-ico\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 20h9\"\/><path d=\"M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4z\"\/><\/svg>';\nconst lockSvg = '<svg class=\"lock\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"\/><path d=\"M8 11V7a4 4 0 0 1 8 0v4\"\/><\/svg>';\n\/\/ playful kid-friendly mascots + speaking bubble\nconst icoStar = '<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2.6l2.6 5.7 6.2.6c.8.1 1.1 1.1.5 1.6l-4.7 4.1 1.4 6.1c.2.8-.7 1.4-1.4 1l-5.4-3.2-5.4 3.2c-.7.4-1.6-.2-1.4-1l1.4-6.1L1.7 10.5c-.6-.5-.3-1.5.5-1.6l6.2-.6L11 2.6c.4-.8 1.6-.8 2 0z\"\/><circle cx=\"9.3\" cy=\"10.8\" r=\"1\" fill=\"#fff\"\/><circle cx=\"14.7\" cy=\"10.8\" r=\"1\" fill=\"#fff\"\/><\/svg>';\nconst icoRocket = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4.6 16.4c-1.4 1-1.9 4.4-1.9 4.4s3.4-.5 4.4-1.9c.6-.8.5-2.1-.3-2.9-.8-.8-2.1-.9-2.2.4z\"\/><path d=\"M12.5 15.5L8.5 11.5c.8-4 3.6-7.4 8.5-9 .6 0 3.5.3 4 4-.9 4.9-4.5 7.7-8.5 9z\"\/><circle cx=\"14.5\" cy=\"9.5\" r=\"1.5\"\/><\/svg>';\nconst icoPlane = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21.5 3.5L2.8 10.2c-.7.3-.7 1.3.1 1.5l6.3 1.9 1.9 6.3c.2.8 1.2.8 1.5.1z\"\/><path d=\"M21.5 3.5L9.2 13.6\"\/><\/svg>';\nconst icoSpeak = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 11.5a8.4 8.4 0 0 1-12.4 7.4L3 20.5l1.6-5.4A8.4 8.4 0 1 1 21 11.5z\"\/><\/svg>';\n\n\/* ============================================================\n   Render\n   ============================================================ *\/\nfunction renderStairs() {\n  const el = document.getElementById(\"stairs\");\n  el.innerHTML = STAIRS.map((s, i) => `\n    <a class=\"step reveal\" href=\"${s.target}\" style=\"--lc:${s.color}; transition-delay:${i * 70}ms\">\n      <span class=\"num\">0${i + 1}<\/span>\n      <span class=\"lvl\">${s.lvl}<\/span>\n      <h4>${s.name}<\/h4>\n      <div class=\"who\">${s.who}<\/div>\n      <span class=\"st ${s.status}\"><i class=\"d\"><\/i>${s.label}<\/span>\n    <\/a>`).join(\"\");\n}\n\nfunction renderYLE() {\n  const mascots = { Starters: icoStar, Movers: icoRocket, Flyers: icoPlane };\n  let html = \"\";\n  YLE.forEach(c => {\n    for (let b = 1; b <= c.books; b++) {\n      const rows = [1, 2, 3].map(n => {\n        let rwUrl = null, listenUrl = null;\n          if (c.name === \"Movers\") if (b === 4) rwUrl = \"\/cambridge-movers-4-test-\" + n + \"-rw\/\";\n          if (c.name === \"Movers\") if (b === 5) rwUrl = \"\/cambridge-movers-5-test-\" + n + \"-rw\/\";\n          if (c.name === \"Movers\") if (b === 6) rwUrl = \"\/cambridge-movers-6-test-\" + n + \"-rw\/\";\n          if (c.name === \"Movers\") if (b === 7) rwUrl = \"\/cambridge-movers-7-test-\" + n + \"-rw\/\";\n          if (c.name === \"Movers\") if (b === 8) rwUrl = \"\/cambridge-movers-8-test-\" + n + \"-rw\/\";\n          if (c.name === \"Movers\") if (b === 9) rwUrl = \"\/cambridge-movers-9-test-\" + n + \"-rw\/\";\n        if (c.name === \"Movers\") if (b === 1) listenUrl = \"\/cambridge-movers-1-test-\" + n + \"-listening\/\"; if (c.name === \"Movers\") if (b === 2) listenUrl = \"\/cambridge-movers-2-test-\" + n + \"-listening\/\"; if (c.name === \"Movers\") if (b === 3) listenUrl = \"\/cambridge-movers-3-test-\" + n + \"-listening\/\"; if (c.name === \"Movers\") if (b === 4) listenUrl = \"\/cambridge-movers-4-test-\" + n + \"-listening\/\"; if (c.name === \"Movers\") if (b === 5) listenUrl = \"\/cambridge-movers-5-test-\" + n + \"-listening\/\"; if (c.name === \"Movers\") if (b === 6) listenUrl = \"\/cambridge-movers-6-test-\" + n + \"-listening\/\"; if (c.name === \"Movers\") if (b === 7) listenUrl = \"\/cambridge-movers-7-test-\" + n + \"-listening\/\";\n        if (c.name === \"Movers\") if (b === 8) listenUrl = \"\/yle-movers-8-test-\" + n + \"-listening\/\";\n        if (c.name === \"Movers\") if (b === 9) listenUrl = \"\/cambridge-movers-9-test-\" + n + \"-listening\/\";\n        if (c.name === \"Movers\") if (b === 1) rwUrl = \"\/cambridge-movers-1-test-\" + n + \"-rw\/\"; if (c.name === \"Movers\") if (b === 2) rwUrl = \"\/cambridge-movers-2-test-\" + n + \"-rw\/\"; if (c.name === \"Movers\") if (b === 3) rwUrl = \"\/cambridge-movers-3-test-\" + n + \"-rw\/\";\n        if (c.name === \"Starters\") if (b === 1) if (n === 1) rwUrl = \"\/cambridge-starters-1-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 1) if (n === 2) rwUrl = \"\/cambridge-starters-1-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 1) if (n === 3) rwUrl = \"\/cambridge-starters-1-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 2) if (n === 1) rwUrl = \"\/cambridge-starters-2-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 2) if (n === 2) rwUrl = \"\/cambridge-starters-2-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 2) if (n === 3) rwUrl = \"\/cambridge-starters-2-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 3) if (n === 1) rwUrl = \"\/cambridge-starters-3-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 3) if (n === 2) rwUrl = \"\/cambridge-starters-3-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 3) if (n === 3) rwUrl = \"\/cambridge-starters-3-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 4) if (n === 1) rwUrl = \"\/cambridge-starters-4-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 4) if (n === 2) rwUrl = \"\/cambridge-starters-4-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 4) if (n === 3) rwUrl = \"\/cambridge-starters-4-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 5) if (n === 1) rwUrl = \"\/cambridge-starters-5-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 5) if (n === 2) rwUrl = \"\/cambridge-starters-5-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 5) if (n === 3) rwUrl = \"\/cambridge-starters-5-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 6) if (n === 1) rwUrl = \"\/cambridge-starters-6-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 8) if (n === 1) rwUrl = \"\/cambridge-starters-8-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 8) if (n === 2) rwUrl = \"\/cambridge-starters-8-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 8) if (n === 3) rwUrl = \"\/cambridge-starters-8-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 9) if (n === 1) rwUrl = \"\/cambridge-starters-9-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 9) if (n === 2) rwUrl = \"\/cambridge-starters-9-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 9) if (n === 3) rwUrl = \"\/cambridge-starters-9-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 7) if (n === 1) rwUrl = \"\/cambridge-starters-7-test-1-rw\/\";\n          if (c.name === \"Starters\") if (b === 7) if (n === 3) rwUrl = \"\/cambridge-starters-7-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 7) if (n === 2) rwUrl = \"\/cambridge-starters-7-test-2-rw\/\";\n          if (c.name === \"Starters\") if (b === 6) if (n === 3) rwUrl = \"\/cambridge-starters-6-test-3-rw\/\";\n          if (c.name === \"Starters\") if (b === 6) if (n === 2) rwUrl = \"\/cambridge-starters-6-test-2-rw\/\";\n        if (c.name === \"Flyers\") if (b === 1) if (n === 1) listenUrl = \"\/cambridge-flyers-1-test-1-listening\/\";\n          if (c.name === \"Flyers\") if (b === 2) if (n === 1) listenUrl = \"\/cambridge-flyers-2-test-1-listening\/\";\n          if (c.name === \"Flyers\") if (b === 2) if (n === 2) listenUrl = \"\/cambridge-flyers-2-test-2-listening\/\";\n          if (c.name === \"Flyers\") if (b === 2) if (n === 3) listenUrl = \"\/cambridge-flyers-2-test-3-listening\/\";\n          if (c.name === \"Flyers\") if (b === 3) if (n === 1) listenUrl = \"\/cambridge-flyers-3-test-1-listening\/\";\n          if (c.name === \"Flyers\") if (b === 3) if (n === 2) listenUrl = \"\/cambridge-flyers-3-test-2-listening\/\";\nif (c.name === \"Flyers\") if (b === 3) if (n === 3) listenUrl = \"\/cambridge-flyers-3-test-3-listening\/\";\nif (c.name === \"Flyers\") if (b === 4) if (n === 1) listenUrl = \"\/cambridge-flyers-4-test-1-listening\/\"; if (c.name === \"Flyers\") if (b === 1) if (n === 1) rwUrl = \"\/cambridge-flyers-1-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 3) if (n === 1) rwUrl = \"\/cambridge-flyers-3-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 3) if (n === 2) rwUrl = \"\/cambridge-flyers-3-test-2-rw\/\";\n          if (c.name === \"Flyers\") if (b === 3) if (n === 3) rwUrl = \"\/cambridge-flyers-3-test-3-rw\/\"; if (c.name === \"Flyers\") if (b === 1) if (n === 2) rwUrl = \"\/cambridge-flyers-1-test-2-rw\/\"; if (c.name === \"Flyers\") if (b === 1) if (n === 3) rwUrl = \"\/cambridge-flyers-1-test-3-rw\/\"; if (c.name === \"Flyers\") if (b === 2) if (n === 1) rwUrl = \"\/cambridge-flyers-2-test-1-rw\/\"; if (c.name === \"Flyers\") if (b === 2) if (n === 2) rwUrl = \"\/cambridge-flyers-2-test-2-rw\/\"; if (c.name === \"Flyers\") if (b === 2) if (n === 3) rwUrl = \"\/cambridge-flyers-2-test-3-rw\/\";\n          if (c.name === \"Flyers\") if (b === 4) if (n === 1) rwUrl = \"\/cambridge-flyers-4-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 4) if (n === 2) rwUrl = \"\/cambridge-flyers-4-test-2-rw\/\";\n          if (c.name === \"Flyers\") if (b === 4) if (n === 3) rwUrl = \"\/cambridge-flyers-4-test-3-rw\/\";\n          if (c.name === \"Flyers\") if (b === 5) if (n === 1) rwUrl = \"\/cambridge-flyers-5-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 5) if (n === 2) rwUrl = \"\/cambridge-flyers-5-test-2-rw\/\";\n          if (c.name === \"Flyers\") if (b === 5) if (n === 3) rwUrl = \"\/cambridge-flyers-5-test-3-rw\/\";\n          if (c.name === \"Flyers\") if (b === 7) if (n === 1) rwUrl = \"\/cambridge-flyers-7-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 7) if (n === 2) rwUrl = \"\/cambridge-flyers-7-test-2-rw\/\";\n          if (c.name === \"Flyers\") if (b === 7) if (n === 3) rwUrl = \"\/cambridge-flyers-7-test-3-rw\/\";\n          if (c.name === \"Flyers\") if (b === 8) if (n === 1) rwUrl = \"\/cambridge-flyers-8-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 8) if (n === 2) rwUrl = \"\/cambridge-flyers-8-test-2-rw\/\";\n          if (c.name === \"Flyers\") if (b === 8) if (n === 3) rwUrl = \"\/cambridge-flyers-8-test-3-rw\/\";\n          if (c.name === \"Flyers\") if (b === 9) if (n === 1) rwUrl = \"\/cambridge-flyers-9-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 9) if (n === 2) rwUrl = \"\/cambridge-flyers-9-test-2-rw\/\";\n          if (c.name === \"Flyers\") if (b === 9) if (n === 3) rwUrl = \"\/cambridge-flyers-9-test-3-rw\/\";\n          if (c.name === \"Flyers\") if (b === 6) if (n === 1) rwUrl = \"\/cambridge-flyers-6-test-1-rw\/\";\n          if (c.name === \"Flyers\") if (b === 6) if (n === 2) rwUrl = \"\/cambridge-flyers-6-test-2-rw\/\";\n          if (c.name === \"Flyers\") if (b === 6) if (n === 3) rwUrl = \"\/cambridge-flyers-6-test-3-rw\/\";\nif (c.name === \"Flyers\") if (b === 1) if (n === 2) listenUrl = \"\/cambridge-flyers-1-test-2-listening\/\";\nif (c.name === \"Flyers\") if (b === 1) if (n === 3) listenUrl = \"\/cambridge-flyers-1-test-3-listening\/\";\n        return `\n        <div class=\"test-row\">\n          <span class=\"tn\">0${n}<\/span>\n          ${paper(listenUrl, icoHeadphones, \"Listening\")}\n          ${paper(rwUrl, icoPen, \"Reading \/ Writing\")}\n        <\/div>`;\n      }).join(\"\");\n      html += `\n      <article class=\"series-card yle-card reveal\" style=\"--lc:${c.color}; --lc-soft:${c.soft}\">\n        <div class=\"sc-info\">\n          <span class=\"status-tag ${c.status}\"><i class=\"d\"><\/i>${c.statusLabel}<\/span>\n          <div class=\"yle-title\">\n            <span class=\"yle-mascot\">${mascots[c.name]}<\/span>\n            <div class=\"yle-head\"><span class=\"lvl-badge\">${c.lvl}<\/span><h3>${c.name} ${b}<\/h3><\/div>\n          <\/div>\n          <p>${c.ages} \u00b7 3 practice tests, each with Listening and Reading \/ Writing plus answer keys.<\/p>\n          <div class=\"sc-stats\">\n            <div class=\"ks\"><b>3<\/b><span>Tests<\/span><\/div>\n            <div class=\"ks\"><b>6<\/b><span>Papers<\/span><\/div>\n            <div class=\"ks\"><b>L + R\/W<\/b><span>Skills covered<\/span><\/div>\n          <\/div>\n        <\/div>\n        <div class=\"sc-right\">\n          <div class=\"yle-books-label\">3 tests \u00b7 Listening + Reading \/ Writing each<\/div>\n          <div class=\"sc-tests\">${rows}<\/div>\n        <\/div>\n      <\/article>`;\n    }\n  });\n  document.getElementById(\"yle-list\").innerHTML = html;\n}\n\nfunction paper(url, ico, label) {\n  if (url) return `<a class=\"test-link\" href=\"${url}\" target=\"_blank\" rel=\"noopener\">${ico}<span class=\"tl-label\">${label}<\/span>${arrowSvg}<\/a>`;\n  return `<span class=\"test-link locked\">${ico}<span class=\"tl-label\">${label}<\/span>${lockSvg}<\/span>`;\n}\n\nfunction seriesCard(s, accent, soft) {\n  const statusLabel = s.statusLabel || STATUS_TEXT[s.status];\n  const statsHtml = s.stats\n    ? `<div class=\"sc-stats\">${s.stats.map(x => `<div class=\"ks\"><b>${x.n}<\/b><span>${x.label}<\/span><\/div>`).join(\"\")}<\/div>`\n    : \"\";\n  const startHtml = s.start\n    ? `<a class=\"btn-lg btn-primary sc-start\" href=\"${s.start.url}\" target=\"_blank\" rel=\"noopener\">${s.start.label} ${arrowSvg}<\/a>`\n    : \"\";\n  let right;\n  if (s.tests) {\n    right = `<div class=\"sc-tests\">${s.tests.map(t => `\n      <div class=\"test-row\">\n        <span class=\"tn\">0${t.n}<\/span>\n        ${paper(t.listen, icoHeadphones, \"Listening\")}\n        ${paper(t.rw, icoPen, \"Reading \/ Writing\")}\n      <\/div>`).join(\"\")}<\/div>`;\n  } else {\n    right = `<div class=\"sc-items\">${s.items.map(it => `<span class=\"sc-item\">${it}<\/span>`).join(\"\")}<\/div>`;\n  }\n  return `\n    <article class=\"series-card reveal${s.status === \"live\" ? \" is-live\" : \"\"}\" style=\"--lc:${accent}; --lc-soft:${soft}\">\n      <div class=\"sc-info\">\n        <span class=\"status-tag ${s.status}\"><i class=\"d\"><\/i>${statusLabel}<\/span>\n        <h3>${s.title}<\/h3>\n        <p>${s.blurb}<\/p>\n        ${statsHtml}\n        ${startHtml}\n      <\/div>\n      <div class=\"sc-right\">${right}<\/div>\n    <\/article>`;\n}\n\nfunction renderKET() {\n  document.getElementById(\"ket-list\").innerHTML =\n    KET_SERIES.map(s => seriesCard(s, \"var(--ket)\", \"var(--ket-soft)\")).join(\"\");\n}\nfunction renderPET() {\n  document.getElementById(\"pet-list\").innerHTML =\n    PET_SERIES.map(s => seriesCard(s, \"var(--pet)\", \"var(--pet-soft)\")).join(\"\");\n}\n\n\/* ============================================================\n   Interactions\n   ============================================================ *\/\nfunction initFilters() {\n  const buttons = document.querySelectorAll(\".fb\");\n  const sections = {\n    yle: document.getElementById(\"yle\"),\n    ket: document.getElementById(\"ket\"),\n    pet: document.getElementById(\"pet\"),\n  };\n  const counts = { all: \"48 series\", yle: \"27 books \u00b7 81 tests\", ket: \"11 series\", pet: \"10 books\" };\n  const countEl = document.querySelector(\".filters .count\");\n  buttons.forEach(btn => btn.addEventListener(\"click\", () => {\n    const f = btn.dataset.f;\n    buttons.forEach(b => b.classList.toggle(\"active\", b === btn));\n    Object.entries(sections).forEach(([key, sec]) => {\n      sec.classList.toggle(\"hide\", !(f === \"all\" || f === key));\n    });\n    countEl.textContent = counts[f];\n    revealNow();\n  }));\n}\n\nfunction initHeader() {\n  const header = document.querySelector(\".site-header\");\n  if (header) {\n    const onScroll = () => header.classList.toggle(\"scrolled\", window.scrollY > 12);\n    onScroll();\n    window.addEventListener(\"scroll\", onScroll, { passive: true });\n  }\n  const toggle = document.querySelector(\".nav-toggle\");\n  const mnav = document.querySelector(\".mobile-nav\");\n  if (toggle) toggle.addEventListener(\"click\", () => mnav.classList.toggle(\"open\"));\n  if (mnav) mnav.querySelectorAll(\"a\").forEach(a => a.addEventListener(\"click\", () => mnav.classList.remove(\"open\")));\n}\n\nlet revealObserver;\nfunction initReveal() {\n  revealObserver = new IntersectionObserver((entries) => {\n    entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add(\"in\"); revealObserver.unobserve(e.target); } });\n  }, { threshold: 0.12, rootMargin: \"0px 0px -40px 0px\" });\n  revealNow();\n}\nfunction revealNow() {\n  document.querySelectorAll(\".reveal:not(.in)\").forEach(el => revealObserver.observe(el));\n}\n\nfunction patchYLELinks() {\n  const yc = document.querySelectorAll('.yle-card');\n  if (!yc.length) return;\n  const s1 = yc[0];\n  const rows = s1.querySelectorAll('.test-row');\n  const L = [\n    { L: BASE+'\/cambridge-starters-1-test-1-listening\/', R: BASE+'\/cambridge-starters-1-test-1-rw\/' },\n    { L: BASE+'\/cambridge-starters-1-test-2-listening\/', R: null },\n    { L: BASE+'\/cambridge-starters-1-test-3-listening\/', R: null },\n  ];\n  rows.forEach((row, i) => {\n    const tl = L[i]; if (!tl) return;\n    const lk = row.querySelectorAll('.test-link.locked');\n    if (tl.L && lk[0]) lk[0].outerHTML = '<a class=\"test-link\" href=\"'+tl.L+'\" target=\"_blank\" rel=\"noopener\">'+icoHeadphones+'<span class=\"tl-label\">Listening<\/span>'+arrowSvg+'<\/a>';\n    if (tl.R && lk[1]) lk[1].outerHTML = '<a class=\"test-link\" href=\"'+tl.R+'\" target=\"_blank\" rel=\"noopener\">'+icoPen+'<span class=\"tl-label\">Reading \/ Writing<\/span>'+arrowSvg+'<\/a>';\n  });\n  \/* Starters 2 patch \u2014 added 2026-06-07 *\/\n  const s2 = yc[1];\n  if (s2) {\n    const rows2 = s2.querySelectorAll('.test-row');\n    const L2 = [\n      { L: BASE+'\/cambridge-starters-2-test-1-listening\/', R: null },\n      { L: BASE+'\/cambridge-starters-2-test-2-listening\/', R: null },\n      { L: BASE+'\/cambridge-starters-2-test-3-listening\/', R: null }\n    ];\n    rows2.forEach((row, i) => {\n      const tl = L2[i]; if (!tl) return;\n      const lk = row.querySelectorAll('.test-link.locked');\n      if (tl.L && lk[0]) lk[0].outerHTML = '<a class=\"test-link\" href=\"'+tl.L+'\" target=\"_blank\" rel=\"noopener\">'+icoHeadphones+'<span class=\"tl-label\">Listening<\/span>'+arrowSvg+'<\/a>';\n    });\n  }\n  \/* Starters 3 patch \u2014 added 2026-06-07 *\/\n  const s3 = yc[2];\n  if (s3) {\n    const rows3 = s3.querySelectorAll('.test-row');\n    const L3 = [\n      { L: BASE+'\/cambridge-starters-3-test-1-listening\/', R: null },\n      { L: BASE+'\/cambridge-starters-3-test-2-listening\/', R: null },\n      { L: BASE+'\/cambridge-starters-3-test-3-listening\/', R: null }\n    ];\n    rows3.forEach((row, i) => {\n      const tl = L3[i]; if (!tl) return;\n      const lk = row.querySelectorAll('.test-link.locked');\n      if (tl.L && lk[0]) lk[0].outerHTML = '<a class=\"test-link\" href=\"'+tl.L+'\" target=\"_blank\" rel=\"noopener\">'+icoHeadphones+'<span class=\"tl-label\">Listening<\/span>'+arrowSvg+'<\/a>';\n    });\n  }\n  \/* Starters 4 patch \u2014 added 2026-06-21 *\/\n  const s4 = yc[3];\n  if (s4) {\n    const rows4 = s4.querySelectorAll(\".test-row\");\n    const L4 = [\n      { L: BASE+\"\/cambridge-starters-4-test-1-listening\/\", R: null },\n      { L: BASE+\"\/cambridge-starters-4-test-2-listening\/\", R: null },\n      { L: BASE+\"\/cambridge-starters-4-test-3-listening\/\", R: null }\n    ];\n    rows4.forEach((row, i) => {\n      const tl = L4[i]; if (!tl) return;\n      const lk = row.querySelectorAll(\".test-link.locked\");\n      if (tl.L && lk[0]) lk[0].outerHTML = '<a class=\"test-link\" href=\"'+tl.L+'\" target=\"_blank\" rel=\"noopener\">'+icoHeadphones+'<span class=\"tl-label\">Listening<\/span>'+arrowSvg+'<\/a>';\n    });\n  }\n}\n\/* ---- boot ---- *\/\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n  renderStairs();\n  renderYLE();\n  patchYLELinks();\n  renderKET();\n  renderPET();\n  initFilters();\n  initHeader();\n  initReveal();\n});\n\n<\/script>\n\n\n\n\n\n\n<script>\n(function(){\n  function addAnchor(id, searchText) {\n    if (document.getElementById(id)) return;\n    var cards = document.querySelectorAll('#yle-list .series-card');\n    for (var i = 0; i < cards.length; i++) {\n      var h = cards[i].querySelector('h3');\n      if (!h) continue;\n      if (h.textContent.trim() !== searchText) continue;\n      var a = document.createElement('div');\n      a.id = id;\n      a.style.cssText = 'position:relative;height:0;overflow:hidden;';\n      cards[i].parentElement.insertBefore(a, cards[i]);\n      return;\n    }\n  }\n  function run() {\n    addAnchor('yle-starters', 'Starters 1');\n    addAnchor('yle-movers', 'Movers 1');\n    addAnchor('yle-flyers', 'Flyers 1');\n  }\n  if (document.readyState === 'complete') { run(); }\n  else { window.addEventListener('load', run); }\n  setTimeout(run, 200);\n  setTimeout(run, 800);\n})();\n<\/script>","protected":false},"excerpt":{"rendered":"<p>\ufeff Cambridge English \u00b7 Official Test Series Practice Cambridge the right way A complete Cambridge pathway \u2014 from YLE (Starters, Movers, Flyers) to KET and PET. Authentic audio, detailed answer keys, and interactive online exercises. Start with KET 2 \u2014 free See the learning path 30+ Books available 160+ Full tests Pre-A1\u2192B1 CEFR levels Pre-A1 [&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-977","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/977","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=977"}],"version-history":[{"count":157,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/977\/revisions"}],"predecessor-version":[{"id":6026,"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/pages\/977\/revisions\/6026"}],"wp:attachment":[{"href":"https:\/\/allenglish4u.com\/vi\/wp-json\/wp\/v2\/media?parent=977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}