/* ==========================================================================
   IELTS Mentor AI — Landing Page Stylesheet
   Plain CSS, mobile-first, no framework, no build step.
   Table of contents:
     1. Design tokens / reset
     2. Base typography
     3. Layout helpers
     4. Store badges
     5. Navbar (v3)
     6. Page headers (about / contact / 404 / calculator)
     7. Key insights + contact cards
     8. Feature cards (about page)
     12. FAQ accordion
     13. CTA (dark)
     14. Footer (v3)
     15. Legal pages (privacy / terms)
     16. Voice waveform (AI Listens to Every Word)
     17. Scroll reveal
     18. Responsive breakpoints
     19. Blog (index + post)
     20. Band score calculator
     21. Cue-card library
     22. Practice mode
     23. Band answers
     25. System v3 components
     26. Homepage v3
     27. Self-assessment
     28. Vocabulary
     29. Band descriptors
     31. Study plan
     32. Word stress trainer
     33. Essay checker
     34. Writing descriptors
     35. Questions and mock test
     36. Tools hub
     37. Guides
     38. Language switcher
     39. Answers
   (Numbers are historical and have gaps — 9-11, 24 and 30 were never used.
   Nothing is renumbered when a section is added; a new section takes the
   next free number and is appended here.)
   ========================================================================== */

/* -------------------------------------------------------------------------
   1. Design tokens / reset
   ------------------------------------------------------------------------- */
:root {
  /* ---- Ink: cool near-black, never pure black ------------------------- */
  --ink: #16181d;
  --ink-2: #4b5160;
  --ink-3: #6b7280;

  /* ---- Ground: white plus two very light, blue-leaning tints ---------- */
  --ground: #ffffff;
  --ground-2: #f6f7fa;
  --ground-3: #eef2fb;
  --line: #e6e8ee;
  --line-2: #d9dde8;

  /* ---- Brand: one blue. Spent on ONE gradient panel (the hero stage),
     text links, tab highlights and small chips — nowhere else. --------- */
  --brand: #2862ef;
  --brand-deep: #1b48c8;
  --brand-ink: #0d2a75;
  --brand-tint: #e6eeff;

  /* ---- Criterion / status colours, shared with the answer annotations
     in section 23 so a chip and a highlight always agree. -------------- */
  --ok: #1e7a4f;
  --ok-tint: #e3f4ea;
  --warn: #b45309;
  --warn-tint: #fff3e0;
  --err: #c2410c;
  --err-tint: #fdeae2;
  --violet: #6b3fd6;
  --violet-tint: #efe9ff;

  /* ---- Type ------------------------------------------------------------
     One grotesk family in two optical sizes: Inter Tight 600 for display
     (h1/h2/h3 and every big numeral), Inter 400/500/600 for body and UI. */
  --font-display: 'Inter Tight', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-body: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  /* ---- Radii ---------------------------------------------------------- */
  --r-panel: 28px;
  --r-card: 20px;
  --r-btn: 14px;
  --r-input: 12px;
  --r-chip: 999px;

  /* ---- Measure and rhythm --------------------------------------------- */
  --shell: 1440px;
  --container: 1200px;
  --gutter: 24px;
  --rhythm: 120px;
  --rhythm-sm: 72px;

  --shadow-device: 0 40px 90px rgba(13, 42, 117, 0.28), 0 8px 24px rgba(13, 42, 117, 0.18);
  --shadow-card: 0 1px 2px rgba(22, 24, 29, 0.04), 0 12px 32px rgba(22, 24, 29, 0.06);

  /* ---- Aliases ---------------------------------------------------------
     Every custom property the pre-v3 rules (sections 3-24: blog, cue
     cards, practice mode, band answers, the calculator and the legal
     pages) were written against, re-pointed at the tokens above. Those
     sections inherit the new system without being rewritten line by line;
     nothing below this block should introduce a new alias. */
  --primary-color: var(--brand);
  --secondary-color: #86baff;
  --neutral-01: var(--ground);
  --neutral-02: var(--ground-2);
  --neutral-03: var(--ink-2);
  --neutral-04: var(--ink);
  --stroke: var(--line);
  --font-family: var(--font-body);
  --radius-sm: var(--r-input);
  --radius-md: var(--r-card);
  --radius-lg: var(--r-panel);
  --container-width: var(--container);
  --section-padding-y: var(--rhythm);
  --section-padding-x: var(--gutter);
  --navbar-height: 68px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--ink-2);
  background-color: var(--ground);
  font-size: 17px;
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

button {
  font-family: inherit;
  cursor: pointer;
}

p {
  margin: 0;
}

/* One focus treatment for the whole site. Anything that opts out (the
   practice countdown, which is focused only to announce itself) does so
   explicitly beside its own rules. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}

/* -------------------------------------------------------------------------
   2. Base typography
   -------------------------------------------------------------------------
   Display metrics are tight and optical: h1 sits at 0.98 line-height with
   -3.5% tracking, h2 at 1.04 / -2.5%, so a two-line headline reads as one
   shape. Body copy stays on Inter at 400. */
h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--ink);
  font-weight: 600;
  line-height: 1.15;
}

h1, h2, h3,
.h1, .h2, .h3 {
  font-family: var(--font-display);
  text-wrap: balance;
}

h1, .h1 {
  font-size: clamp(46px, 6.4vw, 84px);
  line-height: 0.98;
  letter-spacing: -0.035em;
}

h2, .h2 {
  font-size: clamp(32px, 3.8vw, 52px);
  line-height: 1.04;
  letter-spacing: -0.025em;
}

h3, .h3 {
  font-size: clamp(20px, 1.6vw, 24px);
  line-height: 1.2;
  letter-spacing: -0.015em;
}

h4, h5, h6 {
  font-family: var(--font-body);
  letter-spacing: -0.01em;
}

/* Eyebrow: the small uppercase label above a heading. Brand blue on light
   panels; the on-dark variant lives with .panel-dark in section 25. */
h5, .h5, .eyebrow {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand);
  line-height: 1.4;
}

/* Lede under a heading: shorter measure than body prose. */
.section-sub {
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 60ch;
}

.accent {
  color: var(--brand);
}

/* Any numeral shown as data (band scores, step numbers, percentages) takes
   the display face and tabular figures so columns of them line up. */
.num {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* ---- Page-level heading sizes ------------------------------------------
   The global h1/h2 clamps above are tuned for the homepage's display type.
   Document-shaped pages (legal, blog post, blog/cue-card index) step them
   back down to a reading scale rather than inheriting a 84px headline. */
.legal-content h1 {
  font-size: clamp(34px, 4vw, 48px);
  line-height: 1.05;
}

.blog-index-intro h1 {
  font-size: clamp(36px, 4.4vw, 56px);
  line-height: 1.02;
}

/* -------------------------------------------------------------------------
   3. Layout helpers
   ------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container-width);
  margin-inline: auto;
  padding-inline: var(--section-padding-x);
}

/* Vertical rhythm: 72px on a phone, 120px from small desktop up (see the
   1024px breakpoint in section 18). */
section {
  padding-block: var(--rhythm-sm);
}

/* Section head: left-aligned by default in v3 (owner.com never centres a
   section heading); .section-head-center opts back in. */
.section-head {
  max-width: 42ch;
  margin-bottom: 48px;
}

.section-head-center {
  margin-inline: auto;
  text-align: center;
  max-width: 46ch;
}

.section-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.section-head h1,
.section-head h2 {
  margin-bottom: 18px;
}

.section-head .section-sub {
  max-width: 60ch;
}

.section-head-center .section-sub {
  margin-inline: auto;
}

/* Card: white, hairline, no shadow. .card-lift adds one on hover-capable
   surfaces; cards in a row share their height through the grid. */
.card {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 28px;
}

/* The icon set is drawn in brand-blue strokes on a brand-tint tile, so an
   icon reads the same wherever a card puts it. (The SVGs shipped white,
   which was invisible on a light card — they are recoloured at source.) */
.card-icon {
  width: 44px;
  height: 44px;
  padding: 11px;
  margin-bottom: 20px;
  border-radius: 12px;
  background: var(--brand-tint);
}

.card h3 {
  margin: 4px 0 8px;
}

.card p {
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.5;
}

/* -------------------------------------------------------------------------
   4. Store badges
   -------------------------------------------------------------------------
   Always a pair, equal height, 12px apart. Buttons (.btn) live in 25. */
.store-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.store-badges img {
  height: 44px;
  width: auto;
}

@media (min-width: 768px) {
  .store-badges img {
    height: 52px;
  }
}

/* The footer and the mobile nav sheet stack them, where 52px reads heavy. */
.footer-download .store-badges img,
.nav-panel .store-badges img {
  height: 44px;
}

/* -------------------------------------------------------------------------
   5. Navbar (v3)
   -------------------------------------------------------------------------
   Sticky, translucent, one hairline. Logo left, links centred, a single
   dark pill right. Below 1024px the links collapse into a full-height
   sheet driven by the same navToggle / navPanel / is-open contract the
   pre-v3 markup used, so the inline menu script is unchanged. */
.navbar {
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 1px solid var(--line);
}

/* The translucent ground is painted by a pseudo-element rather than by
   .navbar itself: backdrop-filter on an element makes it the containing
   block for its position:fixed descendants, which would trap the mobile
   sheet (#navPanel) inside the 68px-tall bar. */
.navbar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
}

.navbar .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: var(--navbar-height);
  padding-block: 0;
}

.navbar-logo {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

.navbar-logo img {
  height: 30px;
  width: auto;
}

.navbar-links {
  display: flex;
  gap: 30px;
  align-items: center;
}

.navbar-links a {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  transition: color 0.15s ease;
}

.navbar-links a:hover,
.navbar-links a[aria-current="page"] {
  color: var(--ink);
}

.navbar-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

.nav-toggle {
  display: none;
  background: none;
  border: none;
  padding: 8px;
  margin-right: -8px;
  line-height: 0;
}

.nav-toggle img {
  width: 24px;
  height: 24px;
}

.nav-panel {
  display: none;
}

/* ---- Mobile sheet (below 1024px) --------------------------------------- */
@media (max-width: 1023px) {
  .navbar-links {
    display: none;
  }

  .navbar-actions .btn {
    display: none;
  }

  .nav-toggle {
    display: inline-flex;
    align-items: center;
  }

  .nav-panel {
    position: fixed;
    inset: var(--navbar-height) 0 0;
    background: var(--ground);
    padding: 28px var(--gutter) 40px;
    overflow-y: auto;
    z-index: 99;
  }

  .nav-panel.is-open {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .nav-panel a {
    display: block;
    width: 100%;
    padding-block: 14px;
    border-bottom: 1px solid var(--line);
    font-family: var(--font-display);
    font-size: 22px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--ink);
  }

  .nav-panel .btn {
    margin-top: 24px;
    width: 100%;
    padding-block: 16px;
    border-bottom: none;
    font-family: var(--font-body);
    font-size: 15px;
    color: #fff;
  }

  .nav-panel .store-badges {
    margin-top: 20px;
  }

  .nav-panel .store-badges a {
    width: auto;
    padding-block: 0;
    border-bottom: none;
  }
}

/* -------------------------------------------------------------------------
   6. Page headers (about / contact / 404 / calculator)
   -------------------------------------------------------------------------
   The homepage has its own hero (section 26). `.hero` is what every other
   hand-written page uses for its opening block: eyebrow, h1, lede. */
.hero {
  padding-block: 72px 40px;
  text-align: left;
}

.hero .eyebrow {
  display: block;
  margin-bottom: 18px;
}

.hero h1 {
  font-size: clamp(40px, 5vw, 66px);
  max-width: 16ch;
  margin-bottom: 22px;
}

.hero-sub {
  font-size: 19px;
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 58ch;
}

.hero-sub.hero-sub-wide {
  max-width: 68ch;
}

/* The "Practice only what YOU need to improve." line — a lead-in above a
   heading rather than a paragraph of body copy. */
.ai-callout-line {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}

/* -------------------------------------------------------------------------
   7. Key insights + contact cards
   ------------------------------------------------------------------------- */
.key-insights {
  background: var(--ground-2);
}

.key-insights .eyebrow,
.key-insights h2 {
  text-align: left;
}

.key-insights-text h2 {
  margin-bottom: 16px;
}

.key-insights-text p {
  margin-bottom: 28px;
}

.insight-cards {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.insight-cards .card {
  background: var(--ground);
}

.insight-cards .eyebrow {
  display: block;
  margin-bottom: 8px;
}

/* Contact page: two clickable contact cards (email / Instagram) */
.contact-cards {
  flex-direction: column;
}

.contact-card {
  display: block;
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.contact-card:hover,
.contact-card:focus-visible {
  border-color: var(--line-2);
  transform: translateY(-2px);
}

.contact-card h2,
.contact-card h3 {
  margin: 4px 0 8px;
  word-break: break-word;
}

/* -------------------------------------------------------------------------
   8. Feature cards (about page)
   ------------------------------------------------------------------------- */
.feature-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  margin-bottom: 32px;
}

.feature-cards + .section-sub {
  margin-top: 0;
}

.feature-card {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 28px;
}

.feature-card .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.feature-card h2,
.feature-card h3 {
  margin-bottom: 10px;
}

.feature-card p {
  color: var(--ink-2);
  font-size: 16px;
}

.feature-card img.feature-illustration {
  border-radius: var(--r-card);
  margin-inline: auto;
}

/* -------------------------------------------------------------------------
   12. FAQ accordion
   -------------------------------------------------------------------------
   Hairline dividers rather than boxes; the marker is a 28px circle that
   swaps plus for minus when the item is open. */
.faq-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}

.faq-intro h2 {
  margin-bottom: 16px;
}

.faq-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
}

.faq-item {
  border-bottom: 1px solid var(--line);
  background: none;
}

.faq-item summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 0;
  cursor: pointer;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

/* plus.svg / minus.svg already draw the circle, so the marker just needs
   sizing — an extra tinted disc behind it reads as two rings. */
.faq-item .faq-icon {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
}

.faq-item .icon-minus {
  display: none;
}

.faq-item[open] .icon-plus {
  display: none;
}

.faq-item[open] .icon-minus {
  display: block;
}

.faq-item[open] summary {
  padding-bottom: 10px;
}

.faq-answer {
  padding: 0 52px 24px 0;
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1.6;
  max-width: 72ch;
}

/* -------------------------------------------------------------------------
   13. CTA (dark)
   -------------------------------------------------------------------------
   One ink panel, reused by every generated page (blog post, blog index,
   cue-card page and hub) and by the hand-written pages. The homepage's own
   closing CTA is the same panel — see .panel-dark in section 25. */
.cta-section {
  background: var(--ink);
  border-radius: var(--r-panel);
  margin-inline: var(--gutter);
  overflow: hidden;
}

.cta-section .container {
  max-width: var(--container);
}

.cta-inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: center;
  padding-block: 56px;
}

.cta-text .eyebrow {
  color: rgba(255, 255, 255, 0.75);
  display: block;
  margin-bottom: 16px;
}

.cta-text h2 {
  color: var(--ground);
  margin-bottom: 16px;
}

.cta-text p {
  color: rgba(255, 255, 255, 0.72);
  margin-bottom: 28px;
  font-size: 17px;
  max-width: 54ch;
}

.cta-text .ai-callout-line {
  color: var(--ground);
  margin-bottom: 14px;
}

.cta-actions {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.cta-image img {
  margin-inline: auto;
  max-width: 320px;
  border-radius: var(--r-card);
}

/* The generated CTA blocks sit inside a prose column, so their heading
   steps down from the page-level h2 clamp. */
.post-cta .cta-text h2,
.blog-cta .cta-text h2,
.calc-cta .cta-text h2 {
  font-size: clamp(26px, 3vw, 34px);
}

/* -------------------------------------------------------------------------
   14. Footer (v3)
   ------------------------------------------------------------------------- */
.site-footer {
  padding-top: 80px;
  margin-top: 40px;
  border-top: 1px solid var(--line);
  background: var(--ground);
}

/* The brand block is its own full-width row above the columns: with five link
   columns there is no room left for it inside the grid. */
.footer-brand {
  padding-bottom: 48px;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px 24px;
}

.footer-brand > img {
  height: 30px;
  width: auto;
  margin-bottom: 18px;
}

.footer-brand p {
  max-width: 44ch;
  margin-bottom: 20px;
  font-size: 15px;
  color: var(--ink-2);
}

/* Phones: two columns, but the download block keeps the store badges at their
   natural 140px width, so it takes the full row under them. */
.footer-download {
  grid-column: 1 / -1;
}

.footer-social-row {
  display: flex;
  gap: 10px;
}

.footer-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  transition: border-color 0.2s ease;
}

.footer-social:hover {
  border-color: var(--ink);
}

.footer-social img {
  width: 18px;
  height: 18px;
}

.footer-heading {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
  margin-bottom: 18px;
}

.footer-col ul {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.footer-col a {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
}

.footer-col a:hover,
.footer-col a[aria-current="page"] {
  color: var(--ink);
}

.footer-download p {
  font-size: 14px;
  margin-bottom: 16px;
  color: var(--ink-2);
}

.footer-download .store-badges {
  flex-direction: column;
  align-items: flex-start;
}

.footer-bottom {
  margin-top: 64px;
  padding-block: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-3);
}

.footer-disclaimer {
  max-width: 90ch;
}

/* -------------------------------------------------------------------------
   15. Legal pages (privacy / terms)
   ------------------------------------------------------------------------- */
.legal-page {
  padding-block: 64px;
}

.legal-content {
  max-width: 720px;
  margin-inline: auto;
}

.legal-content h1 {
  margin-bottom: 8px;
}

.legal-content .legal-updated {
  color: var(--neutral-03);
  font-size: 14px;
  margin-bottom: 40px;
  display: block;
}

.legal-content h2 {
  font-size: 22px;
  margin-top: 40px;
  margin-bottom: 12px;
}

.legal-content p {
  margin-bottom: 16px;
}

.legal-content ul {
  margin-bottom: 16px;
  padding-left: 20px;
  list-style: disc;
}

.legal-content li {
  margin-bottom: 8px;
}

.legal-content a {
  color: var(--primary-color);
  text-decoration: underline;
}

/* -------------------------------------------------------------------------
   16. Voice waveform (AI Listens to Every Word)
   ------------------------------------------------------------------------- */
.waveform-panel {
  position: relative;
  background: var(--neutral-01);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  padding: 28px 20px 20px;
  overflow: hidden;
}

.waveform-mic {
  position: relative;
  width: 40px;
  height: 40px;
  margin: 0 auto 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-color);
  color: var(--neutral-01);
  border-radius: 50%;
}

.waveform-mic svg {
  position: relative;
  z-index: 1;
  display: block;
}

.waveform-mic-pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--primary-color);
  opacity: 0.5;
  animation: mic-pulse 2s ease-out infinite;
}

@keyframes mic-pulse {
  0% {
    transform: scale(1);
    opacity: 0.45;
  }
  100% {
    transform: scale(2.1);
    opacity: 0;
  }
}

.waveform-bars {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
  height: 72px;
  margin-bottom: 24px;
  padding: 0 4px;
}

.waveform-bars span {
  flex: 1 1 auto;
  max-width: 6px;
  height: 100%;
  border-radius: 3px;
  background: var(--primary-color);
  opacity: 0.75;
  transform-origin: center bottom;
  transform: scaleY(var(--h, 0.4));
  animation: wave-bar 1.1s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}

@keyframes wave-bar {
  0%,
  100% {
    transform: scaleY(var(--h, 0.4));
    opacity: 0.55;
  }
  50% {
    transform: scaleY(1);
    opacity: 1;
  }
}

.waveform-criteria {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.criteria-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--neutral-02);
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
  color: var(--neutral-04);
}

.criteria-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--primary-color);
  flex-shrink: 0;
  animation: criteria-blink 1.6s ease-in-out infinite;
}

.criteria-chip:nth-child(2) .criteria-dot {
  animation-delay: 0.15s;
}

.criteria-chip:nth-child(3) .criteria-dot {
  animation-delay: 0.3s;
}

.criteria-chip:nth-child(4) .criteria-dot {
  animation-delay: 0.45s;
}

@keyframes criteria-blink {
  0%,
  100% {
    opacity: 0.35;
    transform: scale(0.85);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Respect reduced motion: freeze everything at varied static heights/positions
   so it still reads as a waveform, just not moving. */
@media (prefers-reduced-motion: reduce) {
  .waveform-mic-pulse {
    animation: none;
    opacity: 0.2;
  }

  .waveform-bars span {
    animation: none;
    transform: scaleY(var(--h, 0.6));
    opacity: 0.85;
  }

  .criteria-dot {
    animation: none;
    opacity: 1;
  }
}

/* -------------------------------------------------------------------------
   17. Scroll reveal
   ------------------------------------------------------------------------- */
/* Default: fully visible. Only hidden once JS confirms it can reveal them
   (html.js-reveal), so a no-JS visitor always sees complete content. */
.reveal {
  opacity: 1;
  transform: none;
}

.js-reveal .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.js-reveal .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .js-reveal .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* -------------------------------------------------------------------------
   18. Responsive breakpoints
   -------------------------------------------------------------------------
   Only the shared page chrome lives here. The homepage's own breakpoints
   travel with their component, in sections 25 and 26. */

/* ~768px — tablets up: two-column grids kick in */
@media (min-width: 768px) {
  .feature-cards {
    grid-template-columns: 1fr 1fr;
  }

  .contact-cards {
    flex-direction: row;
  }

  .contact-cards .card {
    flex: 1 1 0;
  }

  .footer-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .footer-download {
    grid-column: auto;
  }

  .faq-grid {
    grid-template-columns: 0.85fr 1.15fr;
    gap: 56px;
  }

  .cta-inner {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

/* ~1024px — small desktop up */
@media (min-width: 1024px) {
  :root {
    --gutter: 40px;
  }

  .navbar-links {
    display: flex;
  }

  /* Four link columns plus Download. The link columns are equal; Download is
     a little wider because the store badges are a fixed 140px. */
  .footer-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr)) 1.1fr;
    gap: 40px;
  }

  section {
    padding-block: var(--rhythm);
  }
}

/* -------------------------------------------------------------------------
   19. Blog (index + post)
   ------------------------------------------------------------------------- */
.breadcrumbs {
  font-size: 12px;
  color: var(--neutral-03);
  opacity: 0.8;
  margin-bottom: 20px;
}

.breadcrumbs a {
  color: var(--neutral-03);
}

.breadcrumbs a:hover {
  color: var(--primary-color);
}

.breadcrumbs span[aria-current] {
  color: var(--neutral-04);
}

.breadcrumbs .crumb-sep {
  margin-inline: 6px;
}

.post-page,
.blog-index-page {
  padding-block: 64px;
}

/* Post prose column (matches the legal pages below 1024px; becomes a
   prose + sticky-TOC grid at 1024px and up — see the media query below). */
.post-content {
  max-width: 720px;
  margin-inline: auto;
}

.blog-index-content {
  max-width: 960px;
  margin-inline: auto;
}

/* Shared small uppercase pill: post tags on the eyebrow row and index
   cards. The sample-answer badge below reuses the same shape with a
   darker, neutral fill instead of the blue tint. */
.tag-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tag-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--brand-deep);
  background: var(--brand-tint);
  white-space: nowrap;
}

/* ---- Post header -------------------------------------------------------- */
.post-eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}

.post-eyebrow-meta {
  font-size: 13px;
  color: var(--neutral-03);
}

.post-header h1 {
  font-size: clamp(2rem, 4.5vw, 3rem);
  line-height: 1.1;
  text-wrap: balance;
  margin-bottom: 14px;
}

.post-byline {
  color: var(--neutral-03);
  font-size: 14px;
  margin-bottom: 32px;
}

/* ---- Table of contents ---------------------------------------------------
   Two renderings of the same TOC markup: a closed <details> for <1024px
   (so the first paragraph is visible immediately, no JS required) and a
   sticky sidebar for >=1024px. Only one is in the DOM's visible flow at a
   given width — see the responsive rules at the end of this section. */
.post-toc-mobile {
  background: var(--neutral-02);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  padding: 14px 20px;
  margin-bottom: 32px;
  font-size: 14px;
}

.post-toc-mobile summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--neutral-04);
  list-style: none;
}

.post-toc-mobile summary::-webkit-details-marker {
  display: none;
}

.post-toc-mobile[open] summary {
  margin-bottom: 12px;
}

.post-toc-sidebar {
  display: none;
}

.post-toc-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--neutral-04);
  margin: 0 0 14px;
}

.post-toc-mobile-nav ul,
.post-toc-nav ul {
  list-style: none;
  margin: 0;
  padding-left: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.post-toc-mobile-nav ul ul,
.post-toc-nav ul ul {
  padding-left: 16px;
  margin-top: 10px;
}

.post-toc-mobile-nav a,
.post-toc-nav a {
  display: block;
  color: var(--neutral-03);
  font-size: 14px;
  line-height: 1.4;
}

.post-toc-mobile-nav a:hover {
  color: var(--primary-color);
}

.post-toc-nav a {
  padding-left: 12px;
  border-left: 2px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.post-toc-nav a:hover {
  color: var(--neutral-04);
}

.post-toc-nav a.is-active {
  color: var(--primary-color);
  border-left-color: var(--primary-color);
  font-weight: 600;
}

/* ---- Body rhythm ---------------------------------------------------------*/
.post-body {
  font-size: 17px;
  line-height: 1.7;
  color: var(--neutral-03);
  max-width: 68ch;
}

.post-body > *:first-child {
  margin-top: 0;
}

.post-body p {
  margin-bottom: 20px;
}

.post-body h2 {
  font-size: 26px;
  margin-top: 48px;
  margin-bottom: 12px;
}

.post-body h3 {
  font-size: 20px;
  margin-top: 32px;
  margin-bottom: 8px;
}

/* The callout already ends with its own bottom margin — don't double it up
   when an h2 immediately follows one. */
.post-body .callout + h2 {
  margin-top: 24px;
}

.post-body ul,
.post-body ol {
  margin: 0 0 20px;
  padding-left: 22px;
}

.post-body ul {
  list-style: disc;
}

.post-body ol {
  list-style: decimal;
}

.post-body li {
  margin-bottom: 8px;
}

.post-body a {
  color: var(--primary-color);
  text-decoration: underline;
}

.post-body strong {
  color: var(--neutral-04);
}

/* ---- Sample-answer blockquotes: card treatment + pill badge -------------*/
.post-body blockquote {
  margin: 28px 0;
  padding: 24px 28px;
  background: var(--neutral-02);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  color: var(--neutral-03);
  font-style: normal;
  font-size: 17px;
}

.post-body blockquote p:last-child {
  margin-bottom: 0;
}

/* Matches the front matter convention "> **Band 8 sample answer:** ..." —
   turns the leading bold lead-in into a pill badge, CSS-only. */
.post-body blockquote > p:first-child > strong:first-child {
  display: inline-block;
  padding: 4px 10px;
  margin-bottom: 12px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--neutral-01);
  background: var(--neutral-04);
}

.post-body code {
  background: var(--neutral-02);
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 0.9em;
}

.post-body pre {
  background: var(--neutral-02);
  border-radius: var(--radius-sm);
  padding: 16px 20px;
  overflow-x: auto;
  margin-bottom: 20px;
}

.post-body pre code {
  background: none;
  padding: 0;
}

.post-body img {
  border-radius: var(--radius-md);
  margin-block: 24px;
}

.post-body hr {
  border: none;
  border-top: 1px solid var(--stroke);
  margin: 40px 0;
}

/* ---- "Key takeaways" callout ---------------------------------------------*/
.callout {
  background: var(--ground-3);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius-md);
  padding: 22px 26px;
  margin: 28px 0;
}

.callout > *:last-child {
  margin-bottom: 0;
}

.callout > p:first-child {
  margin-bottom: 14px;
}

.callout > p:first-child > strong {
  display: block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--primary-color);
}

.callout p {
  margin-bottom: 12px;
}

.callout ul,
.callout ol {
  margin-bottom: 0;
}

.callout li {
  margin-bottom: 10px;
}

.callout li:last-child {
  margin-bottom: 0;
}

/* ---- Post CTA: reuses the dark .cta-section look, capped to prose width -*/
.post-cta,
.blog-cta {
  margin-block: 64px;
}

.post-cta {
  max-width: 680px;
}

.post-cta .cta-section,
.blog-cta .cta-section {
  margin-inline: 0;
}

.post-cta .cta-inner,
.blog-cta .cta-inner {
  padding-block: 40px;
  padding-inline: 32px;
  grid-template-columns: 1fr;
  text-align: center;
}

.post-cta .store-badges,
.blog-cta .store-badges {
  justify-content: center;
}

/* ---- FAQ ------------------------------------------------------------------*/
.post-faq {
  max-width: 680px;
  margin-top: 48px;
}

.post-faq h2 {
  font-size: 26px;
  margin-top: 0;
  margin-bottom: 12px;
}

/* ---- More from the blog ---------------------------------------------------*/
.post-more {
  margin-top: 56px;
  padding-top: 40px;
  border-top: 1px solid var(--stroke);
  max-width: 680px;
}

.post-more h2 {
  font-size: 22px;
  margin-bottom: 20px;
}

.more-posts-grid {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.more-post-card {
  display: block;
  padding: 20px;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.more-post-card:hover,
.more-post-card:focus-visible {
  border-color: var(--primary-color);
  transform: translateY(-2px);
}

.more-post-card h3 {
  font-size: 17px;
  margin-bottom: 6px;
}

.more-post-card p {
  color: var(--neutral-03);
  font-size: 14px;
  margin-bottom: 6px;
}

.more-post-card .more-post-meta {
  font-size: 13px;
  margin-bottom: 0;
}

/* ---- Blog index: header, featured card, card grid -------------------------*/
.blog-index-intro {
  max-width: 680px;
  margin-bottom: 40px;
}

.blog-index-intro .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.blog-index-intro h1 {
  margin-bottom: 12px;
}

.blog-featured-card {
  display: block;
  padding: 32px;
  margin-bottom: 32px;
  background: linear-gradient(180deg, var(--ground-3), transparent 65%);
  border: 1px solid var(--line);
  border-top: 3px solid var(--brand);
  border-radius: var(--radius-lg);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.blog-featured-card:hover,
.blog-featured-card:focus-visible {
  border-color: var(--primary-color);
  transform: translateY(-2px);
}

.blog-featured-card h2 {
  font-size: 28px;
  margin: 14px 0 10px;
}

.blog-card-desc {
  color: var(--neutral-03);
  margin-bottom: 10px;
}

.blog-card-meta {
  color: var(--neutral-03);
  font-size: 14px;
}

.blog-post-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

.blog-card {
  display: block;
  padding: 24px;
  background: var(--neutral-01);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.blog-card:hover,
.blog-card:focus-visible {
  border-color: var(--primary-color);
  transform: translateY(-2px);
}

.blog-card h2 {
  font-size: 1.25rem;
  margin: 12px 0 8px;
}

.blog-card .blog-card-desc {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.blog-empty {
  color: var(--neutral-03);
}

/* ---- Motion + responsive ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .more-post-card,
  .blog-featured-card,
  .blog-card,
  .post-toc-nav a {
    transition: none;
  }

  .more-post-card:hover,
  .blog-featured-card:hover,
  .blog-card:hover {
    transform: none;
  }
}

/* Tablet up: index cards go 2-up, "more from the blog" goes side by side */
@media (min-width: 768px) {
  .blog-post-grid {
    grid-template-columns: 1fr 1fr;
  }

  .more-posts-grid {
    flex-direction: row;
  }

  .more-post-card {
    flex: 1 1 0;
  }
}

/* Small desktop up: the post TOC becomes a sticky sidebar next to the
   prose column instead of the collapsed mobile <details>. */
@media (min-width: 1024px) {
  .post-content {
    max-width: 1080px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 260px;
    column-gap: 64px;
    align-items: start;
  }

  .post-content > .post-full {
    grid-column: 1 / -1;
  }

  .post-body {
    max-width: 680px;
  }

  .post-toc-mobile {
    display: none;
  }

  .post-toc-sidebar {
    display: block;
    position: sticky;
    top: calc(var(--navbar-height) + 24px);
    align-self: start;
  }
}

/* -------------------------------------------------------------------------
   20. Band score calculator
   ------------------------------------------------------------------------- */
.calc-section {
  padding-top: 32px;
}

.calc-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

.calc-card-wide {
  grid-column: 1 / -1;
}

.calc-card h3 {
  margin-bottom: 4px;
}

.calc-card-note {
  color: var(--neutral-03);
  font-size: 14px;
  margin-bottom: 20px;
}

.calc-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--neutral-04);
  margin-bottom: 8px;
}

.calc-input,
.calc-select {
  width: 100%;
  font-family: inherit;
  font-size: 17px;
  color: var(--neutral-04);
  background: var(--neutral-02);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  min-height: 52px;
  appearance: none;
}

.calc-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23505561'%3E%3Cpath fill-rule='evenodd' d='M5.23 7.21a.75.75 0 011.06.02L10 11.293l3.71-4.06a.75.75 0 111.08 1.04l-4.24 4.65a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z' clip-rule='evenodd'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 18px;
  padding-right: 42px;
}

.calc-input:focus,
.calc-select:focus,
.calc-toggle-btn:focus-visible {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 3px rgba(40, 98, 239, 0.15);
}

.calc-toggle {
  display: flex;
  gap: 8px;
  background: var(--neutral-02);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 4px;
  margin-bottom: 20px;
}

.calc-toggle-btn {
  flex: 1;
  border: none;
  background: transparent;
  border-radius: 8px;
  padding: 12px 10px;
  min-height: 44px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--neutral-03);
  transition: background-color 0.2s ease, color 0.2s ease;
}

.calc-toggle-btn.is-active {
  background: var(--neutral-01);
  color: var(--primary-color);
  box-shadow: var(--shadow-card);
}

.calc-result {
  margin-top: 20px;
  font-size: 16px;
  color: var(--neutral-04);
}

.calc-result strong {
  color: var(--primary-color);
  font-size: 22px;
}

.calc-result-lg {
  font-size: 17px;
}

.calc-result-lg strong {
  font-size: 24px;
}

.calc-hint {
  margin-top: 10px;
  font-size: 14px;
  color: var(--neutral-03);
}

.calc-noscript {
  margin-top: 16px;
  padding: 12px 14px;
  background: var(--ground-3);
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--neutral-03);
}

.calc-overall-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 4px;
}

.calc-target-field {
  margin-bottom: 20px;
}

.calc-target-grid {
  margin-bottom: 4px;
}

/* ---- Share / copy result --------------------------------------------------*/
.calc-share {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 20px;
}

.calc-share-btn {
  flex: 1 1 200px;
  min-height: 48px;
  padding: 12px 18px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--primary-color);
  background: var(--neutral-01);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.calc-share-btn:hover:not(:disabled) {
  border-color: var(--primary-color);
  background: var(--neutral-02);
}

.calc-share-btn:focus-visible {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 3px rgba(40, 98, 239, 0.15);
}

.calc-share-btn:disabled {
  color: var(--neutral-03);
  cursor: not-allowed;
  opacity: 0.6;
}

.calc-copy-status {
  margin-top: 10px;
  min-height: 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--primary-color);
}

/* ---- Conversion tables ---------------------------------------------------*/
.calc-table-block {
  margin-bottom: 32px;
}

.calc-table-block h3 {
  margin-bottom: 16px;
}

.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  -webkit-overflow-scrolling: touch;
}

.table-scroll table {
  width: 100%;
  border-collapse: collapse;
  min-width: 360px;
  font-size: 15px;
}

.table-scroll th,
.table-scroll td {
  text-align: left;
  padding: 12px 20px;
  border-bottom: 1px solid var(--stroke);
  white-space: nowrap;
}

.table-scroll thead th {
  background: var(--neutral-02);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--neutral-03);
}

.table-scroll tbody tr:last-child td {
  border-bottom: none;
}

.table-scroll tbody td:last-child {
  font-weight: 600;
  color: var(--primary-color);
}

/* ---- Speaking & Writing CTA: single centered column, no phone image ----- */
.calc-cta .cta-inner {
  grid-template-columns: 1fr;
  text-align: center;
}

.calc-cta .cta-text {
  max-width: 720px;
  margin-inline: auto;
}

.calc-cta .store-badges {
  justify-content: center;
}

/* ---- Responsive ---------------------------------------------------------*/
@media (min-width: 640px) {
  .calc-overall-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (min-width: 768px) {
  .calc-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* -------------------------------------------------------------------------
   21. Cue-card library
   ------------------------------------------------------------------------- */
.cue-card-box {
  position: relative;
  margin: 24px 0 28px;
  padding: 24px 24px 20px;
  background: var(--neutral-01);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-lg);
}

.cue-card-label {
  display: inline-block;
  margin-bottom: 14px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--brand-deep);
  background: var(--brand-tint);
}

.cue-card-title {
  font-size: 19px;
  font-weight: 700;
  color: var(--neutral-04);
  margin-bottom: 14px;
}

.cue-card-should-say {
  font-size: 14px;
  font-weight: 600;
  color: var(--neutral-03);
  margin-bottom: 8px;
}

.cue-card-bullets {
  margin: 0 0 14px;
  padding-left: 22px;
  list-style: disc;
}

.cue-card-bullets li {
  margin-bottom: 6px;
  color: var(--neutral-03);
}

.cue-card-explain {
  margin: 0;
  color: var(--neutral-03);
  font-style: italic;
}

/* ---- Part 3 section ------------------------------------------------------*/
.cue-card-part3 {
  margin-top: 48px;
}

.cue-card-part3 h2 {
  font-size: 26px;
  margin-bottom: 12px;
}

.cue-card-part3-list {
  margin: 20px 0 0;
  padding-left: 22px;
  color: var(--neutral-03);
  font-size: 17px;
  line-height: 1.7;
}

.cue-card-part3-list li {
  margin-bottom: 12px;
}

/* ---- Vocabulary tables in the post body ----------------------------------
   build.py wraps every rendered <table> in .table-scroll (the same
   container the calculator page uses), which handles the horizontal-scroll
   fallback. These rules make the table itself fit the ~700px prose column
   at desktop widths — full width, auto layout, wrapping cells — so the
   scrollbar from .table-scroll only ever appears on narrow viewports where
   wrapped cells still can't fit three columns (roughly below ~600px). */
.post-body table {
  width: 100%;
  table-layout: auto;
  border-collapse: collapse;
  margin-bottom: 20px;
  font-size: 14px;
}

.post-body th,
.post-body td {
  text-align: left;
  padding: 10px 16px;
  border-bottom: 1px solid var(--stroke);
  white-space: normal;
  vertical-align: top;
}

.post-body thead th {
  background: var(--neutral-02);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--neutral-03);
}

.post-body tbody tr:last-child td {
  border-bottom: none;
}

/* .table-scroll's own tbody td:last-child rule (styled for the calculator's
   band-score column) has higher specificity than a plain .post-body
   override, so neutralise it explicitly here — a vocabulary table's last
   column is example text, not a highlighted result. */
.post-body tbody td:last-child {
  font-weight: inherit;
  color: inherit;
}

/* ---- Hub page: intro "how to use" list -----------------------------------*/
.cue-card-how-list {
  list-style: disc;
  margin: 20px 0 0;
  padding-left: 22px;
  color: var(--neutral-03);
  font-size: 15px;
  line-height: 1.6;
}

.cue-card-how-list li {
  margin-bottom: 8px;
}

/* ---- Hub page: one section per family -------------------------------------*/
.cue-card-family-section {
  margin-bottom: 40px;
}

.cue-card-family-section h2 {
  font-size: 22px;
  margin-bottom: 16px;
}

.cue-card-family-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.mini-card {
  display: block;
  padding: 18px 20px;
  background: var(--neutral-01);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.mini-card:hover,
.mini-card:focus-visible {
  border-color: var(--primary-color);
  transform: translateY(-2px);
}

.mini-card h3 {
  font-size: 16px;
  margin-bottom: 6px;
}

.mini-card p {
  color: var(--neutral-03);
  font-size: 14px;
  margin-bottom: 0;
}

@media (prefers-reduced-motion: reduce) {
  .mini-card {
    transition: none;
  }

  .mini-card:hover {
    transform: none;
  }
}

/* Tablet up: family grid goes 2-up */
@media (min-width: 768px) {
  .cue-card-family-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* -------------------------------------------------------------------------
   22. Practice mode
   ------------------------------------------------------------------------- */
/* Cue-card page: the "Practise this card" panel. Ships `hidden` in the
   markup — practice.js clears that once JS is confirmed running, so a
   no-JS visitor only ever sees .practice-noscript below. */
.practice-panel {
  margin: 0 0 28px;
  padding: 28px 24px 24px;
  background: var(--neutral-01);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  /* The sticky navbar would otherwise cover the top of the panel (and its
     countdown) when practice.js scrolls it into view for ?practice=1. */
  scroll-margin-top: calc(var(--navbar-height) + 16px);
}

.practice-panel h2 {
  font-size: 20px;
  margin-bottom: 8px;
}

.practice-panel h3 {
  font-size: 16px;
  margin-bottom: 8px;
}

.practice-intro {
  color: var(--neutral-03);
  font-size: 14px;
  margin-bottom: 20px;
}

.practice-idle-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
}

/* ---- Buttons -------------------------------------------------------------
   No generic .btn exists elsewhere on the site (CTAs are store badges), so
   practice mode gets its own small button pair, built from the same design
   tokens as everything else. */
.practice-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 22px;
  border-radius: var(--r-btn);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.1;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.practice-btn-primary {
  background: var(--ink);
  color: #fff;
}

.practice-btn-primary:hover,
.practice-btn-primary:focus-visible {
  background: #000;
}

.practice-btn-secondary {
  background: var(--ground);
  color: var(--ink);
  border-color: var(--line-2);
}

.practice-btn-secondary:hover,
.practice-btn-secondary:focus-visible {
  border-color: var(--ink);
}

.practice-btn:focus-visible {
  outline: 2px solid var(--primary-color);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .practice-btn {
    transition: none;
  }
}

.practice-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--neutral-03);
  cursor: pointer;
}

.practice-toggle input {
  width: 16px;
  height: 16px;
  accent-color: var(--primary-color);
}

/* ---- Countdown ------------------------------------------------------------
   Tabular numerals so mm:ss doesn't jitter in width every second. */
.practice-timer {
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.25rem, 9vw, 3.25rem);
  font-weight: 700;
  color: var(--neutral-04);
  line-height: 1;
  margin: 0 0 20px;
}

/* practice.js calls .focus() on this element (it's tabindex="-1", not
   interactive) purely so screen readers announce the countdown starting —
   there's nothing here for a visible focus ring to usefully outline, so
   suppress it. Buttons and the trigger-words input keep their normal
   :focus-visible outline above/below. */
.practice-timer:focus {
  outline: none;
}

.practice-trigger-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--neutral-03);
  margin-bottom: 6px;
}

.practice-trigger-input {
  display: block;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  background: var(--neutral-01);
  color: var(--neutral-04);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
  resize: vertical;
  margin-bottom: 18px;
}

.practice-trigger-input:focus-visible {
  outline: 2px solid var(--primary-color);
  outline-offset: 2px;
  border-color: var(--primary-color);
}

.practice-trigger-display {
  padding: 10px 14px;
  margin-bottom: 16px;
  background: var(--neutral-02);
  border-radius: var(--radius-sm);
  font-size: 14px;
  color: var(--neutral-03);
}

/* ---- Speaking-phase progress bar ------------------------------------------
   Updated in one-second steps from JS either way; the transition just
   smooths those steps, so removing it under reduced motion loses nothing
   but the smoothing. */
.practice-progress {
  height: 6px;
  border-radius: 999px;
  background: var(--stroke);
  overflow: hidden;
  margin-bottom: 20px;
}

.practice-progress-bar {
  height: 100%;
  width: 0%;
  background: var(--primary-color);
  transition: width 1s linear;
}

@media (prefers-reduced-motion: reduce) {
  .practice-progress-bar {
    transition: none;
  }
}

.practice-bullets-reminder {
  margin: 0 0 20px;
  padding-left: 20px;
  list-style: disc;
  color: var(--neutral-03);
  font-size: 14px;
}

.practice-bullets-reminder li {
  margin-bottom: 6px;
}

.practice-record-note {
  font-size: 13px;
  color: var(--neutral-03);
  margin: 0 0 16px;
}

/* ---- Done state ------------------------------------------------------- */
.practice-done-heading {
  font-size: 19px;
  font-weight: 700;
  color: var(--neutral-04);
  margin-bottom: 16px;
}

.practice-audio-wrap {
  margin-bottom: 20px;
}

.practice-audio-wrap audio {
  display: block;
  width: 100%;
  margin-bottom: 8px;
}

.practice-audio-note {
  font-size: 13px;
  color: var(--neutral-03);
}

.practice-cta {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--stroke);
}

.practice-cta p {
  color: var(--neutral-03);
  font-size: 14px;
  margin-bottom: 16px;
}

/* ---- Quiet cross-link to the self-assessment tool ------------------------ */
.practice-sa-link {
  margin-top: 16px;
  font-size: 13px;
}

.practice-sa-link a {
  color: var(--neutral-03);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.practice-sa-link a:hover,
.practice-sa-link a:focus-visible {
  color: var(--primary-color);
}

.practice-share-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}

.practice-share-note {
  font-size: 13px;
  font-weight: 600;
  color: var(--primary-color);
}

.practice-noscript {
  margin: 0 0 28px;
  padding: 16px 20px;
  background: var(--neutral-02);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  color: var(--neutral-03);
  font-size: 14px;
}

/* ---- Hub: "Practise a random card" ---------------------------------------*/
.practice-random-cta {
  margin-top: 24px;
}

.practice-random-note {
  margin-top: 10px;
  font-size: 13px;
  color: var(--neutral-03);
}

/* Tablet up: prep/speaking countdown and the idle controls get a little
   more breathing room once the panel isn't full-bleed on a phone screen. */
@media (min-width: 768px) {
  .practice-panel {
    padding: 32px 32px 28px;
  }
}

/* -------------------------------------------------------------------------
   23. Band answers
   ------------------------------------------------------------------------- */
/* Six cue-card pages carry a "## The same answer at Band 6, 7 and 8"
   section: three sample answers with inline `{{code|text|note}}` markers
   build.py turns into `<mark class="ann ann-<code>">` highlights, and
   band-answers.js turns the section itself into a tab interface. With no
   JS the three answers stack under their own <h3> in source order (plain
   .post-body typography — no rules needed here for that) and the
   highlights below still render; only the legend and tabs are added by JS. */
.band-answers {
  margin: 20px 0 28px;
}

.band-answers h3 {
  font-size: 16px;
  margin-bottom: 10px;
}

.band-panel p:last-child {
  margin-bottom: 0;
}

/* ---- Annotation highlights (mark.ann) -------------------------------------
   A very light tint background plus a coloured underline per criterion —
   the phrase still reads as ordinary body text at a glance, rather than
   looking like a hard-edged badge. */
mark.ann {
  position: relative;
  background: none;
  color: inherit;
  padding: 0 1px;
  border-radius: 3px;
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  cursor: help;
}

mark.ann-lr {
  background: var(--brand-tint);
  text-decoration-color: var(--brand);
}

mark.ann-gra {
  background: var(--ok-tint);
  text-decoration-color: var(--ok);
}

mark.ann-fc {
  background: var(--violet-tint);
  text-decoration-color: var(--violet);
}

mark.ann-err {
  background: var(--warn-tint);
  text-decoration-color: var(--warn);
  text-decoration-style: wavy;
}

mark.ann:focus-visible {
  outline: 2px solid var(--primary-color);
  outline-offset: 2px;
}

/* ---- Tooltip (.ann-note) ---------------------------------------------
   Hidden via visibility/opacity rather than display, so band-answers.js
   can still measure it with getBoundingClientRect() to clamp it inside
   the viewport before it becomes visible. Shown on hover and keyboard
   focus by CSS alone; band-answers.js additionally toggles `.is-open` for
   a touch tap (touch has no :hover) and closes it on tap-elsewhere. */
.ann-note {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  margin-bottom: 8px;
  width: max-content;
  max-width: 260px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--neutral-04);
  color: var(--neutral-01);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  text-decoration: none;
  white-space: normal;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  /* Above the sticky navbar (z-index: 100 — section 5) so a highlighted
     phrase near the top of the viewport doesn't have its tooltip painted
     underneath the nav on scroll. */
  z-index: 200;
}

mark.ann:hover .ann-note,
mark.ann:focus .ann-note,
mark.ann.is-open .ann-note {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .ann-note {
    transition: none;
  }
}

/* ---- Legend row (JS-inserted only) ---------------------------------- */
.band-legend {
  display: flex;
  flex-wrap: wrap;
}

/* The legend pills and the tab strip are styled with the rest of the
   system's chips and segmented control — see section 25. */

/* -------------------------------------------------------------------------
   25. System v3 components
   -------------------------------------------------------------------------
   The shared vocabulary the homepage is assembled from, and that the rest
   of the site borrows piece by piece: shell, panel, button, chip, marquee,
   segmented control, arrow link. Nothing here is homepage-specific — that
   is section 26.
   ------------------------------------------------------------------------- */

/* ---- Shell --------------------------------------------------------------
   Panels are inset rounded blocks, not full-bleed bands: they sit inside a
   1440px shell with the page gutter left visible down both sides. */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--rhythm-sm);
}

@media (min-width: 1024px) {
  .stack {
    gap: var(--rhythm);
  }
}

/* ---- Panel ------------------------------------------------------------- */
.panel {
  position: relative;
  border-radius: var(--r-panel);
  padding: clamp(32px, 5vw, 72px);
  background: var(--ground);
}

.panel-tint {
  background: var(--ground-2);
}

.panel-blue {
  background: var(--ground-3);
}

.panel-dark {
  background: var(--ink);
  color: rgba(255, 255, 255, 0.72);
}

.panel-dark h1,
.panel-dark h2,
.panel-dark h3 {
  color: #fff;
}

.panel-dark .eyebrow {
  color: rgba(255, 255, 255, 0.75);
}

/* The one gradient on the site. */
.panel-gradient {
  background:
    radial-gradient(120% 90% at 12% 0%, rgba(255, 255, 255, 0.28), transparent 55%),
    linear-gradient(135deg, #3470ff 0%, var(--brand-deep) 55%, var(--brand-ink) 100%);
  color: #fff;
}

/* ---- Buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 22px;
  border: 1px solid transparent;
  border-radius: var(--r-btn);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.1;
  white-space: nowrap;
  transition: transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.btn:hover {
  transform: translateY(-1px);
}

.btn-dark {
  background: var(--ink);
  color: #fff;
}

.btn-dark:hover {
  background: #000;
}

.btn-light {
  background: var(--ground);
  border-color: var(--line-2);
  color: var(--ink);
}

.btn-light:hover {
  border-color: var(--ink);
}

.btn-brand {
  background: var(--brand);
  color: #fff;
}

.btn-brand:hover {
  background: var(--brand-deep);
}

.panel-dark .btn-light {
  background: #fff;
  border-color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn:hover {
    transition: none;
    transform: none;
  }
}

/* ---- Card lift ---------------------------------------------------------- */
.card-lift {
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.card-lift:hover,
.card-lift:focus-visible {
  border-color: var(--line-2);
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .card-lift,
  .card-lift:hover {
    transition: none;
    transform: none;
  }
}

/* ---- Chip ----------------------------------------------------------------
   Criterion chips reuse the annotation palette from section 23, so a chip
   and a highlighted phrase always mean the same thing by colour. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: var(--r-chip);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.2;
  white-space: nowrap;
  background: var(--ground-2);
  color: var(--ink);
}

.chip-lr { background: var(--brand-tint); color: var(--brand-deep); }
.chip-gra { background: var(--ok-tint); color: var(--ok); }
.chip-fc { background: var(--violet-tint); color: var(--violet); }
.chip-err { background: var(--warn-tint); color: var(--warn); }
.chip-pron { background: #e8eaf0; color: var(--ink); }

.panel-gradient > .chip,
.panel-dark > .chip,
.panel-gradient > * > .chip,
.panel-dark > * > .chip {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}

/* ...but a chip inside a white floating pill keeps its own tint. */
.hero-chip .chip-lr { background: var(--brand-tint); color: var(--brand-deep); }
.hero-chip .chip-gra { background: var(--ok-tint); color: var(--ok); }
.hero-chip .chip-fc { background: var(--violet-tint); color: var(--violet); }
.hero-chip .chip-err { background: var(--warn-tint); color: var(--warn); }

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

/* ---- Arrow link --------------------------------------------------------- */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--brand);
}

.arrow-link:hover {
  color: var(--brand-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- Caption / fine print ----------------------------------------------- */
.note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-3);
}

.note-right {
  text-align: right;
}

/* ---- Marquee -------------------------------------------------------------
   Two identical copies of the track scroll left by exactly half the track
   width, so the loop is seamless. Pauses on hover and on keyboard focus
   inside it; under reduced motion it becomes a plain scroll strip. */
.marquee {
  position: relative;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee var(--marquee-duration, 48s) linear infinite;
}

/* Two identical groups. The trailing padding is what makes each group's
   width include the gap that follows it, so translateX(-50%) lands the
   second group exactly where the first started. */
.marquee-group {
  display: flex;
  gap: 16px;
  padding-right: 16px;
}

.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track {
  animation-play-state: paused;
}

@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee {
    overflow-x: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .marquee-track {
    animation: none;
  }

  .marquee-group + .marquee-group {
    display: none;
  }
}

/* ---- Segmented control ---------------------------------------------------
   The shape used by the criteria showcase (CSS-only radio tabs, section 26)
   and by the JS-built Band 6/7/8 tabs from band-answers.js. */
.band-tablist {
  display: flex;
  gap: 4px;
  padding: 4px;
  margin-bottom: 20px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
}

.band-tab {
  flex: 1;
  min-width: 0;
  padding: 10px 8px;
  border: none;
  border-radius: 10px;
  background: none;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.band-tab[aria-selected="true"] {
  background: var(--brand-tint);
  color: var(--ink);
}

.band-tab:hover,
.band-tab:focus-visible {
  color: var(--ink);
}

/* Legend pills become chips. */
.band-legend {
  gap: 8px;
  margin-bottom: 18px;
}

.band-legend-pill {
  padding: 6px 10px;
  border-radius: var(--r-chip);
  font-size: 12px;
  font-weight: 600;
}

.band-legend-lr { background: var(--brand-tint); color: var(--brand-deep); }
.band-legend-gra { background: var(--ok-tint); color: var(--ok); }
.band-legend-fc { background: var(--violet-tint); color: var(--violet); }
.band-legend-err { background: var(--warn-tint); color: var(--warn); }

/* ---- Quiz option cards ---------------------------------------------------
   One answer-card shape, shared by the speaking self-assessment (section 27)
   and the vocabulary self-test (section 28): a numbered key, a label, and a
   brand-tinted selected state. Each quiz adds only what is its own — the
   self-test's right/wrong states live in section 28. */
.sa-options,
.vocab-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sa-option,
.vocab-option {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  min-height: 64px;
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}

.sa-option:hover,
.vocab-option:hover {
  border-color: var(--ink-3);
  background: var(--ground-2);
}

.sa-option:focus-visible,
.vocab-option:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.sa-option[aria-checked="true"],
.vocab-option[aria-checked="true"] {
  border-color: var(--brand);
  background: var(--brand-tint);
  box-shadow: inset 0 0 0 1px var(--brand);
}

.sa-option-key,
.vocab-option-key {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: var(--ground-2);
  color: var(--ink-3);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
}

.sa-option[aria-checked="true"] .sa-option-key,
.vocab-option[aria-checked="true"] .vocab-option-key {
  background: var(--brand);
  color: #fff;
}

.sa-option-label,
.vocab-option-label {
  font-size: 16px;
  line-height: 1.45;
  color: var(--ink);
}

@media (min-width: 600px) {
  .sa-options,
  .vocab-options {
    gap: 12px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sa-option,
  .vocab-option {
    transition: none;
  }
}

/* ---- Report card ---------------------------------------------------------
   The HTML rendering of a scored answer, shared by the criteria showcase.
   Same visual language as the hero device screen (section 26). */
.report {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 22px;
}

.report-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.report-head h3 {
  font-size: 17px;
  letter-spacing: -0.015em;
}

.report-score {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 30px;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
}

.report-bar {
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
  margin-bottom: 20px;
}

.report-bar > i {
  display: block;
  height: 100%;
  width: var(--v, 70%);
  border-radius: 999px;
  background: var(--c, var(--brand));
}

.report-flagged {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 10px;
}

.report-rows {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
}

.report-rows li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  color: var(--ink-2);
}

.report-rows b {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

/* ---- Telegram channel strip ------------------------------------------
   A slim cross-promo card for https://t.me/ieltsmentorai: icon, a two-line
   pitch, a "Join the channel" button. render_telegram_strip() places it on
   cue-card pages, questions topic pages, and the cue-cards/questions hubs
   (never the homepage, tools, guides or blog). On a post/questions page it
   also carries .post-full and caps at 680px like its neighbours .post-more
   and .post-cta; on a hub it isn't inside that grid, so it runs the full
   width of .blog-index-content instead. */
.tg-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
  max-width: 680px;
  margin-top: 56px;
  padding: 24px 28px;
  background: var(--brand-tint);
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
}

.blog-index-content .tg-strip {
  max-width: none;
  margin-top: 0;
}

/* On question topic pages the strip is a direct child of .q-content, which
   has no grid/column split — its siblings (the practise panel, the question
   list) run the full ~820px content width, so the 680px default reads narrow
   next to them. (On cue-card/post pages .tg-strip already matches its
   .post-more/.post-faq/.post-cta neighbours, which are separately capped to
   680px to match .post-body — leave that case alone.) Mobile widths are
   already well under 680px, so this is a no-op on phones. */
.q-content .tg-strip {
  max-width: none;
}

.tg-strip-icon {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
}

.tg-strip-text {
  flex: 1 1 260px;
}

.tg-strip-heading {
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 4px;
}

.tg-strip-sub {
  font-size: 14px;
  color: var(--ink-2);
}

.tg-strip-btn {
  flex-shrink: 0;
  white-space: nowrap;
}

/* ---- Glosses ------------------------------------------------------------
   A localised page keeps the exam text in English and puts one short line in
   the reader's own language directly under it (build.py -> render_gloss).
   The gloss is deliberately quiet: it explains the line above, it never
   competes with it. It is emitted as a <span> inside the element it glosses
   (a cue-card bullet, a marquee tile's title) and as a <p> where it stands
   on its own, so `display: block` is what makes both start a new line.
   Logical properties throughout, so a right-to-left locale needs no
   override. Nothing here can reach an English page: the markup only exists
   under a non-default locale. ------------------------------------------- */
.gloss {
  display: block;
  margin-block-start: 2px;
  font-family: var(--font-body);
  font-size: 0.88em;
  font-weight: 400;
  line-height: 1.4;
  font-style: normal;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink-3);
}

/* Inside a heading the gloss inherits a display face and a tight leading it
   should not keep, and on the cue-card box's title it sits under a much
   larger line, so it gets a little more air. */
h1 > .gloss,
h2 > .gloss,
h3 > .gloss,
.cue-card-title > .gloss,
p.gloss {
  margin-block-start: 4px;
}

/* The two tile grids are height-constrained — the marquee strip scrolls at a
   fixed height and the hub's mini-cards sit in a grid — so a long gloss is
   clamped to two lines rather than pushing the tile out of its row. */
.cue-tile .gloss,
.mini-card .gloss,
.q-tile .gloss {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.cue-tile .gloss {
  -webkit-line-clamp: 1;
  font-size: 0.85em;
}

/* -------------------------------------------------------------------------
   26. Homepage v3
   -------------------------------------------------------------------------
   Section-by-section, in page order: hero + device stage, cue-card
   marquee, criteria showcase, band comparison, feature grid + gallery,
   explore tiles, how-it-works steps, FAQ, closing CTA.
   ------------------------------------------------------------------------- */
.home {
  display: block;
}

.home > section {
  padding-block: 0;
  margin-block: var(--rhythm-sm);
}

.home > section:first-child {
  margin-top: 0;
}

@media (min-width: 1024px) {
  .home > section {
    margin-block: var(--rhythm);
  }
}

/* ---- 1. Hero ------------------------------------------------------------ */
.home > .hero-v3 {
  padding-top: clamp(72px, 9vw, 128px);
}

.hero-head {
  max-width: 1000px;
  margin-inline: auto;
  text-align: center;
}

/* Our honest replacement for owner.com's star-rating line: the four
   criteria every answer is actually marked against. */
.hero-criteria {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-bottom: 26px;
}

.hero-criteria-label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink-3);
  margin-right: 4px;
}

.hero-head h1 {
  margin-bottom: 24px;
}

.hero-lede {
  font-size: clamp(17px, 1.5vw, 20px);
  line-height: 1.45;
  color: var(--ink-2);
  max-width: 62ch;
  margin-inline: auto;
}

.hero-lede-2 {
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink-3);
  max-width: 72ch;
  margin: 12px auto 0;
}

.hero-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-top: 34px;
}

.hero-cta .store-badges {
  justify-content: center;
}

/* ---- Hero stage: the one gradient panel on the site --------------------- */
.hero-stage {
  position: relative;
  height: clamp(520px, 46vw, 620px);
  margin-top: 56px;
  overflow: hidden;
  border-radius: var(--r-panel);
}

.hero-caption {
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-3);
  text-align: right;
}

/* Floating annotations over the panel. Decorative, so they're hidden from
   assistive tech and from narrow screens where they'd cover the device. */
.hero-chip {
  position: absolute;
  z-index: 2;
  display: none;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: var(--r-chip);
  background: #fff;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  box-shadow: var(--shadow-card);
  animation: hero-float 7s ease-in-out infinite alternate;
}

.hero-chip-a {
  left: 4%;
  top: 12%;
}

.hero-chip-b {
  right: 4%;
  top: 58%;
  animation-delay: -3.5s;
}

@keyframes hero-float {
  from { transform: translateY(-6px); }
  to { transform: translateY(6px); }
}

@media (min-width: 900px) {
  .hero-chip {
    display: inline-flex;
  }
}

/* ---- Device mockup ------------------------------------------------------ */
.device {
  position: absolute;
  top: 34px;
  left: 50%;
  transform: translateX(-50%);
  width: 280px;
  aspect-ratio: 9 / 19.5;
  border: 10px solid var(--ink);
  border-radius: 48px;
  background: var(--ground-2);
  box-shadow: var(--shadow-device);
  overflow: hidden;
}

@media (min-width: 600px) {
  .device {
    width: 330px;
    top: 40px;
  }
}

@media (min-width: 1024px) {
  .device {
    width: 360px;
    top: 48px;
  }
}

.device-screen {
  height: 100%;
  padding: 16px 14px;
  background: var(--ground-2);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.35;
  text-align: left;
}

.scr-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 8px 10px;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.scr-status-icons {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.scr-status-icons i {
  display: block;
  width: 12px;
  height: 8px;
  border-radius: 2px;
  background: var(--ink);
}

.scr-status-icons i:nth-child(2) { width: 11px; }
.scr-status-icons i:nth-child(3) { width: 18px; }

.scr-topbar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 4px 12px;
}

.scr-back {
  font-size: 20px;
  line-height: 1;
  color: var(--ink-3);
}

.scr-title {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.scr-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px;
  margin-bottom: 10px;
  border-radius: 14px;
  background: var(--ok-tint);
}

.scr-check {
  position: relative;
  flex: 0 0 auto;
  display: inline-block;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--ok);
  color: transparent;
  font-size: 0;
  line-height: 0;
}

.scr-check::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 5px;
  height: 9px;
  border: 2px solid #fff;
  border-top: 0;
  border-left: 0;
  border-radius: 1px;
  transform: translate(-50%, -62%) rotate(45deg);
}

.scr-banner strong {
  display: block;
  font-size: 13px;
  color: var(--ink);
}

.scr-banner span {
  display: block;
  font-size: 11px;
  line-height: 1.35;
  color: var(--ink-2);
}

.scr-card {
  padding: 14px;
  margin-bottom: 10px;
  border-radius: 16px;
  background: #fff;
}

.scr-card h4 {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 12px;
}

.scr-overall {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
}

.scr-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
}

.scr-big {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 44px;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--ok);
}

.scr-range {
  font-size: 12px;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

.scr-range b {
  color: var(--ink);
  font-weight: 600;
}

.scr-bars {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.scr-bars li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 8px;
  align-items: baseline;
}

.scr-bars span {
  font-size: 12px;
  color: var(--ink-2);
}

.scr-bars b {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
  color: var(--c);
}

.scr-bars i {
  grid-column: 1 / -1;
  display: block;
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}

.scr-bars i::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--v);
  border-radius: 999px;
  background: var(--c);
  animation: bar-fill 900ms ease-out 300ms both;
}

.scr-bars li:nth-child(2) i::after { animation-delay: 420ms; }
.scr-bars li:nth-child(3) i::after { animation-delay: 540ms; }
.scr-bars li:nth-child(4) i::after { animation-delay: 660ms; }

@keyframes bar-fill {
  from { width: 0; }
  to { width: var(--v); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-chip {
    animation: none;
  }

  .scr-bars i::after {
    animation: none;
  }
}

/* ---- 2. Cue-card marquee ------------------------------------------------ */
.cards-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  max-width: none;
  margin-bottom: 32px;
}

.cards-head h2 {
  margin-bottom: 0;
}

.cue-tile {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 14px;
  width: 260px;
  min-height: 150px;
  padding: 20px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  transition: border-color 0.2s ease;
}

.cue-tile:hover {
  border-color: var(--line-2);
}

.cue-tile-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
}

/* ---- 3. Criteria showcase ----------------------------------------------- */
#scoring-works {
  scroll-margin-top: calc(var(--navbar-height) + 16px);
}

.showcase {
  margin-top: 40px;
}

.showcase-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.showcase-tablist {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  padding: 6px;
  margin-bottom: 28px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
}

.showcase-tablist label {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 11px 10px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  text-align: center;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.showcase-tablist label:hover {
  color: var(--ink);
}

.showcase-pane {
  display: none;
  gap: 32px;
  align-items: start;
}

#crit-fc:checked ~ .showcase-tablist label[for="crit-fc"],
#crit-lr:checked ~ .showcase-tablist label[for="crit-lr"],
#crit-gra:checked ~ .showcase-tablist label[for="crit-gra"],
#crit-pron:checked ~ .showcase-tablist label[for="crit-pron"] {
  background: var(--brand-tint);
  color: var(--ink);
}

#crit-fc:focus-visible ~ .showcase-tablist label[for="crit-fc"],
#crit-lr:focus-visible ~ .showcase-tablist label[for="crit-lr"],
#crit-gra:focus-visible ~ .showcase-tablist label[for="crit-gra"],
#crit-pron:focus-visible ~ .showcase-tablist label[for="crit-pron"] {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

#crit-fc:checked ~ #pane-fc,
#crit-lr:checked ~ #pane-lr,
#crit-gra:checked ~ #pane-gra,
#crit-pron:checked ~ #pane-pron {
  display: grid;
}

.showcase-copy p {
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1.6;
  margin-bottom: 16px;
  max-width: 56ch;
}

.showcase-copy p:last-child {
  margin-bottom: 0;
}

.showcase-copy strong {
  color: var(--ink);
}

.range-strip {
  margin-top: 36px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 28px;
}

.range-strip h3 {
  margin-bottom: 10px;
}

.range-strip p {
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1.6;
  max-width: 78ch;
}

.range-strip a {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- 4. The same answer at Band 6, 7 and 8 ----------------------------- */
.band-proof .band-answers {
  margin: 28px 0 0;
  padding: 24px;
  background: var(--ground);
  border-radius: var(--r-card);
}

.band-proof .band-answers p {
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1.7;
}

.band-proof .band-answers h3 {
  font-size: 16px;
  margin-bottom: 10px;
}

.band-proof-links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}

/* ---- 5. Everything you need in one app --------------------------------- */
.fact-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin-bottom: 40px;
}

.fact-row .eyebrow {
  display: block;
  margin-bottom: 8px;
}

.fact-row h3 {
  font-size: 19px;
  margin-bottom: 8px;
}

.feature-grid {
  display: block;
}

.feat-card {
  break-inside: avoid;
  margin-bottom: 16px;
}

@media (min-width: 768px) {
  .feature-grid {
    column-count: 2;
    column-gap: 16px;
  }
}

.feat-card .eyebrow {
  display: block;
  margin-bottom: 10px;
}

.feat-card h3 {
  margin-bottom: 10px;
}

.feat-card > p {
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.55;
}

.feat-sub {
  margin-top: 16px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.feat-list {
  margin-top: 14px;
  border-top: 1px solid var(--line);
}

.feat-list li {
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-2);
}

.feat-list li:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

/* The waveform panel, folded into its feature card. */
.feat-card .waveform-panel {
  margin-top: 18px;
  padding: 20px 16px 16px;
}

.feat-card .waveform-bars {
  height: 48px;
  margin-bottom: 16px;
}

/* ---- Screenshot gallery -------------------------------------------------- */
.gallery {
  margin-top: 40px;
}

.gallery-strip {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 12px;
  -webkit-overflow-scrolling: touch;
}

.gallery-strip > figure {
  flex: 0 0 auto;
  width: 300px;
  margin: 0;
  scroll-snap-align: start;
}

.gallery-strip img {
  width: 300px;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.gallery-caption {
  margin-top: 14px;
}

/* ---- 6. Explore ---------------------------------------------------------- */
.explore-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.explore-tile {
  padding: 32px;
  border-radius: var(--r-card);
  background: var(--ground-2);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.explore-tile .eyebrow {
  margin-bottom: 4px;
}

.explore-tile h3 a {
  color: var(--ink);
}

.explore-tile h3 a:hover {
  color: var(--brand);
}

.explore-tile p {
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.55;
  margin-bottom: 4px;
}

.explore-tile p a {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.explore-tile .arrow-link {
  margin-top: auto;
}

/* ---- 7. How it works ----------------------------------------------------- */
#how-it-works {
  scroll-margin-top: calc(var(--navbar-height) + 16px);
}

.how-steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}

.how-step {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 20px;
  border-top: 2px solid var(--line);
}

.how-step-number {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 48px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--brand);
  margin-bottom: 8px;
}

.how-step h3 {
  font-size: 19px;
}

.how-step p {
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.55;
}

/* ---- 8. FAQ -------------------------------------------------------------- */
.home .faq-intro h2 {
  font-size: clamp(30px, 3.2vw, 44px);
}

/* ---- 9. Closing CTA ------------------------------------------------------ */
.cta-v3 {
  text-align: center;
}

.cta-v3 h2 {
  max-width: 16ch;
  margin-inline: auto;
  margin-bottom: 18px;
}

.cta-v3 .ai-callout-line {
  color: #fff;
  margin-bottom: 14px;
}

.cta-v3 > .eyebrow {
  display: block;
  margin-bottom: 16px;
}

.cta-v3 p {
  color: rgba(255, 255, 255, 0.72);
  font-size: 17px;
  line-height: 1.55;
  max-width: 54ch;
  margin-inline: auto;
}

.cta-v3 .store-badges {
  justify-content: center;
  margin-top: 32px;
}

.cta-v3-image {
  max-width: 300px;
  margin: 36px auto 0;
  border-radius: var(--r-card);
}

/* A section head that uses the full panel width: eyebrow + heading left,
   lede right, both sitting on the same baseline. */
@media (min-width: 900px) {
  .section-head-split {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    column-gap: 56px;
    align-items: end;
    max-width: none;
  }

  .section-head-split .eyebrow {
    grid-column: 1;
    grid-row: 1;
  }

  .section-head-split h2 {
    grid-column: 1;
    grid-row: 2;
    margin-bottom: 0;
  }

  .section-head-split .section-sub {
    grid-column: 2;
    grid-row: 2;
    max-width: 52ch;
  }
}

/* ---- Homepage breakpoints ------------------------------------------------ */
@media (min-width: 600px) {
  .fact-row,
  .explore-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 768px) {
  .showcase-tablist {
    grid-template-columns: repeat(4, 1fr);
  }

  .how-steps {
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
  }
}

@media (min-width: 900px) {
  .showcase-pane {
    grid-template-columns: 1fr 0.85fr;
    gap: 48px;
  }
}

@media (min-width: 1024px) {
  .fact-row {
    grid-template-columns: repeat(3, 1fr);
  }

  /* Nine tiles, 3x3. */
  .explore-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .cta-v3-image {
    max-width: 340px;
  }
}

/* The hero's two quiet secondary actions, under the store badges. */
.hero-quiet-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 28px;
}

.hero-scoring-link {
  margin-top: 4px;
  color: var(--ink-2);
}

.hero-scoring-link:hover {
  color: var(--brand);
}

/* -------------------------------------------------------------------------
   27. Self-assessment
   -------------------------------------------------------------------------
   /ielts-speaking-self-assessment — the twelve-question quiz, its result
   view and the share card. Built entirely from the v3 tokens: one white
   card floating in a tinted panel, pill buttons, chips, and the same bar
   language as the homepage hero's report card.
   ------------------------------------------------------------------------- */

/* ---- Page rhythm --------------------------------------------------------- */
.sa-hero {
  padding-block: clamp(56px, 7vw, 96px) 0;
}

/* One centred column, the way the homepage hero is centred: the tool is the
   page, so nothing competes with it for the axis. */
.sa-hero-head {
  max-width: 780px;
  margin-inline: auto;
  text-align: center;
}

.sa-hero-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.sa-hero-head h1 {
  font-size: clamp(40px, 5.4vw, 72px);
}

.sa-hero-sub {
  margin: 20px auto 0;
  max-width: 52ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-2);
}

.sa-quiz-section {
  padding-block: clamp(28px, 4vw, 48px) 0;
}

/* The tinted panel is a frame around the card, not a full-width band. */
.sa-panel {
  max-width: 880px;
  margin-inline: auto;
  padding: clamp(12px, 1.6vw, 24px);
}

/* The quiz itself needs JS; the .js-reveal gate is set by the inline script
   in <head>, so a no-JS visitor gets the <noscript> line and the FAQ only. */
.sa-app {
  display: none;
}

.js-reveal .sa-app {
  display: block;
}

.sa-noscript {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- The card ------------------------------------------------------------ */
.sa-card {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(22px, 3.2vw, 40px);
}

.sa-card[hidden] {
  display: none;
}

.sa-card:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.sa-card > .eyebrow {
  display: block;
  margin-bottom: 12px;
}

/* ---- Intro --------------------------------------------------------------- */
#saIntro h2 {
  font-size: clamp(26px, 2.6vw, 34px);
  line-height: 1.1;
  margin-bottom: 16px;
}

.sa-intro-lede {
  max-width: 60ch;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.sa-intro-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 24px 0 0;
  padding: 20px 0 0;
  border-top: 1px solid var(--line);
}

.sa-intro-list li {
  position: relative;
  padding-left: 20px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.sa-intro-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--brand);
}

.sa-intro-list strong {
  color: var(--ink);
}

.sa-intro-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  margin-top: 28px;
}

.sa-start {
  padding: 16px 26px;
  font-size: 15px;
}

/* ---- Progress ------------------------------------------------------------ */
.sa-progress-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin-bottom: 12px;
}

.sa-step {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.sa-criterion:empty {
  display: none;
}

.sa-progress {
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}

.sa-progress > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--brand);
  transition: width 0.25s ease;
}

@media (prefers-reduced-motion: reduce) {
  .sa-progress > i {
    transition: none;
  }
}

/* ---- Question ------------------------------------------------------------
   The option cards themselves are the shared quiz component in section 25,
   used by this page and by the vocabulary self-test. */
.sa-question {
  margin: 28px 0 22px;
  font-size: clamp(21px, 2.2vw, 29px);
  line-height: 1.18;
  letter-spacing: -0.02em;
  max-width: 30ch;
  text-wrap: balance;
}

.sa-quiz-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

.sa-back {
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
}

.sa-back:hover:not(:disabled) {
  color: var(--brand);
}

.sa-back:disabled {
  color: var(--ink-3);
  opacity: 0.5;
  cursor: default;
}

.sa-keyhint {
  margin: 0;
}

.sa-keyhint kbd {
  display: inline-block;
  min-width: 18px;
  padding: 1px 5px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: var(--ground-2);
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
}

@media (max-width: 599px) {
  .sa-keyhint {
    display: none;
  }
}

/* ---- Result -------------------------------------------------------------- */
.sa-result-head {
  display: block;
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.15;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.sa-range {
  display: block;
  margin-top: 6px;
  font-size: clamp(48px, 7.2vw, 84px);
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--ink);
  white-space: nowrap;
}

.sa-range-label {
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.sa-disclaimer {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.sa-block-title {
  font-size: 13px;
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 18px;
}

.sa-bars-block {
  margin-top: 34px;
}

/* Same bar language as the hero's report card (section 26), one step up in
   size because this one is the page's own result, not a mock screen. */
.sa-bars {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-bottom: 14px;
}

.sa-bars li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 12px;
  align-items: baseline;
}

.sa-bars span {
  font-size: 15px;
  color: var(--ink-2);
}

.sa-bars b {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  font-weight: 600;
  color: var(--c, var(--ink));
}

.sa-bars i {
  grid-column: 1 / -1;
  display: block;
  height: 8px;
  border-radius: 999px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}

.sa-bars i::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--v, 0%);
  border-radius: 999px;
  background: var(--c, var(--brand));
  animation: sa-bar-fill 700ms ease-out both;
}

.sa-bars li:nth-child(2) i::after { animation-delay: 90ms; }
.sa-bars li:nth-child(3) i::after { animation-delay: 180ms; }
.sa-bars li:nth-child(4) i::after { animation-delay: 270ms; }

.sa-bars .is-weakest span {
  color: var(--ink);
  font-weight: 600;
}

@keyframes sa-bar-fill {
  from { width: 0; }
  to { width: var(--v, 0%); }
}

@media (prefers-reduced-motion: reduce) {
  .sa-bars i::after {
    animation: none;
  }
}

/* ---- Fix this first ------------------------------------------------------ */
.sa-fix {
  margin-top: 34px;
  padding: clamp(20px, 2.6vw, 30px);
  border-radius: var(--r-card);
  background: var(--ground-3);
}

.sa-fix .eyebrow {
  display: block;
  margin-bottom: 8px;
}

.sa-fix h3 {
  font-size: clamp(21px, 1.8vw, 26px);
  margin-bottom: 18px;
}

.sa-tips {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.sa-tips li {
  position: relative;
  padding-left: 22px;
  max-width: 68ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.sa-tips li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--brand);
}

.sa-tips a {
  color: var(--brand-deep);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.sa-habit {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line-2);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.55;
  color: var(--ink);
}

/* ---- Share --------------------------------------------------------------- */
.sa-share {
  margin-top: 34px;
  padding-top: 28px;
  border-top: 1px solid var(--line);
}

.sa-share-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  align-items: start;
}

.sa-share-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.sa-share-btn {
  width: 100%;
  max-width: 320px;
  min-height: 48px;
  padding: 13px 18px;
  text-align: left;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.sa-share-btn:hover {
  border-color: var(--ink);
  background: var(--ground-2);
}

@media (prefers-reduced-motion: reduce) {
  .sa-share-btn {
    transition: none;
  }
}

.sa-copy-status {
  min-height: 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
}

.sa-canvas-wrap {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}

.sa-canvas-wrap canvas {
  width: 240px;
  height: 240px;
  max-width: 100%;
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}

/* ---- Challenge a friend ---------------------------------------------------
   Optional first-name field plus its own share button, tucked under the
   other share actions; the banner it produces lives at the top of a shared
   result (see below). */
.sa-challenge {
  width: 100%;
  max-width: 320px;
  margin-top: 6px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.sa-challenge-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: 6px;
}

.sa-challenge-input {
  display: block;
  width: 100%;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--ink);
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
  padding: 12px 14px;
  min-height: 46px;
  margin-bottom: 10px;
  appearance: none;
}

.sa-challenge-input:focus-visible {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(40, 98, 239, 0.15);
}

.sa-challenge-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  margin-bottom: 24px;
  padding: 16px 20px;
  background: var(--brand-tint);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.sa-challenge-banner[hidden] {
  display: none;
}

.sa-challenge-banner p {
  margin: 0;
  max-width: 44ch;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--brand-ink);
}

.sa-challenge-take-btn {
  flex: 0 0 auto;
}

/* ---- CTA inside the result ----------------------------------------------- */
.sa-cta {
  margin-top: 34px;
  padding: clamp(26px, 3.4vw, 44px);
  border-radius: var(--r-card);
}

.sa-cta .eyebrow {
  display: block;
  margin-bottom: 10px;
}

.sa-cta h3 {
  font-size: clamp(24px, 2.4vw, 32px);
  margin-bottom: 14px;
}

.sa-cta p {
  max-width: 58ch;
  font-size: 16px;
  line-height: 1.6;
}

.sa-cta .store-badges {
  margin-top: 24px;
}

/* ---- Foot ---------------------------------------------------------------- */
.sa-result-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  margin-top: 28px;
}

.sa-retake {
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.sa-retake:hover {
  color: var(--brand);
}

.sa-result-foot [hidden] {
  display: none;
}

/* ---- Breakpoints --------------------------------------------------------- */
@media (min-width: 860px) {
  .sa-share-grid {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 40px;
  }
}

/* -------------------------------------------------------------------------
   28. Vocabulary
   -------------------------------------------------------------------------
   /vocabulary/ and /vocabulary/<slug>/ — the topic hub and the topic page:
   the "where it comes up" strip, the upgrade table, the band-grouped phrase
   cards, the gap-fill self-test, and the practise/related blocks. The test's
   option cards are the shared quiz component from section 25; only its
   right/wrong states are here.
   ------------------------------------------------------------------------- */
.vocab-page {
  padding-block: 64px;
}

.vocab-content {
  max-width: 960px;
  margin-inline: auto;
}

/* These are <section>s inside an article, not page bands, so they drop the
   global section rhythm (which would stack 120px of padding on top of the
   margin) and space themselves. */
.vocab-content > section {
  padding-block: 0;
  margin-top: clamp(52px, 6vw, 84px);
}

.vocab-content > section > h2 {
  font-size: clamp(26px, 2.8vw, 36px);
  line-height: 1.06;
  letter-spacing: -0.025em;
  margin-bottom: 10px;
}

.vocab-section-lede {
  max-width: 62ch;
  margin-bottom: 28px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---- Header -------------------------------------------------------------- */
.vocab-header h1 {
  font-size: clamp(34px, 4.6vw, 56px);
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
  margin-bottom: 12px;
}

.vocab-intro {
  max-width: 66ch;
}

.vocab-intro p {
  font-size: 17px;
  line-height: 1.62;
  color: var(--ink-2);
  margin-bottom: 16px;
}

.vocab-intro p:last-child {
  margin-bottom: 0;
}

.vocab-intro a {
  color: var(--brand-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- Where this topic comes up ------------------------------------------- */
.vocab-where-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
  margin-top: 22px;
}

.vocab-where-list li {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px 20px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}

.vocab-where-tag {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}

.vocab-where-line {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.vocab-where-line a {
  color: var(--brand-deep);
  font-weight: 600;
}

.vocab-where-line a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- Instead of… say… ----------------------------------------------------- */
.vocab-upgrade-card {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--ground);
  overflow-x: auto;
}

.vocab-upgrade-table {
  width: 100%;
  min-width: 420px;
  border-collapse: collapse;
}

.vocab-upgrade-table th {
  padding: 14px 22px;
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--ground-2);
  border-bottom: 1px solid var(--line);
}

.vocab-upgrade-table td {
  padding: 16px 22px;
  vertical-align: top;
  border-bottom: 1px solid var(--line);
  font-size: 16px;
  line-height: 1.45;
}

.vocab-upgrade-table tr:last-child td {
  border-bottom: 0;
}

.vocab-upgrade-from {
  color: var(--ink-3);
  width: 40%;
}

.vocab-upgrade-to strong {
  display: block;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.vocab-upgrade-note {
  display: block;
  margin-top: 5px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}

/* ---- Phrases by band ------------------------------------------------------ */
.vocab-band-group + .vocab-band-group {
  margin-top: clamp(36px, 4vw, 56px);
}

.vocab-band-head {
  padding-top: 18px;
  border-top: 1px solid var(--line);
  margin-bottom: 20px;
}

.vocab-band-head h3 {
  font-size: clamp(20px, 1.8vw, 24px);
  margin: 10px 0 6px;
}

.vocab-band-head p {
  max-width: 58ch;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.vocab-items {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

.vocab-item {
  padding: 22px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.vocab-item-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 10px;
}

.vocab-phrase {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--ink);
}

.vocab-type {
  text-transform: lowercase;
}

.vocab-meaning {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
  margin-bottom: 12px;
}

.vocab-example {
  padding-left: 14px;
  border-left: 2px solid var(--line-2);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-3);
  font-style: italic;
}

/* ---- Test yourself -------------------------------------------------------- */
.vocab-section-lede kbd {
  display: inline-block;
  min-width: 18px;
  padding: 1px 5px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: var(--ground-2);
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
}

.vocab-noscript {
  padding: 18px 22px;
  border-radius: var(--r-card);
  background: var(--ground-2);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.vocab-test-app[hidden] {
  display: none;
}

.vocab-test-card {
  padding: clamp(22px, 3.2vw, 40px);
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.vocab-test-card[hidden] {
  display: none;
}

.vocab-test-card:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.vocab-test-q {
  margin: 26px 0 22px;
  font-family: var(--font-display);
  font-size: clamp(20px, 2.1vw, 27px);
  font-weight: 600;
  line-height: 1.22;
  letter-spacing: -0.02em;
  color: var(--ink);
  max-width: 36ch;
  text-wrap: balance;
}

/* The three states a locked question leaves behind: the right phrase always
   shows green, the chosen wrong one amber, everything else steps back. */
.vocab-option.is-correct {
  border-color: var(--ok);
  background: var(--ok-tint);
  box-shadow: inset 0 0 0 1px var(--ok);
}

.vocab-option.is-correct .vocab-option-key {
  background: var(--ok);
  color: #fff;
}

.vocab-option.is-wrong {
  border-color: var(--err);
  background: var(--err-tint);
  box-shadow: inset 0 0 0 1px var(--err);
}

.vocab-option.is-wrong .vocab-option-key {
  background: var(--err);
  color: #fff;
}

.vocab-option.is-dim {
  opacity: 0.55;
}

.vocab-option.is-correct,
.vocab-option.is-wrong,
.vocab-option.is-dim {
  cursor: default;
}

.vocab-option.is-correct:hover,
.vocab-option.is-wrong:hover,
.vocab-option.is-dim:hover {
  background: inherit;
}

.vocab-test-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  min-height: 62px;
}

.vocab-test-feedback {
  flex: 1 1 260px;
  max-width: 58ch;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}

.vocab-test-feedback.is-right {
  color: var(--ok);
}

.vocab-test-feedback.is-wrong {
  color: var(--ink-2);
}

.vocab-next[hidden] {
  display: none;
}

/* ---- Result --------------------------------------------------------------- */
.vocab-score-label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.vocab-score {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: clamp(46px, 6.6vw, 76px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--ink);
  margin-top: 6px;
}

.vocab-score-note {
  margin-top: 14px;
  max-width: 56ch;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.vocab-review {
  margin-top: 30px;
  padding: 22px;
  border-radius: var(--r-card);
  background: var(--ground-3);
}

.vocab-review[hidden] {
  display: none;
}

.vocab-block-title {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 14px;
}

.vocab-review-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.vocab-review-list li {
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}

.vocab-review-list b {
  display: block;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.vocab-test-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
  margin-top: 28px;
}

.vocab-share-btn {
  min-height: 46px;
  padding: 12px 18px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.vocab-share-btn:hover {
  border-color: var(--ink);
  background: var(--ground-2);
}

@media (prefers-reduced-motion: reduce) {
  .vocab-share-btn {
    transition: none;
  }
}

.vocab-copy-status {
  flex: 1 1 100%;
  min-height: 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
}

.vocab-test-links {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

/* ---- Challenge a friend ----------------------------------------------------
   Built by vocab-test.js at result time (see that file): optional name field
   plus its own share button, and the banner a shared `#c=` link renders
   above the quiz. */
.vocab-challenge {
  max-width: 320px;
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

.vocab-challenge-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: 6px;
}

.vocab-challenge-input {
  display: block;
  width: 100%;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--ink);
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
  padding: 12px 14px;
  min-height: 46px;
  margin-bottom: 10px;
  appearance: none;
}

.vocab-challenge-input:focus-visible {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(40, 98, 239, 0.15);
}

.vocab-challenge-banner {
  margin-bottom: 20px;
  padding: 16px 20px;
  background: var(--brand-tint);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.vocab-challenge-banner p {
  margin: 0;
  max-width: 44ch;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--brand-ink);
}

/* ---- Practise it out loud -------------------------------------------------- */
.vocab-questions + .vocab-questions {
  margin-top: 32px;
}

.vocab-questions h3 {
  font-size: 18px;
  margin-bottom: 14px;
}

.vocab-question-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  border-top: 1px solid var(--line);
  padding-top: 14px;
}

.vocab-question-list li {
  position: relative;
  padding-left: 20px;
  max-width: 70ch;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
}

.vocab-question-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 10px;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--brand);
}

.vocab-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: 32px;
}

.vocab-card-tile {
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--ground-2);
}

.vocab-card-tile .eyebrow {
  display: block;
  margin-bottom: 10px;
}

.vocab-card-tile h3 {
  font-size: 19px;
  margin-bottom: 14px;
}

.vocab-card-tile h3 a {
  color: var(--ink);
}

.vocab-card-tile h3 a:hover {
  color: var(--brand-deep);
}

/* ---- Related reading / more topics ----------------------------------------- */
.vocab-related .more-posts-grid,
.vocab-more .more-posts-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

.vocab-content .post-cta,
.vocab-content .post-faq {
  max-width: none;
}

.vocab-content .post-faq {
  margin-top: clamp(52px, 6vw, 84px);
}

/* ---- Hub ------------------------------------------------------------------- */
.vocab-hub .blog-index-intro {
  max-width: 72ch;
}

.vocab-group + .vocab-group {
  margin-top: clamp(44px, 5vw, 64px);
}

.vocab-group > h2 {
  font-size: clamp(24px, 2.4vw, 32px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  padding-bottom: 14px;
  margin-bottom: 22px;
  border-bottom: 1px solid var(--line);
}

.vocab-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.vocab-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 26px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--ground);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.vocab-tile:hover,
.vocab-tile:focus-visible {
  border-color: var(--line-2);
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .vocab-tile,
  .vocab-tile:hover {
    transition: none;
    transform: none;
  }
}

.vocab-tile h3 {
  font-size: 20px;
  letter-spacing: -0.02em;
}

.vocab-tile-count {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.vocab-tile-chips {
  margin: 4px 0 6px;
}

.vocab-tile .arrow-link {
  margin-top: auto;
  padding-top: 6px;
}

/* ---- Breakpoints ----------------------------------------------------------- */
@media (min-width: 600px) {
  .vocab-where-list li {
    grid-template-columns: 120px minmax(0, 1fr);
    align-items: baseline;
  }
}

@media (min-width: 760px) {
  .vocab-items {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .vocab-card-grid {
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  }

  .vocab-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .vocab-related .more-posts-grid,
  .vocab-more .more-posts-grid {
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  }
}

@media (min-width: 1024px) {
  .vocab-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* -------------------------------------------------------------------------
   29. Band descriptors
   -------------------------------------------------------------------------
   /ielts-band-descriptors — the criterion × band explorer, the "Band 7 at a
   glance" strip, the facts cards and the full 24-cell table. Built from the
   same v3 vocabulary as the self-assessment: one tinted panel framing white
   cards, segmented controls for the two axes, and the section-23 annotation
   palette carried through so a criterion always means the same colour
   (fluency violet, vocabulary blue, grammar green, pronunciation ink).
   ------------------------------------------------------------------------- */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- Page rhythm --------------------------------------------------------- */
.bd-hero {
  padding-block: clamp(56px, 7vw, 96px) 0;
}

.bd-hero-head {
  max-width: 820px;
  margin-inline: auto;
  text-align: center;
}

.bd-hero-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.bd-hero-head h1 {
  font-size: clamp(38px, 5.2vw, 72px);
}

.bd-hero-sub {
  margin: 20px auto 0;
  max-width: 56ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-2);
}

.bd-explorer-section {
  padding-block: clamp(28px, 4vw, 48px) 0;
}

.bd-glance-section,
.bd-arith-section,
.bd-facts-section,
.bd-next-section,
.bd-table-section,
.bd-cta-section {
  padding-block: clamp(48px, 6vw, 88px) 0;
}

.bd-main .faq {
  padding-block: clamp(48px, 6vw, 88px) 0;
}

.bd-cta-section {
  padding-bottom: clamp(56px, 7vw, 104px);
}

/* ---- The explorer panel -------------------------------------------------- */
.bd-panel {
  max-width: 1080px;
  margin-inline: auto;
  padding: clamp(16px, 2vw, 28px);
}

.bd-controls {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: clamp(16px, 2vw, 24px);
}

/* Criterion tabs: the shared segmented control, tinted with each criterion's
   own colour when it is the selected one. */
.bd-tablist {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
}

.bd-tab {
  flex: 1;
  min-width: 0;
  padding: 11px 8px;
  border: none;
  border-radius: 10px;
  background: none;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.bd-tab:hover {
  color: var(--ink);
}

.bd-tab:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.bd-tab-fc[aria-selected="true"] { background: var(--violet-tint); color: var(--violet); }
.bd-tab-lr[aria-selected="true"] { background: var(--brand-tint); color: var(--brand-deep); }
.bd-tab-gra[aria-selected="true"] { background: var(--ok-tint); color: var(--ok); }
.bd-tab-pr[aria-selected="true"] { background: #e8eaf0; color: var(--ink); }

.bd-tab-abbr {
  display: none;
}

/* ---- Band control + tools ------------------------------------------------ */
.bd-bandrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.bd-bands {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
}

.bd-band {
  min-width: 46px;
  padding: 9px 10px;
  border: none;
  border-radius: 10px;
  background: none;
  color: var(--ink-2);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.bd-band:hover {
  color: var(--ink);
}

.bd-band:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.bd-band[aria-checked="true"] {
  background: var(--ink);
  color: #fff;
}

.bd-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
}

.bd-compare {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  cursor: pointer;
}

.bd-compare input {
  width: 16px;
  height: 16px;
  accent-color: var(--brand);
}

.bd-compare.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.bd-copy {
  padding: 10px 16px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.bd-copy:hover {
  border-color: var(--ink);
}

.bd-copy:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.bd-copy-status {
  min-width: 80px;
  margin: 0;
}

.bd-noscript {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- The cell ------------------------------------------------------------ */
.bd-cells {
  display: grid;
  gap: 16px;
}

.bd-cell {
  --bd-accent: var(--ink);
  --bd-accent-tint: var(--ground-2);
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(20px, 3vw, 36px);
}

.bd-cell[data-crit="fc"] { --bd-accent: var(--violet); --bd-accent-tint: var(--violet-tint); }
.bd-cell[data-crit="lr"] { --bd-accent: var(--brand); --bd-accent-tint: var(--brand-tint); }
.bd-cell[data-crit="gra"] { --bd-accent: var(--ok); --bd-accent-tint: var(--ok-tint); }
.bd-cell[data-crit="pr"] { --bd-accent: var(--ink); --bd-accent-tint: #e8eaf0; }

.bd-cell-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 14px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}

.bd-cell-title {
  margin: 0;
  font-size: clamp(26px, 2.6vw, 34px);
  line-height: 1.05;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}

/* <section> carries the global section rhythm (section 3); inside a cell it
   must not. */
.bd-block {
  padding: 20px 0 0;
  margin-top: 20px;
  border-top: 1px solid var(--line);
}

.bd-cell-head + .bd-block {
  border-top: none;
  margin-top: 0;
}

.bd-block-title {
  margin: 0 0 12px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
  text-wrap: balance;
}

.bd-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.bd-list li {
  position: relative;
  padding-left: 20px;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 66ch;
}

.bd-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--bd-accent);
}

.bd-list-traps li::before {
  border-radius: 2px;
  background: var(--warn);
}

/* ---- "What it sounds like" ---------------------------------------------- */
.bd-quote {
  margin: 0 0 12px;
  padding: 16px 18px;
  background: var(--ground-2);
  border-left: 3px solid var(--bd-accent);
  border-radius: 0 var(--r-input) var(--r-input) 0;
}

.bd-quote:last-child {
  margin-bottom: 0;
}

.bd-quote blockquote {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
}

/* These marks are illustrations, not tooltips — nothing opens on hover. */
.bd-quote mark.ann {
  cursor: default;
}

.bd-quote figcaption {
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-3);
}

.bd-desc-note {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-3);
}

.bd-tag {
  display: inline-block;
  margin-right: 6px;
  padding: 3px 8px;
  border-radius: var(--r-chip);
  background: var(--ground-2);
  color: var(--ink-2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.bd-desc {
  margin: 0;
  max-width: 66ch;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---- Compare view -------------------------------------------------------- */
.bd-cells-compare .bd-cell-next {
  border-color: var(--line-2);
  background: var(--ground);
}

@media (min-width: 900px) {
  .bd-cells-compare {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
}

/* ---- Band 7 at a glance -------------------------------------------------- */
.bd-glance {
  display: grid;
  gap: 12px;
  margin-top: 28px;
}

.bd-glance-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 24px;
  border-radius: var(--r-card);
  border: 1px solid var(--line);
  border-top: 3px solid var(--bd-accent, var(--ink));
  background: var(--ground);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.bd-glance-fc { --bd-accent: var(--violet); }
.bd-glance-lr { --bd-accent: var(--brand); }
.bd-glance-gra { --bd-accent: var(--ok); }
.bd-glance-pr { --bd-accent: var(--ink); }

.bd-glance-col:hover {
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}

.bd-glance-col:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.bd-glance-crit {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.bd-glance-line {
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}

.bd-glance-go {
  margin-top: auto;
  padding-top: 6px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--brand);
}

@media (prefers-reduced-motion: reduce) {
  .bd-glance-col,
  .bd-glance-col:hover {
    transition: none;
    transform: none;
  }
}

/* ---- How the numbers work ------------------------------------------------ */
.bd-arith-text {
  max-width: 70ch;
}

.bd-arith .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.bd-arith p {
  margin: 16px 0 20px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---- Facts people get wrong ---------------------------------------------- */
.bd-facts {
  display: grid;
  gap: 16px;
  margin-top: 28px;
}

.bd-fact {
  padding: 28px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.bd-fact h3 {
  margin: 0 0 10px;
  font-size: 19px;
  letter-spacing: -0.015em;
}

.bd-fact p {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- Where to go next ---------------------------------------------------- */
.bd-next {
  display: grid;
  gap: 16px;
  margin-top: 28px;
}

.bd-next-tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 32px;
  background: var(--ground-2);
  border: 1px solid transparent;
  border-radius: var(--r-card);
}

.bd-next-tile h3 {
  margin: 0;
  font-size: 20px;
  letter-spacing: -0.02em;
}

.bd-next-tile p {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.bd-next-tile .arrow-link {
  margin-top: auto;
  padding-top: 8px;
}

.bd-next-tile:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* ---- The full table ------------------------------------------------------ */
.bd-table {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 28px;
}

.bd-details {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.bd-details > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 26px;
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}

.bd-details > summary::-webkit-details-marker {
  display: none;
}

.bd-details > summary:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -2px;
  border-radius: var(--r-card);
}

.bd-details-hint {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}

.bd-details[open] > summary {
  border-bottom: 1px solid var(--line);
}

.bd-details-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 22px 26px 26px;
}

.bd-cell-static {
  background: var(--ground-2);
  border-color: transparent;
}

.bd-cell-static .bd-cell-head,
.bd-cell-static .bd-block {
  border-color: var(--line-2);
}

.bd-cell-static .bd-quote {
  background: var(--ground);
}

/* ---- CTA ----------------------------------------------------------------- */
.bd-cta {
  max-width: 900px;
  margin-inline: auto;
  text-align: center;
}

.bd-cta .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.bd-cta h2 {
  margin: 0 0 16px;
}

.bd-cta p {
  margin: 0 auto 28px;
  max-width: 56ch;
  font-size: 17px;
  line-height: 1.6;
}

.bd-cta .store-badges {
  justify-content: center;
}

/* ---- Breakpoints --------------------------------------------------------- */
@media (max-width: 639px) {
  .bd-tab-full { display: none; }
  .bd-tab-abbr { display: inline; }

  .bd-tab {
    padding: 11px 4px;
    font-size: 13px;
    letter-spacing: 0.02em;
  }

  .bd-bandrow {
    flex-direction: column;
    align-items: stretch;
  }

  .bd-bands {
    justify-content: space-between;
  }

  .bd-band {
    flex: 1;
    min-width: 0;
  }
}

/* From here the cell reads as a bureau table: the block label sits in a fixed
   left column and the content runs beside it. The compare view has two cells
   side by side and stays single-column inside each. */
@media (min-width: 1000px) {
  .bd-cell-head,
  .bd-block {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr);
    column-gap: 32px;
    align-items: start;
  }

  .bd-cell-head .chip {
    grid-column: 1;
    align-self: center;
  }

  .bd-block-title {
    grid-column: 1;
    margin-bottom: 0;
    padding-top: 3px;
  }

  .bd-block > :not(.bd-block-title) {
    grid-column: 2;
  }

  .bd-cells-compare .bd-cell-head,
  .bd-cells-compare .bd-block {
    display: block;
  }

  .bd-cells-compare .bd-block-title {
    margin-bottom: 12px;
    padding-top: 0;
  }
}

@media (min-width: 760px) {
  .bd-facts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .bd-next {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .bd-glance {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .bd-glance {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ---- Hooks from the other pages ------------------------------------------
   Three small rules that belong to this page's integration rather than to
   the pages they appear on: the homepage's criterion-card titles and the
   line under them, and the link the self-assessment result adds under "Fix
   this first". */
.report-crit-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--line-2);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.report-crit-link:hover {
  text-decoration-color: currentColor;
}

.scoring-explore {
  margin: 24px 0 0;
}

.sa-fix-link {
  margin: 14px 0 0;
}

.sa-fix-link a {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--brand);
}

.sa-fix-link a:hover {
  color: var(--brand-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* -------------------------------------------------------------------------
   31. Study plan
   -------------------------------------------------------------------------
   /ielts-study-plan — the week-by-week generator. One input card floating
   in a tinted panel (the self-assessment's shape, section 27), then the
   generated plan as a numbered list of week cards. Controls are sized for
   a thumb: 52px inputs, 48px segmented buttons, 44px chips. The print
   rules at the bottom drop everything but the plan itself.
   ------------------------------------------------------------------------- */

/* ---- Page rhythm --------------------------------------------------------- */
.sp-hero {
  padding-block: clamp(56px, 7vw, 96px) 0;
}

.sp-hero-head {
  max-width: 820px;
  margin-inline: auto;
  text-align: center;
}

.sp-hero-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.sp-hero-head h1 {
  font-size: clamp(38px, 5.2vw, 70px);
}

.sp-hero-sub {
  margin: 20px auto 0;
  max-width: 56ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-2);
}

.sp-form-section {
  padding-block: clamp(28px, 4vw, 48px) 0;
}

.sp-panel {
  max-width: 920px;
  margin-inline: auto;
  padding: clamp(12px, 1.6vw, 24px);
}

/* The generator needs JS; the .js-reveal gate is set by the inline script
   in <head>, so a no-JS visitor gets the <noscript> line and the FAQ. */
.sp-app {
  display: none;
}

.js-reveal .sp-app {
  display: block;
}

.sp-noscript {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- The input card ------------------------------------------------------ */
.sp-card {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(22px, 3.2vw, 40px);
}

.sp-form > .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.sp-form h2 {
  font-size: clamp(26px, 2.6vw, 34px);
  line-height: 1.1;
  margin-bottom: 14px;
}

.sp-form-lede {
  max-width: 58ch;
  margin-bottom: 28px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.sp-fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

.sp-fieldset {
  border: none;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.sp-label {
  display: block;
  padding: 0;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.sp-help {
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-3);
}

.sp-help-top {
  margin-top: 0;
  margin-bottom: 12px;
}

.sp-input,
.sp-select {
  width: 100%;
  min-height: 52px;
  padding: 14px 16px;
  font-family: inherit;
  font-size: 17px;
  color: var(--ink);
  background: var(--ground-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  appearance: none;
}

.sp-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23505561'%3E%3Cpath fill-rule='evenodd' d='M5.23 7.21a.75.75 0 011.06.02L10 11.293l3.71-4.06a.75.75 0 111.08 1.04l-4.24 4.65a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z' clip-rule='evenodd'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 18px;
  padding-right: 42px;
}

.sp-input:disabled {
  color: var(--ink-3);
  background: var(--ground-2);
  opacity: 0.6;
}

.sp-input:focus-visible,
.sp-select:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-color: var(--brand);
}

.sp-check {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  min-height: 44px;
}

.sp-check input {
  width: 20px;
  height: 20px;
  flex: none;
  accent-color: var(--brand);
}

.sp-check input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.sp-check label {
  font-size: 15px;
  line-height: 1.4;
  color: var(--ink-2);
  cursor: pointer;
}

/* ---- Segmented controls -------------------------------------------------- */
.sp-seg {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 5px;
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
}

.sp-seg-btn {
  flex: 1 1 64px;
  min-height: 48px;
  padding: 12px 10px;
  border: none;
  border-radius: 9px;
  background: transparent;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease;
}

.sp-seg-btn:hover {
  color: var(--ink);
}

.sp-seg-btn[aria-checked="true"] {
  background: var(--ground);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--brand), var(--shadow-card);
}

.sp-seg-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* ---- Weak-area chips ----------------------------------------------------- */
.sp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.sp-chip-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 10px 16px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-chip);
  background: var(--ground);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color 0.18s ease, background-color 0.18s ease, color 0.18s ease;
}

.sp-chip-btn:hover {
  border-color: var(--ink-3);
  color: var(--ink);
}

.sp-chip-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.sp-chip-btn.is-on {
  border-color: var(--brand);
  background: var(--brand-tint);
  color: var(--brand-ink);
}

.sp-chip-order {
  display: none;
}

.sp-chip-btn.is-on .sp-chip-order {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
}

/* ---- Actions ------------------------------------------------------------- */
.sp-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 28px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

.sp-build {
  min-height: 52px;
  padding-inline: 28px;
}

.sp-ghost-btn,
.sp-tool-btn {
  min-height: 48px;
  padding: 12px 20px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--brand);
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  cursor: pointer;
  transition: border-color 0.18s ease, background-color 0.18s ease;
}

.sp-ghost-btn:hover,
.sp-tool-btn:hover {
  border-color: var(--brand);
  background: var(--ground-2);
}

.sp-ghost-btn:focus-visible,
.sp-tool-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.sp-copy-status {
  min-height: 18px;
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
}

/* ---- The generated plan -------------------------------------------------- */
.sp-plan-section {
  padding-block: 0;
}

.sp-plan:empty {
  display: none;
}

.sp-plan {
  max-width: 920px;
  margin-inline: auto;
  padding-block: clamp(40px, 5vw, 72px) 0;
}

.sp-plan:focus {
  outline: none;
}

.sp-plan:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 6px;
  border-radius: var(--r-card);
}

.sp-plan-head .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.sp-plan-head h2 {
  font-size: clamp(28px, 3.2vw, 42px);
  line-height: 1.06;
}

.sp-plan-meta {
  margin-top: 14px;
  font-size: 15px;
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}

.sp-notices {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 24px;
}

.sp-notice {
  padding: 16px 18px;
  border-radius: var(--r-input);
  background: var(--ground-3);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.sp-notice-warn {
  background: var(--warn-tint);
  color: #7c3d05;
}

.sp-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 24px;
}

.sp-tools .sp-tool-btn {
  flex: 1 1 180px;
}

.sp-plan .sp-copy-status {
  margin-top: 10px;
}

.sp-save {
  margin-top: 20px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--ground-2);
}

.sp-save h3 {
  font-size: 18px;
  margin-bottom: 8px;
}

.sp-save p {
  max-width: 62ch;
  margin-bottom: 16px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---- Week cards ---------------------------------------------------------- */
.sp-weeks {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 32px;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.sp-week-card {
  padding: clamp(20px, 2.6vw, 30px);
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.sp-week-head {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 8px 16px;
}

.sp-week-num {
  grid-row: 1 / 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--ground-3);
  color: var(--brand-deep);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 19px;
  font-weight: 600;
}

.sp-week-head-text {
  min-width: 0;
}

.sp-week-head .chip {
  grid-column: 2;
  justify-self: start;
}

.sp-week-dates {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.sp-week-head h3 {
  margin-top: 4px;
  font-size: clamp(19px, 1.7vw, 23px);
  line-height: 1.2;
}

.sp-week-aim {
  margin-top: 6px;
  max-width: 60ch;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.sp-week-habit {
  margin-top: 16px;
  padding: 14px 16px;
  border-radius: var(--r-input);
  background: var(--ground-2);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.sp-week-habit strong {
  color: var(--ink);
}

.sp-res,
.sp-session {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.sp-res-title {
  margin-bottom: 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.sp-res-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  list-style: none;
  padding: 0;
}

.sp-res-item {
  padding-left: 14px;
  border-left: 2px solid var(--line);
}

.sp-res-kind {
  display: block;
  margin-bottom: 4px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.sp-res-line {
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.sp-res-cards {
  display: flex;
  flex-direction: column;
  gap: 4px;
  list-style: none;
  padding: 0;
}

.sp-res-cards li {
  font-size: 15px;
  line-height: 1.6;
}

.sp-res-item a {
  color: var(--brand);
  font-weight: 500;
}

.sp-res-item a:hover {
  color: var(--brand-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.sp-res-pending {
  color: var(--ink-3);
  font-style: italic;
}

.sp-session-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  list-style: none;
  padding: 0;
}

.sp-session-list li {
  display: flex;
  align-items: baseline;
  gap: 12px;
}

.sp-session-mins {
  flex: none;
  min-width: 58px;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  font-weight: 600;
  color: var(--brand);
}

.sp-session-text {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.sp-session .note {
  margin-top: 12px;
}

.sp-session-days {
  margin-top: 14px;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}

.sp-foot-note {
  max-width: 70ch;
  margin-top: 28px;
}

/* ---- CTA ----------------------------------------------------------------- */
.sp-cta-section {
  padding-block: clamp(48px, 6vw, 88px) 0;
}

.sp-cta {
  max-width: 920px;
  margin-inline: auto;
  text-align: center;
}

.sp-cta .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.sp-cta h2 {
  font-size: clamp(26px, 3vw, 40px);
  line-height: 1.08;
}

.sp-cta p {
  max-width: 62ch;
  margin: 16px auto 24px;
  font-size: 16px;
  line-height: 1.6;
}

.sp-cta .store-badges {
  justify-content: center;
}

/* ---- Wider viewports ----------------------------------------------------- */
@media (min-width: 720px) {
  .sp-fields {
    grid-template-columns: 1fr 1fr;
    gap: 24px 28px;
  }

  .sp-field-wide {
    grid-column: 1 / -1;
  }

  .sp-week-head {
    grid-template-columns: auto 1fr auto;
  }

  .sp-week-head .chip {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
  }

  .sp-week-head-text {
    grid-column: 2;
    grid-row: 1 / 3;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sp-seg-btn,
  .sp-chip-btn,
  .sp-ghost-btn,
  .sp-tool-btn {
    transition: none;
  }
}

/* ---- Print ---------------------------------------------------------------
   Black on white, the plan only: no navigation, no form, no buttons, no
   store badges. Week cards are kept off page breaks where the browser
   allows it. */
@media print {
  .navbar,
  .nav-panel,
  .site-footer,
  .sp-hero,
  .sp-form-section,
  .sp-cta-section,
  .faq,
  .sp-tools,
  .sp-save,
  .sp-plan .sp-copy-status {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }

  .sp-plan-section,
  .sp-plan {
    padding: 0;
    margin: 0;
    max-width: none;
  }

  .sp-plan-head h2,
  .sp-week-head h3,
  .sp-plan-head .eyebrow {
    color: #000;
  }

  .sp-plan-head .eyebrow,
  .sp-res-title,
  .sp-week-dates {
    color: #000;
  }

  .sp-plan-meta,
  .sp-week-aim,
  .sp-week-habit,
  .sp-res-line,
  .sp-res-cards li,
  .sp-session-text,
  .sp-session-days,
  .sp-foot-note,
  .note {
    color: #000;
  }

  .sp-week-card,
  .sp-notice,
  .sp-week-habit {
    background: #fff;
    border: 1px solid #000;
    box-shadow: none;
  }

  .sp-week-num {
    background: #fff;
    border: 1px solid #000;
    color: #000;
  }

  .sp-week-head .chip,
  .sp-session-mins {
    background: #fff;
    color: #000;
  }

  .sp-res-item a,
  .sp-res-item a:hover {
    color: #000;
    text-decoration: underline;
  }

  .sp-weeks {
    gap: 12px;
  }

  .sp-week {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .sp-plan {
    font-size: 11pt;
  }

  @page {
    margin: 14mm;
  }
}

/* -------------------------------------------------------------------------
   32. Word stress trainer
   -------------------------------------------------------------------------
   /ielts-word-stress-trainer — the listen-and-mark round, the eight static
   pattern cards under it, and the result view. Same shape as the
   self-assessment (section 27): one white card floating in a tinted panel,
   the shared chip and button vocabulary from section 25, and the same
   progress bar language. The syllable boxes are the one new component.
   ------------------------------------------------------------------------- */

/* ---- Page rhythm --------------------------------------------------------- */
.ws-hero {
  padding-block: clamp(56px, 7vw, 96px) 0;
}

.ws-hero-head {
  max-width: 820px;
  margin-inline: auto;
  text-align: center;
}

.ws-hero-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.ws-hero-head h1 {
  font-size: clamp(40px, 5.4vw, 72px);
}

.ws-hero-sub {
  margin: 20px auto 0;
  max-width: 56ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-2);
}

.ws-trainer-section {
  padding-block: clamp(28px, 4vw, 48px) 0;
}

.ws-panel {
  max-width: 880px;
  margin-inline: auto;
  padding: clamp(12px, 1.6vw, 24px);
}

/* The trainer needs JS; the .js-reveal gate is set by the inline script in
   <head>, so a no-JS visitor gets the <noscript> line and the eight static
   pattern cards, which carry the whole lesson on their own. */
.ws-app {
  display: none;
}

.js-reveal .ws-app {
  display: block;
}

.ws-noscript {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- Challenge banner ---------------------------------------------------- */
.ws-banner {
  margin: 0 0 12px;
  padding: 14px 18px;
  border-radius: var(--r-input);
  background: var(--brand-tint);
  color: var(--brand-ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.45;
}

.ws-banner[hidden] {
  display: none;
}

/* ---- The card ------------------------------------------------------------ */
.ws-card {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(22px, 3.2vw, 40px);
}

.ws-card[hidden] {
  display: none;
}

.ws-card:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.ws-card > .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.ws-card > h2 {
  font-size: clamp(26px, 2.6vw, 34px);
  line-height: 1.1;
  margin-bottom: 16px;
}

/* ---- Intro --------------------------------------------------------------- */
.ws-intro-lede {
  max-width: 60ch;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.ws-intro-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 24px 0 0;
  padding: 20px 0 0;
  border-top: 1px solid var(--line);
}

.ws-intro-list li {
  position: relative;
  padding-left: 20px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.ws-intro-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--brand);
}

.ws-intro-list strong {
  color: var(--ink);
}

.ws-intro-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin-top: 28px;
}

.ws-start {
  padding: 16px 26px;
  font-size: 15px;
}

.ws-intro-note {
  margin-top: 14px;
}

/* ---- Family picker ------------------------------------------------------- */
.ws-pick-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

.ws-pick {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  width: 100%;
  padding: 16px 18px;
  text-align: left;
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.ws-pick:hover {
  border-color: var(--ink-3);
  background: var(--ground-2);
}

.ws-pick:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.ws-pick b {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.ws-pick span {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}

.ws-pick i {
  font-style: normal;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.ws-back {
  margin-top: 20px;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
}

.ws-back:hover {
  color: var(--brand);
}

/* ---- Progress ------------------------------------------------------------ */
.ws-progress-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin-bottom: 12px;
}

.ws-step {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.ws-tag[hidden] {
  display: none;
}

.ws-progress {
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}

.ws-progress > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--brand);
  transition: width 0.25s ease;
}

.ws-family-line {
  margin-top: 14px;
  font-size: 13px;
  color: var(--ink-3);
}

.ws-family-line[hidden] {
  display: none;
}

.ws-family-line b {
  color: var(--ink);
  font-weight: 600;
}

/* ---- The word ------------------------------------------------------------ */
.ws-prompt {
  margin: 26px 0 18px;
  font-size: clamp(21px, 2.2vw, 29px);
  line-height: 1.18;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.ws-play-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin-bottom: 20px;
}

.ws-play {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 12px 22px 12px 18px;
  border: 1px solid var(--brand);
  border-radius: var(--r-chip);
  background: var(--brand-tint);
  color: var(--brand-ink);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.ws-play:hover {
  background: #d8e4ff;
}

.ws-play:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* A CSS triangle: no new image asset for one play glyph. */
.ws-play-icon {
  flex: none;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 7px 0 7px 11px;
  border-color: transparent transparent transparent var(--brand-deep);
}

.ws-speech-note {
  display: none;
  margin: 0;
  max-width: 40ch;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-3);
}

/* No speech synthesis, or no English voice within 1.5s: the play button goes
   and the note takes its place. The round itself is unchanged — the syllable
   boxes always spell the word. */
.ws-nospeech .ws-play {
  display: none;
}

.ws-nospeech .ws-speech-note {
  display: block;
}

/* Nothing to replay, so the Space half of the key hint goes too. */
.ws-nospeech .ws-key-space {
  display: none;
}

/* ---- Syllable boxes ------------------------------------------------------ */
.ws-syllables {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.ws-syl {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 78px;
  min-height: 72px;
  padding: 18px 16px;
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}

.ws-syl:hover:not(:disabled) {
  border-color: var(--ink-3);
  background: var(--ground-2);
}

.ws-syl:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.ws-syl:disabled {
  cursor: default;
}

.ws-syl-key {
  position: absolute;
  top: 6px;
  left: 8px;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-3);
}

.ws-syl-text {
  font-family: var(--font-display);
  font-size: clamp(22px, 4.4vw, 30px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.ws-syl.is-answer {
  border-color: var(--ok);
  background: var(--ok-tint);
  box-shadow: inset 0 0 0 1px var(--ok);
}

.ws-syl.is-answer .ws-syl-text,
.ws-syl.is-answer .ws-syl-key {
  color: var(--ok);
}

.ws-syl.is-wrong {
  border-color: var(--err);
  background: var(--err-tint);
}

.ws-syl.is-wrong .ws-syl-text,
.ws-syl.is-wrong .ws-syl-key {
  color: var(--err);
}

/* ---- Feedback ------------------------------------------------------------ */
.ws-feedback {
  margin-top: 22px;
  padding: 18px 20px;
  border-radius: var(--r-input);
  background: var(--ground-2);
  border-left: 3px solid var(--line-2);
}

.ws-feedback[hidden] {
  display: none;
}

.ws-feedback.is-correct {
  background: var(--ok-tint);
  border-left-color: var(--ok);
}

.ws-feedback.is-wrong {
  background: var(--warn-tint);
  border-left-color: var(--warn);
}

.ws-verdict {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.ws-feedback.is-correct .ws-verdict {
  color: var(--ok);
}

.ws-feedback.is-wrong .ws-verdict {
  color: var(--warn);
}

.ws-answer {
  margin-top: 6px;
  font-family: var(--font-display);
  font-size: clamp(22px, 3vw, 28px);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--ink);
  word-break: break-word;
}

.ws-answer strong {
  color: var(--brand-deep);
}

.ws-rule {
  margin-top: 10px;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.ws-note {
  margin-top: 8px;
  max-width: 62ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-3);
}

.ws-note[hidden] {
  display: none;
}

/* ---- Round foot ---------------------------------------------------------- */
.ws-round-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  min-height: 62px;
}

.ws-next[hidden] {
  display: none;
}

.ws-keyhint {
  margin: 0;
}

.ws-keyhint kbd {
  display: inline-block;
  min-width: 18px;
  padding: 1px 5px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: var(--ground-2);
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
}

@media (max-width: 599px) {
  .ws-keyhint {
    display: none;
  }
}

/* ---- Result -------------------------------------------------------------- */
.ws-result-head {
  display: block;
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.15;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.ws-score {
  display: block;
  margin-top: 6px;
  font-size: clamp(48px, 7.2vw, 84px);
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--ink);
  white-space: nowrap;
}

.ws-result-sub {
  margin-top: 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.ws-block-title {
  font-size: 13px;
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 16px;
}

.ws-missed {
  margin-top: 30px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

.ws-missed-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ws-missed-list li {
  padding: 16px 18px;
  border-radius: var(--r-input);
  background: var(--ground-3);
}

.ws-missed-list b {
  display: block;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin-bottom: 4px;
}

.ws-missed-list span {
  display: block;
  max-width: 64ch;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- Result actions ------------------------------------------------------ */
.ws-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 28px;
}

.ws-share-btn {
  min-height: 48px;
  padding: 13px 20px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.ws-share-btn:hover {
  border-color: var(--ink);
  background: var(--ground-2);
}

/* ---- Challenge a friend -------------------------------------------------- */
.ws-challenge {
  margin-top: 30px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

.ws-challenge-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}

.ws-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 220px;
  min-width: 0;
}

.ws-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
}

.ws-input {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
}

.ws-input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}

.ws-challenge .btn-light {
  min-height: 48px;
}

.ws-copy-status {
  min-height: 18px;
  margin-top: 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
}

/* ---- What to do next ----------------------------------------------------- */
.ws-next-links {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 30px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

/* ---- The eight patterns (static, indexable) ------------------------------ */
.ws-pattern-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.ws-pattern {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 26px;
}

.ws-pattern h3 {
  font-size: 19px;
  letter-spacing: -0.015em;
  margin-bottom: 8px;
}

.ws-pattern-rule {
  max-width: 52ch;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.ws-pattern-examples {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

/* Not a flex row: the syllables of one example must sit flush against each
   other ("TAble"), so the part-of-speech label gets the gap instead. */
.ws-pattern-examples li {
  display: inline-block;
  padding: 7px 12px;
  border-radius: var(--r-chip);
  background: var(--ground-2);
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
}

.ws-pattern-examples strong {
  color: var(--brand-deep);
}

.ws-pos {
  margin-left: 7px;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ---- Why stress matters -------------------------------------------------- */
.ws-why-panel .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.ws-why-panel h2 {
  margin-bottom: 20px;
}

.ws-why-panel p {
  max-width: 68ch;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

.ws-why-panel p + p {
  margin-top: 18px;
}

/* ---- CTA ----------------------------------------------------------------- */
.ws-cta .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.ws-cta h2 {
  margin-bottom: 16px;
}

.ws-cta p {
  max-width: 58ch;
  font-size: 16px;
  line-height: 1.6;
}

.ws-cta .store-badges {
  margin-top: 26px;
}

/* ---- Breakpoints --------------------------------------------------------- */
@media (min-width: 600px) {
  .ws-syllables {
    gap: 12px;
  }

  .ws-syl {
    min-width: 96px;
  }
}

@media (min-width: 760px) {
  .ws-pick-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ws-next-links {
    flex-direction: row;
    gap: 28px;
  }
}

@media (min-width: 900px) {
  .ws-pattern-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (prefers-reduced-motion: reduce) {
  .ws-progress > i,
  .ws-pick,
  .ws-play,
  .ws-syl,
  .ws-share-btn {
    transition: none;
  }
}

/* -------------------------------------------------------------------------
   33. Essay checker
   -------------------------------------------------------------------------
   /ielts-essay-checker — the Writing Task 2 structure checker. One white
   editor card floating in a tinted panel (the same frame the self-assessment
   uses in section 27), then a summary card and a grid of ten check cards.

   The three verdicts have one colour each, reused everywhere they appear —
   tally, chip, and the left edge of a check card — so a page of results can
   be read at a glance without reading a word: green Good (--ok), amber Look
   again (--warn), rust Fix (--err). They are never a band score, and the
   page says so in three separate places.
   ------------------------------------------------------------------------- */

/* ---- Page rhythm --------------------------------------------------------- */
.ec-hero {
  padding-block: clamp(48px, 6vw, 88px) 0;
}

.ec-hero-head {
  max-width: 820px;
  margin-inline: auto;
  text-align: center;
}

.ec-hero-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.ec-hero-head h1 {
  font-size: clamp(34px, 4.8vw, 62px);
}

.ec-hero-sub {
  margin: 20px auto 0;
  max-width: 60ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* The "not a band score" flag. It sits in the hero on purpose: this is the
   one thing a visitor must understand before they read a single result. */
.ec-hero-flag {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  max-width: 62ch;
  margin: 26px auto 0;
  padding: 16px 20px;
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  text-align: left;
}

.ec-tool-section {
  padding-block: clamp(28px, 4vw, 48px) 0;
}

.ec-panel {
  max-width: 940px;
  margin-inline: auto;
  padding: clamp(12px, 1.6vw, 24px);
}

/* The checker needs JS. The .js-reveal gate is set by the inline script in
   <head>, so a no-JS visitor sees the <noscript> line and the FAQ, and never
   an empty box with dead buttons. */
.ec-app {
  display: none;
}

.js-reveal .ec-app {
  display: block;
}

.ec-noscript {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- Cards --------------------------------------------------------------- */
.ec-card {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(20px, 3vw, 36px);
}

/* One 16px gap between every block inside the app, whatever is showing. */
.ec-app > .ec-card + .ec-card,
.ec-app > .ec-status + .ec-card,
.ec-app > .ec-card + .ec-results,
.ec-app > .ec-status + .ec-results {
  margin-top: 16px;
}

.ec-card-title {
  font-size: clamp(22px, 2.2vw, 28px);
  margin-bottom: 20px;
}

.ec-card > .eyebrow {
  display: block;
  margin-bottom: 12px;
}

/* ---- The two textareas --------------------------------------------------- */
.ec-field + .ec-field {
  margin-top: 20px;
}

.ec-label {
  display: block;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin-bottom: 8px;
}

.ec-label span {
  font-weight: 400;
  color: var(--ink-3);
}

/* Body face, not monospace: the essay should look like prose on the page,
   because that is how it will be read. */
.ec-input {
  display: block;
  width: 100%;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--ground-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  padding: 14px 16px;
  resize: vertical;
}

.ec-input::placeholder {
  color: var(--ink-3);
}

.ec-input:focus-visible,
.ec-input:focus {
  outline: none;
  background: var(--ground);
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(40, 98, 239, 0.15);
}

.ec-input-prompt {
  min-height: 96px;
}

.ec-input-essay {
  min-height: 320px;
}

.ec-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
  margin-top: 10px;
}

.ec-count {
  font-size: 14px;
  color: var(--ink-2);
}

.ec-count b {
  font-size: 18px;
  color: var(--ink);
  margin-right: 2px;
}

.ec-count span {
  color: var(--ink-3);
}

.ec-meta .note {
  margin: 0;
}

/* ---- Timer ---------------------------------------------------------------
   Counts up to the 40 minutes Task 2 is usually given, and does nothing when
   it gets there: no auto-submit, no lock-out, just a number. */
.ec-timer {
  margin-top: 22px;
  padding: 16px 18px;
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
}

.ec-timer-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  margin-bottom: 10px;
}

.ec-timer-label {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.ec-timer-label .note {
  font-weight: 400;
  margin-left: 4px;
}

.ec-timer-out {
  font-size: 20px;
  color: var(--ink);
}

.ec-timer-track {
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}

.ec-timer-track > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--brand);
  transition: width 0.3s linear;
}

.ec-timer-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-top: 12px;
}

.ec-timer-actions .note {
  margin: 0;
  flex: 1 1 100%;
}

/* ---- Buttons ------------------------------------------------------------- */
.ec-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 24px;
}

.ec-run {
  padding: 15px 26px;
  font-size: 15px;
}

/* The quiet button shape this page reuses for every secondary action. */
.ec-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px 18px;
  min-height: 44px;
  background: var(--ground);
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

.ec-ghost:hover {
  border-color: var(--ink-3);
  color: var(--ink);
}

.ec-ghost:focus-visible,
.ec-run:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.ec-live-note {
  margin: 12px 0 0;
}

.ec-status {
  margin: 12px 4px 0;
}

.ec-status:empty {
  display: none;
}

/* ---- Empty state --------------------------------------------------------- */
.ec-empty[hidden] {
  display: none;
}

.ec-empty h2 {
  font-size: clamp(22px, 2.2vw, 28px);
  margin-bottom: 14px;
}

.ec-empty-lede {
  max-width: 62ch;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.ec-empty-list {
  counter-reset: eclist;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 22px 0 18px;
  padding: 20px 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
}

.ec-empty-list li {
  position: relative;
  counter-increment: eclist;
  padding-left: 34px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.ec-empty-list li::before {
  content: counter(eclist);
  position: absolute;
  left: 0;
  top: 1px;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--brand-tint);
  color: var(--brand-deep);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 600;
}

.ec-empty-list strong {
  color: var(--ink);
}

/* ---- Summary card -------------------------------------------------------- */
.ec-results[hidden] {
  display: none;
}

.ec-summary-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
}

.ec-summary-head h2 {
  font-size: clamp(24px, 2.4vw, 32px);
}

.ec-stats {
  margin: 8px 0 0;
  font-variant-numeric: tabular-nums;
}

.ec-summary-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

.ec-copy-status {
  margin: 0;
  max-width: 24ch;
}

.ec-copy-status:empty {
  display: none;
}

/* Three tallies, one per verdict. Counts of checks — never a band. */
.ec-tallies {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.ec-tally {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px;
  border-radius: var(--r-input);
  border: 1px solid transparent;
}

.ec-tally-num {
  font-size: clamp(28px, 3.4vw, 40px);
  line-height: 1;
}

.ec-tally-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.005em;
}

.ec-tally--good { background: var(--ok-tint); border-color: rgba(30, 122, 79, 0.18); color: var(--ok); }
.ec-tally--look { background: var(--warn-tint); border-color: rgba(180, 83, 9, 0.18); color: var(--warn); }
.ec-tally--fix  { background: var(--err-tint); border-color: rgba(194, 65, 12, 0.18); color: var(--err); }

.ec-summary-note {
  margin: 14px 0 0;
}

/* ---- What to do next ------------------------------------------------------ */
.ec-todo {
  margin-top: 24px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}

.ec-todo-title {
  font-size: 18px;
  margin-bottom: 12px;
}

.ec-todo-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding-left: 20px;
}

.ec-todo-list li {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.ec-todo-list strong {
  color: var(--ink);
}

.ec-todo-clear {
  margin: 0;
  max-width: 68ch;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

/* ---- The ten check cards --------------------------------------------------
   One column on a phone, two from 760px: ten cards in one column is a very
   long scroll on a laptop. */
.ec-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-top: 16px;
}

.ec-check {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--ground);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-2);
  border-radius: var(--r-input);
  padding: 20px 22px;
}

.ec-check--good { border-left-color: var(--ok); }
.ec-check--look { border-left-color: var(--warn); }
.ec-check--fix  { border-left-color: var(--err); }

.ec-check-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.ec-check-head h3 {
  font-size: 18px;
  letter-spacing: -0.015em;
}

.ec-chip {
  flex: none;
}

.ec-chip--good { background: var(--ok-tint); color: var(--ok); }
.ec-chip--look { background: var(--warn-tint); color: var(--warn); }
.ec-chip--fix  { background: var(--err-tint); color: var(--err); }

.ec-finding {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
}

.ec-detail {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

.ec-detail li {
  position: relative;
  padding-left: 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-2);
}

.ec-detail li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 4px;
  height: 4px;
  border-radius: 999px;
  background: var(--line-2);
}

/* "Why it matters" — the marking idea behind the check, in our own words. */
/* Pinned to the bottom: cards in a row share a height through the grid, so
   the descriptor note lines up across the pair instead of leaving a hole. */
.ec-why {
  margin: 14px 0 0;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-3);
}

/* ---- CTA ------------------------------------------------------------------ */
.ec-cta-section {
  padding-block: clamp(40px, 5vw, 72px) 0;
}

.ec-cta {
  max-width: 940px;
  margin-inline: auto;
  text-align: center;
}

.ec-cta .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.ec-cta h2 {
  font-size: clamp(28px, 3vw, 42px);
}

.ec-cta p {
  max-width: 56ch;
  margin: 16px auto 0;
  font-size: 16px;
  line-height: 1.6;
}

.ec-cta .store-badges {
  justify-content: center;
  margin-top: 28px;
}

/* ---- Breakpoints ---------------------------------------------------------- */
@media (min-width: 560px) {
  .ec-tally {
    padding: 16px 14px;
  }

  .ec-tally-label {
    font-size: 13px;
  }

  .ec-hero-flag {
    flex-direction: row;
    align-items: flex-start;
  }

  .ec-hero-flag .chip {
    margin-top: 1px;
  }

  .ec-timer-actions .note {
    flex: 1 1 auto;
  }
}

@media (min-width: 760px) {
  .ec-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ec-summary-actions {
    align-items: flex-end;
  }

  .ec-copy-status {
    text-align: right;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ec-timer-track > i,
  .ec-ghost {
    transition: none;
  }
}

/* -------------------------------------------------------------------------
   34. Writing descriptors
   -------------------------------------------------------------------------
   /ielts-writing-band-descriptors — the task × criterion × band explorer.
   It reuses section 29 wholesale (the panel, the criterion tabs, the band
   segmented control, the cell, the compare view, the glance columns, the
   facts cards and the full-table <details>); everything here is what that
   page needs on top: a third control for the task, the two criteria the
   Speaking page does not have, the "illustration" block that replaces the
   cue-card quotes, and the section sub-headings that come with having two
   tasks on one page.

   Criterion colours follow the same discipline: the response criterion
   (Task Response / Task Achievement) violet, vocabulary blue, grammar
   green, and coherence the neutral ink chip.
   ------------------------------------------------------------------------- */

/* ---- The task switch ----------------------------------------------------- */
.wd-taskrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
}

.wd-control-label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.wd-tasks {
  display: flex;
  flex: 1;
  min-width: 0;
  gap: 4px;
  padding: 4px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
}

.wd-task {
  flex: 1;
  min-width: 0;
  padding: 10px 8px;
  border: none;
  border-radius: 10px;
  background: none;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.wd-task:hover {
  color: var(--ink);
}

.wd-task:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.wd-task[aria-checked="true"] {
  background: var(--ink);
  color: #fff;
}

.wd-task-abbr {
  display: none;
}

/* ---- The two criteria the Speaking page does not have -------------------- */
.bd-tab[hidden] {
  display: none;
}

.bd-tab-tr[aria-selected="true"],
.bd-tab-ta[aria-selected="true"] { background: var(--violet-tint); color: var(--violet); }
.bd-tab-cc[aria-selected="true"] { background: #e8eaf0; color: var(--ink); }

.chip-tr,
.chip-ta { background: var(--violet-tint); color: var(--violet); }
.chip-cc { background: #e8eaf0; color: var(--ink); }

.bd-cell[data-crit="tr"],
.bd-cell[data-crit="ta"] { --bd-accent: var(--violet); --bd-accent-tint: var(--violet-tint); }
.bd-cell[data-crit="cc"] { --bd-accent: var(--ink); --bd-accent-tint: #e8eaf0; }

.bd-glance-tr,
.bd-glance-ta { --bd-accent: var(--violet); }
.bd-glance-cc { --bd-accent: var(--ink); }

/* ---- The cell header carries the task as well as the criterion ----------- */
.wd-cell-labels {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

.wd-task-tag {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ---- "What it looks like" -----------------------------------------------
   The site has no annotated Writing samples, so this block is original
   example writing rather than a quotation — the tag says so, and the rule
   below gives it the same weight as the Speaking page's quote block without
   dressing it up as a real candidate answer. */
.wd-illus {
  margin: 0;
}

.wd-illus-note {
  margin: 0 0 10px;
  max-width: 66ch;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-3);
}

.wd-illus-line {
  margin: 0 0 10px;
  padding: 16px 18px;
  max-width: 66ch;
  background: var(--ground-2);
  border-left: 3px solid var(--bd-accent);
  border-radius: 0 var(--r-input) var(--r-input) 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
}

.wd-illus-line:last-child {
  margin-bottom: 0;
}

.bd-cell-static .wd-illus-line {
  background: var(--ground);
}

/* ---- Two tasks on one page ----------------------------------------------- */
.wd-glance-title,
.wd-table-title {
  margin: 36px 0 0;
  font-size: 20px;
  letter-spacing: -0.02em;
}

.wd-glance-note,
.wd-shared-note {
  margin: 18px 0 0;
  max-width: 74ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.wd-shared-note {
  margin-bottom: -10px;
}

/* ---- Breakpoints --------------------------------------------------------- */
@media (max-width: 639px) {
  .wd-task-full { display: none; }
  .wd-task-abbr { display: inline; }

  .wd-taskrow {
    flex-direction: column;
    align-items: stretch;
  }

  .wd-tasks {
    flex: none;
  }

  .wd-task {
    padding: 10px 4px;
    font-size: 13px;
    letter-spacing: 0.01em;
  }
}

@media (min-width: 1000px) {
  .wd-cell-labels {
    grid-column: 1;
    align-self: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .wd-task {
    transition: none;
  }
}

/* -------------------------------------------------------------------------
   35. Questions and mock test
   -------------------------------------------------------------------------
   /questions/ and /questions/<slug>/ — the Part 1 / Part 3 question bank,
   built from the same shapes as the vocabulary pages (section 28) — and
   /ielts-speaking-mock-test, the full timed simulator, which borrows the
   self-assessment's card-in-a-tinted-panel layout (section 27) and the
   practice panel's countdown typography (section 22).
   ------------------------------------------------------------------------- */

/* ---- Topic page: rhythm --------------------------------------------------- */
.q-page {
  padding-block: 64px;
}

.q-content {
  max-width: 900px;
  margin-inline: auto;
}

/* <section>s inside an article, not page bands: drop the global section
   rhythm and space them from each other instead. */
.q-content > section {
  padding-block: 0;
  margin-top: clamp(52px, 6vw, 84px);
}

.q-content > section > h2 {
  font-size: clamp(26px, 2.8vw, 36px);
  line-height: 1.06;
  letter-spacing: -0.025em;
  margin-bottom: 10px;
}

.q-section-lede {
  max-width: 62ch;
  margin-bottom: 28px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---- Topic page: header --------------------------------------------------- */
.q-header h1 {
  font-size: clamp(34px, 4.6vw, 56px);
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
  margin-bottom: 12px;
}

.q-intro {
  max-width: 66ch;
}

.q-intro p {
  font-size: 17px;
  line-height: 1.62;
  color: var(--ink-2);
  margin-bottom: 16px;
}

.q-intro p:last-child {
  margin-bottom: 0;
}

.q-intro a {
  color: var(--brand-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- The question lists ---------------------------------------------------
   A numbered list where the number is the examiner's turn counter: it sits
   in its own gutter column so the question text aligns whether the number
   is one digit or two. */
.q-list {
  counter-reset: q-item;
  list-style: none;
  padding-left: 0;
  border-top: 1px solid var(--line);
}

.q-item {
  counter-increment: q-item;
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 2px 12px;
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
}

.q-item::before {
  content: counter(q-item);
  grid-row: 1 / span 2;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--ink-3);
}

.q-text {
  font-size: 17px;
  line-height: 1.5;
  color: var(--ink);
  letter-spacing: -0.01em;
}

.q-tip {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-3);
}

.q-tip-label {
  display: inline;
  margin-right: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
}

/* ---- Practise this topic --------------------------------------------------- */
/* `.q-content > section` above (which resets padding-block to 0) is more
   specific than a bare `.q-practise`, so this rule needs the same `.q-content >`
   prefix to win and keep its own padding. */
.q-content > .q-practise {
  padding: clamp(32px, 5vw, 56px);
}

.q-practise .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.q-practise-list {
  list-style: none;
  padding-left: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 28px;
}

.q-practise-list li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line-2);
}

.q-practise-list li:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.q-practise-link {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}

.q-practise-link:hover,
.q-practise-link:focus-visible {
  color: var(--brand-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.q-practise-note {
  font-size: 14px;
  color: var(--ink-3);
}

.q-practise-cta .note {
  margin-top: 12px;
}

/* ---- Hub ------------------------------------------------------------------ */
.q-hub-count {
  margin-top: 18px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-2);
}

.q-hub-cta {
  margin-top: 24px;
}

.q-hub-cta .note {
  margin-top: 10px;
}

.q-group {
  margin-top: clamp(44px, 5vw, 72px);
}

.q-group > h2 {
  font-size: clamp(24px, 2.4vw, 32px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin-bottom: 22px;
}

.q-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.q-tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 24px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.q-tile:hover,
.q-tile:focus-visible {
  border-color: var(--line-2);
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}

.q-tile h3 {
  font-size: 19px;
  letter-spacing: -0.02em;
}

.q-tile-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-3);
}

.q-tile-teaser {
  margin-top: 6px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}

.q-tile .arrow-link {
  margin-top: auto;
  padding-top: 14px;
}

/* -------------------------------------------------------------------------
   Mock test simulator
   ------------------------------------------------------------------------- */
.mt-hero {
  padding-block: clamp(56px, 7vw, 96px) 0;
}

.mt-hero-head {
  max-width: 820px;
  margin-inline: auto;
  text-align: center;
}

.mt-hero-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.mt-hero-head h1 {
  font-size: clamp(38px, 5.2vw, 70px);
}

.mt-hero-sub {
  margin: 20px auto 0;
  max-width: 56ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-2);
}

.mt-app-section {
  padding-block: clamp(28px, 4vw, 48px) 0;
}

.mt-panel {
  max-width: 880px;
  margin-inline: auto;
  padding: clamp(12px, 1.6vw, 24px);
}

/* ---- Cards ---------------------------------------------------------------- */
.mt-card {
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: clamp(22px, 3.2vw, 40px);
}

.mt-card[hidden] {
  display: none;
}

.mt-card:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.mt-card > .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.mt-card h2 {
  font-size: clamp(26px, 2.6vw, 34px);
  line-height: 1.1;
  margin-bottom: 16px;
}

.mt-lede {
  max-width: 60ch;
  margin-bottom: 22px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.mt-block-title {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 12px;
}

/* ---- Challenge banner ------------------------------------------------------ */
.mt-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  padding: 14px 18px;
  background: var(--brand-tint);
  border-radius: var(--r-card);
  font-size: 15px;
  font-weight: 600;
  color: var(--brand-ink);
}

.mt-banner[hidden] {
  display: none;
}

/* ---- Setup ---------------------------------------------------------------- */
.mt-setup-list {
  counter-reset: mt-step;
  list-style: none;
  padding-left: 0;
  border-top: 1px solid var(--line);
  margin-bottom: 18px;
}

/* The numbered key is absolutely positioned rather than a grid column:
   these items mix a <strong> lead-in with plain text, and grid would
   blockify the <strong> into a cell of its own. */
.mt-setup-list li {
  counter-increment: mt-step;
  position: relative;
  padding: 14px 0 14px 42px;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.mt-setup-list li::before {
  content: counter(mt-step);
  position: absolute;
  left: 0;
  top: 13px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: var(--ground-2);
  color: var(--ink-3);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
}

.mt-setup-list strong {
  color: var(--ink);
  font-weight: 600;
}

.mt-noscript,
.mt-error {
  margin-top: 18px;
  padding: 16px 18px;
  background: var(--ground-2);
  border: 1px solid var(--line);
  border-radius: var(--r-input);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.mt-error {
  background: var(--warn-tint);
  border-color: var(--warn-tint);
  color: var(--warn);
}

.mt-error[hidden] {
  display: none;
}

.mt-setup-controls {
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

.mt-setup-controls[hidden] {
  display: none;
}

.mt-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 20px;
}

.mt-field label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mt-field select {
  width: 100%;
  max-width: 420px;
  padding: 13px 14px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.3;
}

.mt-field select:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.mt-field-note {
  font-size: 13px;
  color: var(--ink-3);
}

.mt-toggles {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 24px;
}

.mt-toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  color: var(--ink-2);
  cursor: pointer;
}

.mt-toggle[hidden] {
  display: none;
}

.mt-toggle input {
  width: 18px;
  height: 18px;
  accent-color: var(--brand);
}

/* ---- Runner ---------------------------------------------------------------- */
.mt-runner-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

/* Wins over the generic `.mt-card h2` size above: this h2 is a small part
   label, not a card title — the countdown below it is the headline. */
.mt-card h2.mt-part-label {
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 0;
}

.mt-part-timer {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-3);
}

.mt-part-timer b {
  margin-left: 6px;
  color: var(--ink);
}

/* The big countdown, in the display face with tabular numerals so mm:ss
   never changes width as it ticks. */
.mt-timer {
  margin-top: 22px;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: clamp(56px, 12vw, 92px);
  font-weight: 600;
  line-height: 0.95;
  letter-spacing: -0.035em;
  color: var(--ink);
}

.mt-progress {
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
  margin-top: 14px;
}

.mt-progress > i {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--brand);
  transition: width 1s linear;
}

.mt-timer-note {
  margin-top: 10px;
  font-size: 13px;
  color: var(--ink-3);
}

.mt-lead {
  margin-top: 26px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--brand-deep);
}

.mt-lead[hidden],
.mt-question[hidden],
.mt-opener[hidden],
.mt-cue[hidden],
.mt-prep[hidden],
.mt-record-note[hidden],
.mt-audio-wrap[hidden],
.mt-trigger-back[hidden],
.mt-cue-explain[hidden] {
  display: none;
}

.mt-question {
  margin-top: 16px;
  font-family: var(--font-display);
  font-size: clamp(24px, 3.4vw, 34px);
  font-weight: 600;
  line-height: 1.16;
  letter-spacing: -0.025em;
  color: var(--ink);
  text-wrap: balance;
}

.mt-opener {
  margin-top: 18px;
}

.mt-opener-line {
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  font-size: 17px;
  line-height: 1.5;
  color: var(--ink-2);
}

.mt-opener-line:last-child {
  border-bottom: 0;
  color: var(--ink);
  font-weight: 600;
}

/* The exam-style cue-card box, same shape as the library's. */
.mt-cue {
  margin-top: 20px;
  padding: 24px;
  background: var(--ground-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-card);
}

.mt-cue-label {
  display: inline-block;
  margin-bottom: 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mt-cue-title {
  font-family: var(--font-display);
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.mt-cue-should {
  margin-top: 14px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}

.mt-cue-bullets {
  margin: 8px 0 0;
  padding-left: 20px;
  list-style: disc;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.mt-cue-explain {
  margin-top: 12px;
  font-size: 15px;
  font-style: italic;
  line-height: 1.55;
  color: var(--ink-2);
}

.mt-prep {
  margin-top: 20px;
}

.mt-prep label {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mt-prep textarea {
  display: block;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  background: var(--ground);
  color: var(--ink);
  font-family: inherit;
  font-size: 16px;
  line-height: 1.55;
  resize: vertical;
}

.mt-prep textarea:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-color: var(--brand);
}

.mt-record-note {
  margin-top: 16px;
  padding: 10px 14px;
  background: var(--ground-2);
  border-radius: var(--r-input);
  font-size: 13px;
  color: var(--ink-2);
}

.mt-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 26px;
}

.mt-keyhint {
  margin-top: 12px;
}

.mt-keyhint kbd {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  background: var(--ground);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-2);
}

/* ---- Done ------------------------------------------------------------------ */
.mt-times {
  list-style: none;
  padding-left: 0;
  border-top: 1px solid var(--line);
  margin-bottom: 30px;
}

.mt-times li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
  color: var(--ink-2);
}

.mt-times li.is-total {
  font-weight: 600;
  color: var(--ink);
}

.mt-times b {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
}

.mt-audio-wrap,
.mt-trigger-back,
.mt-next,
.mt-share {
  margin-bottom: 30px;
}

.mt-audio-note {
  margin: -6px 0 14px;
  font-size: 13px;
  color: var(--ink-3);
}

.mt-audio-list {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.mt-audio {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  background: var(--ground-2);
  border-radius: var(--r-input);
}

.mt-audio-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}

.mt-audio audio {
  width: 100%;
}

.mt-audio-save {
  align-self: flex-start;
}

.mt-trigger-back-text {
  padding: 14px 16px;
  background: var(--ground-2);
  border-radius: var(--r-input);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
  white-space: pre-wrap;
}

.mt-next-list {
  list-style: none;
  padding-left: 0;
  border-top: 1px solid var(--line);
}

.mt-next-list li {
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-2);
}

.mt-cta {
  margin-bottom: 30px;
  padding: clamp(24px, 3.4vw, 40px);
  border-radius: var(--r-card);
}

.mt-cta .eyebrow {
  display: block;
  margin-bottom: 12px;
}

.mt-cta h3 {
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin-bottom: 12px;
}

.mt-cta p {
  max-width: 56ch;
  margin-bottom: 22px;
  font-size: 15px;
  line-height: 1.6;
}

.mt-share-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}

.mt-share-btn {
  padding: 12px 18px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-btn);
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: border-color 0.15s ease;
}

.mt-share-btn:hover {
  border-color: var(--ink);
}

.mt-share-btn:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.mt-challenge {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  width: 100%;
}

.mt-challenge-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-3);
}

.mt-challenge-input {
  width: 100%;
  max-width: 260px;
  padding: 11px 14px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-input);
  background: var(--ground);
  color: var(--ink);
  font-family: inherit;
  font-size: 16px;
}

.mt-challenge-input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-color: var(--brand);
}

.mt-copy-status {
  min-height: 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
}

.mt-done-foot {
  padding-top: 22px;
  border-top: 1px solid var(--line);
}

/* ---- Below the simulator ---------------------------------------------------- */
.mt-section-head {
  max-width: 46ch;
  margin-bottom: 36px;
}

.mt-section-head .eyebrow {
  display: block;
  margin-bottom: 14px;
}

.mt-section-head h2 {
  margin-bottom: 16px;
}

.mt-real-grid,
.mt-links-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

.mt-real-col {
  padding: 26px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}

.mt-real-time {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--brand);
  margin-bottom: 8px;
}

.mt-real-col h3 {
  font-size: 21px;
  letter-spacing: -0.02em;
  margin-bottom: 10px;
}

.mt-real-col p {
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.mt-real-total {
  margin-top: 24px;
}

.mt-how-list {
  list-style: none;
  padding-left: 0;
  border-top: 1px solid var(--line);
  max-width: 76ch;
}

.mt-how-list li {
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.mt-how-list strong {
  color: var(--ink);
  font-weight: 600;
}

.mt-link-tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 26px;
  background: var(--ground-2);
  border: 1px solid transparent;
  border-radius: var(--r-card);
  transition: border-color 0.2s ease, transform 0.2s ease;
}

.mt-link-tile:hover,
.mt-link-tile:focus-visible {
  border-color: var(--line-2);
  transform: translateY(-2px);
}

.mt-link-tile h3 {
  font-size: 20px;
  letter-spacing: -0.02em;
}

.mt-link-tile p {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
}

.mt-link-tile .arrow-link {
  margin-top: auto;
  padding-top: 10px;
}

/* ---- Breakpoints ------------------------------------------------------------ */
@media (min-width: 600px) {
  .q-item {
    grid-template-columns: 40px minmax(0, 1fr);
  }

  .mt-share-actions {
    gap: 16px;
  }
}

@media (min-width: 768px) {
  .q-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mt-real-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .mt-links-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mt-toggles {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 24px;
  }
}

@media (min-width: 1024px) {
  .q-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .mt-links-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

@media (prefers-reduced-motion: reduce) {
  .q-tile,
  .q-tile:hover,
  .mt-link-tile,
  .mt-link-tile:hover,
  .mt-share-btn {
    transition: none;
    transform: none;
  }

  .mt-progress > i {
    transition: none;
  }
}

/* -------------------------------------------------------------------------
   36. Tools hub
   -------------------------------------------------------------------------
   /tools — the index of every browser-based tool on the site. Three groups
   of tiles built from the questions hub's tile (section 35) plus a chip that
   says which paper the tool is for, then the dark CTA panel (section 25).
   ------------------------------------------------------------------------- */
.tools-hero {
  padding-block: clamp(56px, 7vw, 96px) 0;
}

.tools-hero-head {
  max-width: 760px;
}

.tools-hero-head h1 {
  margin-top: 14px;
}

.tools-hero-sub {
  margin-top: 18px;
  max-width: 58ch;
  font-size: 18px;
  line-height: 1.55;
  color: var(--ink-2);
}

.tools-list {
  padding-block: clamp(40px, 5vw, 64px) 0;
}

.tools-group + .tools-group {
  margin-top: clamp(44px, 5vw, 72px);
}

.tools-group > h2 {
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 20px;
}

.tools-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.tools-tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 24px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.tools-tile:hover,
.tools-tile:focus-visible {
  border-color: var(--line-2);
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}

.tools-tile h3 {
  font-size: 19px;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.tools-tile p {
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
}

.tools-tile .arrow-link {
  margin-top: auto;
  padding-top: 14px;
}

/* Which paper the tool is for. Deliberately not the criterion chips from
   section 25 — same shape, different vocabulary. */
.chip-speaking { background: var(--violet-tint); color: var(--violet); }
.chip-writing { background: var(--brand-tint); color: var(--brand-deep); }
.chip-both { background: #e8eaf0; color: var(--ink); }

.tools-cta-section {
  padding-block: clamp(56px, 7vw, 96px) 0;
}

.tools-cta h2 {
  margin-top: 14px;
  max-width: 20ch;
}

.tools-cta p {
  margin-top: 18px;
  max-width: 68ch;
  color: rgba(255, 255, 255, 0.78);
}

.tools-cta .store-badges {
  margin-top: 28px;
}

@media (min-width: 600px) {
  .tools-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .tools-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (prefers-reduced-motion: reduce) {
  .tools-tile,
  .tools-tile:hover {
    transition: none;
    transform: none;
  }
}

/* -------------------------------------------------------------------------
   37. Guides
   -------------------------------------------------------------------------
   /guides/<slug>/ — a page built for one search phrasing. It reuses the blog
   post shell wholesale (section 19: .post-content's prose + sticky-TOC grid,
   .post-full, .post-body, the FAQ and CTA blocks), and adds three things of
   its own, in page order:

     .guide-answer    the "Quick answer" card — also used by any blog post
                      that carries an `answer:` in its front matter, where it
                      appears without the conversion row below.
     .guide-convert   the conversion row: badges and a one-line pitch on the
                      left, a compact mockup of one app screen on the right
                      (stacked, mockup last, below 900px).
     .guide-mock-*    those mockups. The score-report one reuses the hero's
                      own .scr-* rules (section 26) unchanged; everything
                      here is the card around them plus the four other
                      feature cards.

   Plus the /guides/ index, which reuses .blog-index-* (section 19) and only
   adds the per-type group heading and its card grid.
   ------------------------------------------------------------------------- */

/* The guide page runs tighter above the fold than a blog post: the quick
   answer, the badges and the mockup all have to be reachable without
   scrolling on a laptop, so the header rhythm is compressed rather than the
   content cut. */
.guide-page {
  padding-block: 40px 64px;
}

.guide-page .post-header h1 {
  font-size: clamp(1.85rem, 3.4vw, 2.6rem);
  line-height: 1.08;
}

.guide-page .post-byline {
  margin-bottom: 0;
}

/* ---- Quick answer ------------------------------------------------------- */
.guide-answer {
  margin-top: 24px;
  padding: 22px 24px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-left: 4px solid var(--brand);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}

.guide-answer-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 10px;
}

.guide-answer p:not(.guide-answer-label) {
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
}

.guide-answer p + p:not(.guide-answer-label) {
  margin-top: 12px;
}

/* On a blog post the block sits between the byline and the body, so it needs
   the bottom margin the byline gave up. */
.post-page:not(.guide-page) .guide-answer {
  margin-bottom: 32px;
}

/* ---- Conversion row ----------------------------------------------------- */
.guide-convert {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-top: 20px;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--line);
}

.guide-convert-main {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}

.guide-convert-line {
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 46ch;
}

.guide-convert .store-badges {
  margin: 0;
}

.guide-convert .note {
  font-size: 13px;
  color: var(--ink-3);
}

/* ---- Feature mockups ---------------------------------------------------- */
.guide-mock {
  width: 100%;
  max-width: 360px;
  flex: 0 0 auto;
}

.guide-mock-card {
  padding: 18px;
  border-radius: 20px;
  background: var(--ground);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  text-align: left;
}

/* The score report reuses the hero device screen's own cards, so it takes
   the device screen's ground instead of white. */
.guide-mock-screen {
  padding: 12px;
  background: var(--ground-2);
  font-size: 13px;
  line-height: 1.35;
  color: var(--ink);
}

.guide-mock-screen .scr-card:last-child {
  margin-bottom: 0;
}

.guide-mock-cap {
  margin-top: 8px;
  font-size: 12px;
  color: var(--ink-3);
}

.guide-mock-title {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.guide-mock-flag {
  margin-top: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.guide-mock-rows {
  display: flex;
  flex-direction: column;
  margin-top: 8px;
  border-top: 1px solid var(--line);
}

.guide-mock-rows li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink-2);
}

.guide-mock-rows li:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.guide-mock-rows b {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

.guide-mock-sessions b {
  color: var(--ink-3);
  font-weight: 600;
}

.guide-mock-bars {
  margin-top: 16px;
}

/* ---- Mock test card ----------------------------------------------------- */
.guide-mock-timer {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 14px;
}

.guide-mock-time {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 34px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--brand);
}

.guide-mock-timer-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.guide-mock-cue {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
}

.guide-mock-note {
  margin-top: 6px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-3);
}

/* ---- Band-range card ---------------------------------------------------- */
.guide-mock-range-value {
  margin-top: 10px;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 15px;
  color: var(--ink-2);
}

.guide-mock-range-value b {
  /* The 30px numeral's side bearings swallow the surrounding word spaces. */
  margin-inline: 1px 4px;
  font-size: 30px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.guide-mock-arrow {
  color: var(--ink-3);
  padding-inline: 2px;
}

.guide-mock-range-bar {
  height: 8px;
  margin-top: 14px;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}

.guide-mock-range-bar > i {
  display: block;
  height: 100%;
  margin-left: 58%;
  width: 14%;
  border-radius: 999px;
  background: var(--brand);
}

/* ---- Related ------------------------------------------------------------ */
/* Kept to the prose column's width, like .post-faq and .post-cta (section
   19): at >=1024px the sticky TOC sidebar can still be pinned over the right
   column this far down the page, and a full-width grid here would run under
   it. */
.guide-related {
  max-width: 680px;
  margin-top: 48px;
}

.guide-related > h2 {
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 20px;
}

.guide-related-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.guide-related-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 22px;
  background: var(--ground);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.guide-related-card:hover,
.guide-related-card:focus-visible {
  border-color: var(--line-2);
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}

.guide-related-card h3 {
  font-size: 17px;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.guide-related-card p {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}

/* ---- The /guides/ index ------------------------------------------------- */
.guide-hub-count {
  margin-top: 16px;
  font-size: 14px;
  color: var(--ink-3);
}

/* A <section> per type, so the group headings nest properly — but the
   global `section { padding-block: var(--rhythm-sm) }` (section 3) is meant
   for full-width landing-page bands, not for list groups inside an index.
   Spacing here comes from the margin below instead. */
.guide-group {
  padding-block: 0;
}

.guide-group + .guide-group {
  margin-top: clamp(40px, 5vw, 64px);
}

.guide-group > h2 {
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.guide-group-blurb {
  margin-top: 8px;
  margin-bottom: 20px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 62ch;
}

.guide-index-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

.guide-index-card h3 {
  font-size: 1.15rem;
  letter-spacing: -0.02em;
  margin: 12px 0 8px;
}

/* ---- Responsive --------------------------------------------------------- */
@media (min-width: 600px) {
  .guide-index-grid,
  .guide-related-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Tablet and up: the badges and the mockup sit side by side, mockup right. */
@media (min-width: 900px) {
  .guide-convert {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
    gap: 40px;
  }

  .guide-convert-main {
    flex: 1 1 auto;
    padding-top: 4px;
  }
}

/* Small desktop up: .post-content becomes a prose + sidebar grid (section
   19) and .post-full spans both columns, which would stretch the quick
   answer's measure to ~90 characters. Cap it at the prose column's own
   width instead, so the card, the badges under it and the article all share
   one left column and one right edge. */
@media (min-width: 1024px) {
  .guide-answer {
    max-width: 760px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .guide-related-card,
  .guide-related-card:hover {
    transition: none;
    transform: none;
  }
}

/* -------------------------------------------------------------------------
   38. Language switcher
   -------------------------------------------------------------------------
   Rendered by build.py only once a second locale actually has pages (see
   render_lang_switcher / render_lang_switcher_sheet). Two shapes: a compact
   EN · UZ control sitting in .navbar-actions at >=1024px, and a labelled row
   at the foot of the mobile sheet below that.

   Written entirely in logical properties (inline/block, text-align: start) so
   a right-to-left locale mirrors it with no extra rules — see the RTL
   checklist in DEPLOY.md for what is still physical elsewhere. */
.nav-lang {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding-inline: 9px;
  padding-block: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  white-space: nowrap;
}

.nav-lang-link {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  text-align: start;
  color: var(--ink-3);
  transition: color 0.15s ease;
}

.nav-lang-link:hover {
  color: var(--ink);
}

.nav-lang-link.is-current {
  color: var(--ink);
  cursor: default;
}

.nav-lang-sep {
  font-size: 11px;
  line-height: 1;
  color: var(--line-2);
}

/* The sheet row only exists below 1024px, where #navPanel itself does. */
.nav-panel-lang {
  display: none;
}

@media (max-width: 1023px) {
  .nav-lang {
    display: none;
  }

  .nav-panel-lang {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 18px;
    inline-size: 100%;
    margin-block-start: 26px;
    padding-block-start: 20px;
    border-block-start: 1px solid var(--line);
  }

  .nav-panel-lang-label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: start;
    color: var(--ink-3);
  }

  /* Overrides the sheet's own big block links for this row. */
  .nav-panel .nav-lang-sheet-link {
    display: inline-block;
    inline-size: auto;
    padding-block: 0;
    border-block-end: none;
    font-family: var(--font-body);
    font-size: 15px;
    font-weight: 600;
    color: var(--ink-2);
  }

  .nav-panel .nav-lang-sheet-link.is-current {
    color: var(--ink);
  }
}

/* -------------------------------------------------------------------------
   39. Answers
   -------------------------------------------------------------------------
   /answers/<slug>/ — reuses .guide-page (the compressed above-the-fold
   rhythm) and .guide-answer/.guide-convert/.guide-related verbatim (section
   37), plus .post-faq for its Sources block (section 12). The only markup
   this page adds that nothing else on the site has is the video embed. */
.answer-video iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border-radius: var(--r-card);
}
