/*
 * TeachMe motion layer. Plan: research/lucian-motion-2026-10-20/MOTION-PLAN.md (codes G/H/HM/FT/L/S/R/M/C).
 * Timing references Lucian UX/UI #008 #212 #216 #237 #251 #258 #370 (MIT); original implementation.
 * Rules: transform/opacity/clip-path only; every moving rule sits under html:not(.tm-motion-calm);
 * hidden-before-reveal states are added by motion.js, so content stays visible without JS.
 */
:root {
  --tm-dur-1: 120ms;
  --tm-dur-2: 200ms;
  --tm-dur-3: 320ms;
  --tm-dur-4: 600ms;
  --tm-ease-out: cubic-bezier(.2, .8, .2, 1);
  --tm-ease-in-out: cubic-bezier(.45, 0, .3, 1);
  --tm-ease-spring: cubic-bezier(.34, 1.45, .64, 1);
  --tm-stagger: 60ms;
  --tm-rise: 16px;
}

@keyframes tm-rise-in { from { opacity: 0; transform: translateY(var(--tm-rise)); } to { opacity: 1; transform: none; } }
@keyframes tm-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes tm-drop-in { from { opacity: 0; transform: translateY(-6px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes tm-slide-down { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@keyframes tm-mask-up { from { clip-path: inset(0 0 100% 0); transform: translateY(18px); } to { clip-path: inset(-25% -5% -25% -5%); transform: none; } }
@keyframes tm-pop { 0% { transform: scale(.8); } 60% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes tm-burst { 0% { transform: scale(.85); } 45% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes tm-ring { from { opacity: .7; transform: scale(.6); } to { opacity: 0; transform: scale(1.6); } }
@keyframes tm-shake { 0%, 100% { transform: none; } 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }
@keyframes tm-spin { to { transform: rotate(360deg); } }
@keyframes tm-pulse { 50% { opacity: .55; } }
@keyframes tm-check-draw { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }

/* ---------- G03/G04 · focus ring and anchor offset ---------- */
:where(a, button, summary, input, select, textarea, [tabindex]) { transition-property: outline-offset; transition-duration: var(--tm-dur-1); }
:where(main [id], .entry-content [id]) { scroll-margin-top: 96px; }

/* ---------- G02 · replace "transition: all" on visible components ---------- */
.tm-faq-item { transition: border-color var(--tm-dur-2) var(--tm-ease-out), box-shadow var(--tm-dur-2) var(--tm-ease-out); }

/* ---------- Reveal on scroll (HM06 HM07 HM08 HM11 HM18 L01 C02–C05 C09 FT01 …) ---------- */
html:not(.tm-motion-calm) .tm-reveal:not(.is-in) { opacity: 0; transform: translateY(var(--tm-rise)); }
html:not(.tm-motion-calm) .tm-reveal.is-in:not(.is-instant) {
  animation: tm-rise-in var(--tm-dur-4) var(--tm-ease-out) both;
  animation-delay: calc(var(--tm-i, 0) * var(--tm-stagger));
}

/* ---------- H01 · desktop menu underline (#373 slide-in) ---------- */
@media (min-width: 992px) {
  .tm-menu > li:not(.tm-menu-item-lang) > a { position: relative; }
  .tm-menu > li:not(.tm-menu-item-lang) > a::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 2px; border-radius: 2px;
    background: currentColor; transform: scaleX(0); transform-origin: right; pointer-events: none;
  }
  .tm-menu > li:not(.tm-menu-item-lang) > a:is(:hover, :focus-visible)::after,
  .tm-menu > li.current-menu-item > a::after { transform: scaleX(1); transform-origin: left; }
  html:not(.tm-motion-calm) .tm-menu > li > a::after { transition: transform var(--tm-dur-3) var(--tm-ease-out); }
}

/* ---------- H03 · language dropdown ---------- */
.tm-lang-chevron { transition: transform var(--tm-dur-2) var(--tm-ease-out); }
.tm-menu-item-lang:is(.is-open, .is-hovered) .tm-lang-chevron { transform: rotate(180deg); }
html:not(.tm-motion-calm) .tm-menu-item-lang:is(.is-open, .is-hovered) .tm-lang-dropdown { animation: tm-drop-in var(--tm-dur-2) var(--tm-ease-out) both; }
html.tm-motion-calm .tm-lang-chevron { transition: none; }

/* ---------- H04 · header hides while reading down on mobile (#212) ---------- */
html:not(.tm-motion-calm) .tm-header { transition: transform var(--tm-dur-3) var(--tm-ease-out), box-shadow var(--tm-dur-2) var(--tm-ease-out); }
@media (max-width: 991px) {
  html:not(.tm-motion-calm) .tm-header.tm-header--away { transform: translateY(calc(-100% - 2px)); box-shadow: none; }
}

/* ---------- H05 HM03 HM15 FT01 · press feedback on primary actions ---------- */
:is(.tm-btn-request, .tm-hero-cta, .s4-btn, .tm-footer-button, .tme-button, .tme-intake [data-next], .tme-intake [data-send], .tme-auth [type=submit], .wp-block-search__button) { -webkit-tap-highlight-color: transparent; }
html:not(.tm-motion-calm) :is(.tm-btn-request, .tm-hero-cta, .s4-btn, .tm-footer-button, .tme-button, .tme-intake [data-next], .tme-intake [data-back], .tme-intake [data-send], .tme-auth [type=submit], .wp-block-search__button):active { transform: scale(.97); transition: transform var(--tm-dur-1) var(--tm-ease-out); }

/* ---------- H06 H07 · mobile menu panel, staggered items, dim backdrop (#286/#324) ---------- */
@media (max-width: 991px) {
  html:not(.tm-motion-calm) .tm-navigation.tm-navigation-open { animation: tm-slide-down var(--tm-dur-3) var(--tm-ease-out) both; transform-origin: top; }
  html:not(.tm-motion-calm) .tm-navigation.tm-navigation-open .tm-menu > li { animation: tm-rise-in var(--tm-dur-3) var(--tm-ease-out) both; animation-delay: calc(60ms + var(--tm-i, 0) * 40ms); --tm-rise: 8px; }
  body:has(.tm-navigation.tm-navigation-open)::after {
    content: ""; position: fixed; inset: 0; z-index: 999; background: rgb(7 17 71 / 45%); pointer-events: none;
  }
  html:not(.tm-motion-calm) body:has(.tm-navigation.tm-navigation-open)::after { animation: tm-fade-in var(--tm-dur-3) var(--tm-ease-out) both; }
}

/* ---------- HM01 HM03 HM04 · hero entrance, once (#216 + #237) ---------- */
html:not(.tm-motion-calm) .tm-hero .tm-hero-lockup { animation: tm-rise-in 560ms var(--tm-ease-out) both; }
html:not(.tm-motion-calm) .tm-hero .tm-hero-tagline { animation: tm-rise-in 560ms var(--tm-ease-out) 80ms both; }
html:not(.tm-motion-calm) .tm-hero .tm-hero-title { animation: tm-mask-up 700ms var(--tm-ease-out) 140ms both; }
html:not(.tm-motion-calm) .tm-hero .tm-hero-lead { animation: tm-rise-in 560ms var(--tm-ease-out) 260ms both; }
html:not(.tm-motion-calm) .tm-hero .tm-hero-intro-actions { animation: tm-rise-in 560ms var(--tm-ease-out) 340ms both; }
html:not(.tm-motion-calm) .tm-hero .tm-hero-feature { animation: tm-rise-in var(--tm-dur-3) var(--tm-ease-out) both; animation-delay: calc(480ms + var(--tm-i, 0) * var(--tm-stagger)); --tm-rise: 8px; }
.tm-hero-feature:nth-child(1) { --tm-i: 0; } .tm-hero-feature:nth-child(2) { --tm-i: 1; } .tm-hero-feature:nth-child(3) { --tm-i: 2; } .tm-hero-feature:nth-child(4) { --tm-i: 3; }

/* ---------- HM05 · program marquee pauses on hover/focus/off-screen (WCAG 2.2.2) ---------- */
.tm-hero-programs:is(:hover, :focus-within, .is-offscreen) .tm-hero-programs-track { animation-play-state: paused !important; }
html:not(.tm-motion-calm) .tm-hero-program { transition: transform var(--tm-dur-2) var(--tm-ease-out), box-shadow var(--tm-dur-2) var(--tm-ease-out); }
html:not(.tm-motion-calm) .tm-hero-program:is(:hover, :focus-visible) { transform: translateY(-2px); box-shadow: 0 8px 18px rgb(7 17 71 / 12%); }
html.tm-motion-calm .tm-hero-programs-track { animation: none !important; transform: none !important; }

/* ---------- HM08 HM10 · subject cards ---------- */
.tm-home-subject { overflow: hidden; }
html:not(.tm-motion-calm) .tm-home-subject { transition: transform var(--tm-dur-2) var(--tm-ease-out), box-shadow var(--tm-dur-2) var(--tm-ease-out); }
html:not(.tm-motion-calm) .tm-subject-cover { transition: transform var(--tm-dur-4) var(--tm-ease-out), filter 500ms var(--tm-ease-out), opacity 500ms var(--tm-ease-out); }
html:not(.tm-motion-calm) .tm-home-subject:is(:hover, :focus-within) { transform: translateY(-4px); box-shadow: 0 14px 30px rgb(7 17 71 / 10%); }
html:not(.tm-motion-calm) .tm-home-subject:is(:hover, :focus-within) .tm-subject-cover { transform: scale(1.04); }

/* ---------- HM10 L01 S01 · blur-up images (#258), only while a real load is pending ---------- */
html:not(.tm-motion-calm) img.tm-img-pending { filter: blur(8px); opacity: .6; }
html:not(.tm-motion-calm) img.tm-img-loaded { transition: filter 500ms var(--tm-ease-out), opacity 500ms var(--tm-ease-out); }

/* ---------- HM11 · benefit icons pop once ---------- */
html:not(.tm-motion-calm) .s2-card.tm-reveal.is-in:not(.is-instant) .s2-icon { animation: tm-pop 450ms var(--tm-ease-spring) both; animation-delay: calc(150ms + var(--tm-i, 0) * var(--tm-stagger)); }

/* ---------- HM12 · counted stats keep their width ---------- */
.s2-stat .num { font-variant-numeric: tabular-nums; }

/* ---------- HM13 HM14 C02 · process timeline lights up while reading (#370) ---------- */
.s4-step-line { position: relative; overflow: hidden; }
.s4-step-line::after { content: ""; position: absolute; inset: 0; background: var(--tm-mint-text, #07796c); transform-origin: top; transform: scaleY(var(--tm-p, 1)); }
html:not(.tm-motion-calm) .s4-steps.tm-timeline .s4-step-line::after { transform: scaleY(var(--tm-p, 0)); }
html:not(.tm-motion-calm) .s4-steps.tm-timeline .s4-step-num { transition: background-color var(--tm-dur-3) var(--tm-ease-out), color var(--tm-dur-3) var(--tm-ease-out), box-shadow .2s ease; }
html:not(.tm-motion-calm) .s4-steps.tm-timeline .s4-step:not(.is-lit):not(:last-child) .s4-step-num { background: #9fb4c6; }
html:not(.tm-motion-calm) .s4-steps.tm-timeline .s4-step.is-lit .s4-step-num { animation: tm-pop 450ms var(--tm-ease-spring) both; }
html:not(.tm-motion-calm) .s4-steps.tm-timeline .s4-step-content { transition: opacity var(--tm-dur-4) var(--tm-ease-out), transform var(--tm-dur-4) var(--tm-ease-out); }
html:not(.tm-motion-calm) .s4-steps.tm-timeline .s4-step:not(.is-lit) .s4-step-content { opacity: .45; transform: translateX(12px); }
.tm-step-badge { transition: transform var(--tm-dur-3) var(--tm-ease-spring); }
html:not(.tm-motion-calm) .tm-step-item.tm-reveal.is-in:not(.is-instant) .tm-step-badge { animation: tm-pop 450ms var(--tm-ease-spring) both; animation-delay: calc(150ms + var(--tm-i, 0) * var(--tm-stagger)); }

/* ---------- L01 C05 · tutor and blog cards ---------- */
html:not(.tm-motion-calm) .tm-builder-post { transition: transform var(--tm-dur-2) var(--tm-ease-out), box-shadow var(--tm-dur-2) var(--tm-ease-out); }
html:not(.tm-motion-calm) .tm-builder-post:is(:hover, :focus-within) { transform: translateY(-4px); box-shadow: 0 14px 30px rgb(7 17 71 / 10%); }
.tm-builder-post .wp-block-post-featured-image { overflow: hidden; }
html:not(.tm-motion-calm) .tm-builder-post .wp-block-post-featured-image img { transition: transform var(--tm-dur-4) var(--tm-ease-out), filter 500ms var(--tm-ease-out), opacity 500ms var(--tm-ease-out); }
html:not(.tm-motion-calm) .tm-builder-post:is(:hover, :focus-within) .wp-block-post-featured-image img { transform: scale(1.04); }

/* ---------- L02 S04 · save tutor: busy while posting, burst only after the server confirmed (#022/#012) ---------- */
form .tm-fav-busy { animation: tm-pulse 900ms ease-in-out infinite; cursor: progress; }
.tm-fav-confirmed { position: relative; }
html:not(.tm-motion-calm) .tm-fav-confirmed[aria-pressed="true"] { animation: tm-burst 450ms var(--tm-ease-spring) both; }
html:not(.tm-motion-calm) .tm-fav-confirmed[aria-pressed="true"]::after {
  content: ""; position: absolute; inset: -6px; border-radius: inherit; border: 2px solid var(--tm-mint-text, #07796c);
  pointer-events: none; animation: tm-ring 600ms var(--tm-ease-out) both;
}
html.tm-motion-calm form .tm-fav-busy { animation: none; opacity: .7; }

/* ---------- L04 L09 · filter chips and empty state ---------- */
html:not(.tm-motion-calm) .tme-filter-chips a { transition: background-color var(--tm-dur-2), transform var(--tm-dur-2) var(--tm-ease-out); }
html:not(.tm-motion-calm) .tme-filter-chips a:active { transform: scale(.94); }

/* ---------- FT02 C01 · accordions (height animated by motion.js) ---------- */
details.tm-animating { overflow: hidden; }

/* ---------- FT04 · footer social ---------- */
html:not(.tm-motion-calm) .tm-footer-social-link { transition: transform var(--tm-dur-2) var(--tm-ease-out), color var(--tm-dur-2), border-color var(--tm-dur-2); }
html:not(.tm-motion-calm) .tm-footer-social-link:is(:hover, :focus-visible) { transform: translateY(-2px); }

/* ---------- FT06 · floating contact: one entrance per visit, channels fan in (#011) ---------- */
html:not(.tm-motion-calm) .tme-contact-widget.tm-contact-intro { animation: tm-rise-in 500ms var(--tm-ease-out) 1.2s both; --tm-rise: 20px; }
html:not(.tm-motion-calm) .tme-contact-menu[open] .tme-contact-list > li { animation: tm-rise-in var(--tm-dur-3) var(--tm-ease-out) both; animation-delay: calc(var(--tm-i, 0) * 50ms); --tm-rise: 12px; }
html:not(.tm-motion-calm) .tme-contact-menu[open] .tme-contact-close-icon,
html:not(.tm-motion-calm) .tme-contact-menu:not([open]) .tme-contact-open-icon { animation: tm-pop var(--tm-dur-3) var(--tm-ease-spring) both; }
.tme-contact-widget { transition: transform var(--tm-dur-3) var(--tm-ease-out); }
body.tm-has-sticky-cta .tme-contact-widget { transform: translateY(-72px); }

/* ---------- S02 · profile section nav marks where you are (#048/#275) ---------- */
.tme-profile-nav > a:not(.tme-button) { position: relative; }
.tme-profile-nav > a:not(.tme-button)::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 2px; height: 2px; border-radius: 2px;
  background: var(--tm-mint-text, #07796c); transform: scaleX(0); transform-origin: left;
}
.tme-profile-nav > a.is-current { color: var(--tm-navy, #071147); font-weight: 700; }
.tme-profile-nav > a.is-current::after { transform: scaleX(1); }
html:not(.tm-motion-calm) .tme-profile-nav > a::after { transition: transform var(--tm-dur-3) var(--tm-ease-out); }

/* ---------- S03 · mobile "Request this tutor" bar (#221) ---------- */
.tm-sticky-cta { display: none; }
@media (max-width: 760px) {
  .tm-sticky-cta {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 990; padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: rgb(255 255 255 / 96%); border-top: 1px solid #dce7e6; box-shadow: 0 -8px 24px rgb(7 17 71 / 8%);
    transform: translateY(110%); visibility: hidden;
  }
  .tm-sticky-cta.is-shown { transform: none; visibility: visible; }
  .tm-sticky-cta a { flex: 1; text-align: center; justify-content: center; }
  html:not(.tm-motion-calm) .tm-sticky-cta { transition: transform var(--tm-dur-3) var(--tm-ease-out), visibility 0s linear var(--tm-dur-3); }
  html:not(.tm-motion-calm) .tm-sticky-cta.is-shown { transition: transform var(--tm-dur-3) var(--tm-ease-out), visibility 0s; }
}

/* ---------- S05 · copy link turns into a check (#008) ---------- */
.tme-copy-link { position: relative; display: inline-flex; align-items: center; gap: 8px; }
.tme-copy-link::before {
  content: ""; width: 16px; height: 16px; flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='9' width='11' height='11' rx='2'/%3E%3Cpath d='M5 15V5a2 2 0 0 1 2-2h10'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='9' y='9' width='11' height='11' rx='2'/%3E%3Cpath d='M5 15V5a2 2 0 0 1 2-2h10'/%3E%3C/svg%3E") center / contain no-repeat;
}
.tme-copy-link.is-copied::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E");
}
.tme-copy-link.is-copied { border-color: var(--tm-mint-text, #07796c); }
html:not(.tm-motion-calm) .tme-copy-link.is-copied::before { animation: tm-pop 400ms var(--tm-ease-spring) both; }
html:not(.tm-motion-calm) .tme-copy-status.is-fresh { display: inline-block; animation: tm-drop-in var(--tm-dur-2) var(--tm-ease-spring) both; }

/* ---------- S07 S09 M03 M07 · status notices slide in ---------- */
html:not(.tm-motion-calm) :is(.tme-feedback, .tme-panel p[role="status"], .tme-auth [role="alert"], .tme-auth .tme-error, .tme-email-hint:not([hidden])) { animation: tm-slide-down var(--tm-dur-3) var(--tm-ease-out) both; }
html:not(.tm-motion-calm) .tme-auth :is([role="alert"], .tme-error) { animation: tm-slide-down var(--tm-dur-3) var(--tm-ease-out) both, tm-shake 240ms ease-in-out var(--tm-dur-3) 2; }

/* ---------- R01–R03 R09–R11 · tutor request wizard ---------- */
html:not(.tm-motion-calm) .tme-form .tme-choice { transition: background-color 150ms, border-color 150ms, transform var(--tm-dur-1) var(--tm-ease-out), box-shadow var(--tm-dur-2); }
html:not(.tm-motion-calm) .tme-form .tme-choice:active { transform: scale(.98); }
html:not(.tm-motion-calm) .tme-form .tme-choice input[type=radio]:checked { animation: tm-pop 300ms var(--tm-ease-spring) both; }
html:not(.tm-motion-calm) .tme-progress-meter::-webkit-progress-value { transition: width var(--tm-dur-3) var(--tm-ease-out); }
html:not(.tm-motion-calm) .tme-form-errors:not([hidden]) { animation: tm-slide-down var(--tm-dur-2) var(--tm-ease-out) both; }
html:not(.tm-motion-calm) .tme-form .tm-shake { animation: tm-shake 240ms ease-in-out 2; }
.tme-intake [data-send].tm-sending { display: inline-flex; align-items: center; justify-content: center; gap: 10px; cursor: progress; }
.tme-intake [data-send].tm-sending::before {
  content: ""; width: 16px; height: 16px; border-radius: 50%; flex: none;
  border: 2px solid rgb(255 255 255 / 35%); border-top-color: #fff;
}
html:not(.tm-motion-calm) .tme-intake [data-send].tm-sending::before { animation: tm-spin 900ms linear infinite; }
.tme-panel[role="status"] > h2:first-child { display: flex; align-items: center; gap: 12px; }
.tme-panel[role="status"] > h2:first-child::before {
  content: ""; width: 36px; height: 36px; flex: none; border-radius: 50%;
  background: var(--tm-mint-text, #07796c) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 12.5l4 4L18 8'/%3E%3C/svg%3E") center / 22px no-repeat;
}
html:not(.tm-motion-calm) .tme-panel[role="status"] > h2:first-child::before { animation: tm-pop 500ms var(--tm-ease-spring) 120ms both; }
html:not(.tm-motion-calm) .tme-panel[role="status"] > :not(h2) { animation: tm-rise-in var(--tm-dur-4) var(--tm-ease-out) 260ms both; }

/* ---------- C04 · partner logos ---------- */
html:not(.tm-motion-calm) .tm-partner-logo { transition: filter var(--tm-dur-3) var(--tm-ease-out), transform var(--tm-dur-3) var(--tm-ease-out); }
.tm-partner-logo { filter: grayscale(.6); }
.tm-partner-card:is(:hover, :focus-within) .tm-partner-logo { filter: none; }
html:not(.tm-motion-calm) .tm-partner-card:is(:hover, :focus-within) .tm-partner-logo { transform: scale(1.04); }

/* ---------- C06 · reading progress on long pages (#058) ---------- */
.tm-read-progress {
  position: fixed; left: 0; right: 0; top: 0; z-index: 1001; height: 3px; pointer-events: none;
  background: var(--tm-mint-text, #07796c); transform-origin: left; transform: scaleX(var(--tm-p, 0));
}
:where(.admin-bar) .tm-read-progress { top: 32px; }
@media (max-width: 782px) { :where(.admin-bar) .tm-read-progress { top: 46px; } }
html.tm-motion-calm .tm-read-progress { display: none; }

@media print {
  .tm-reveal, .tm-reveal * { opacity: 1 !important; transform: none !important; animation: none !important; }
  .tm-sticky-cta, .tm-read-progress { display: none !important; }
}

/* ---------- BT · every button: lift, light sweep, sliding arrow, ink ripple (Lucian #002 arrow, #006 ripple) ----------
 * One effect set for the two button templates in brand.css. Hover/focus: the button rises 2px with a soft
 * shadow, a light band sweeps across once and a trailing arrow slides 4px. Press: scale .97 (H05) plus an ink
 * ripple from the pointer (motion.js). Calm mode keeps colour changes only.
 */
html:not(.tm-motion-calm) body :is(.tm-btn-dark, .tm-btn-light, .tm-hero-cta, .tme-button, .button-primary, .wpcf7-submit, .tm-btn-primary, .tm-profile-cta, .tme-form button[type=submit], .tme-form button[data-next], .tme-form button[data-send], .tme-form button[data-back], .tme-panel button[type=submit], .tme-filters button, .wp-block-search__button, .wp-block-button__link, .s4-btn, .tm-btn-request, .header-nav-primary > li.become > a, .btn-primary, .btn-secondary, .tme-subject-more, .tm-footer-button) {
  position: relative; overflow: hidden; isolation: isolate;
  transition: background-color var(--tm-dur-2) var(--tm-ease-out), border-color var(--tm-dur-2) var(--tm-ease-out), color var(--tm-dur-2) var(--tm-ease-out),
    transform var(--tm-dur-2) var(--tm-ease-out), box-shadow var(--tm-dur-2) var(--tm-ease-out);
}
html:not(.tm-motion-calm) body :is(.tm-btn-dark, .tm-btn-light, .tm-hero-cta, .tme-button, .button-primary, .wpcf7-submit, .tm-btn-primary, .tm-profile-cta, .tme-form button[type=submit], .tme-form button[data-next], .tme-form button[data-send], .tme-form button[data-back], .tme-panel button[type=submit], .tme-filters button, .wp-block-search__button, .wp-block-button__link, .s4-btn, .tm-btn-request, .header-nav-primary > li.become > a, .btn-primary, .btn-secondary, .tme-subject-more, .tm-footer-button):is(:hover, :focus-visible):not(:disabled) {
  transform: translateY(-2px); box-shadow: 0 10px 22px -6px rgb(7 17 71 / 35%);
}
html:not(.tm-motion-calm) body :is(.tm-btn-dark, .tm-btn-light, .tm-hero-cta, .tme-button, .button-primary, .wpcf7-submit, .tm-btn-primary, .tm-profile-cta, .tme-form button[type=submit], .tme-form button[data-next], .tme-form button[data-send], .tme-form button[data-back], .tme-panel button[type=submit], .tme-filters button, .wp-block-search__button, .wp-block-button__link, .s4-btn, .tm-btn-request, .header-nav-primary > li.become > a, .btn-primary, .btn-secondary, .tme-subject-more, .tm-footer-button):active:not(:disabled) { transform: translateY(0) scale(.97); box-shadow: 0 4px 10px -4px rgb(7 17 71 / 30%); transition-duration: var(--tm-dur-1); }
html:not(.tm-motion-calm) body :is(.tm-btn-dark, .tm-btn-light, .tm-hero-cta, .tme-button, .button-primary, .wpcf7-submit, .tm-btn-primary, .tm-profile-cta, .tme-form button[type=submit], .tme-form button[data-next], .tme-form button[data-send], .tme-form button[data-back], .tme-panel button[type=submit], .tme-filters button, .wp-block-search__button, .wp-block-button__link, .s4-btn, .tm-btn-request, .header-nav-primary > li.become > a, .btn-primary, .btn-secondary, .tme-subject-more, .tm-footer-button)::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(110deg, transparent 30%, rgb(255 255 255 / 35%) 48%, transparent 66%);
  transform: translateX(-130%);
}
html:not(.tm-motion-calm) body :is(.tm-btn-dark, .tm-btn-light, .tm-hero-cta, .tme-button, .button-primary, .wpcf7-submit, .tm-btn-primary, .tm-profile-cta, .tme-form button[type=submit], .tme-form button[data-next], .tme-form button[data-send], .tme-form button[data-back], .tme-panel button[type=submit], .tme-filters button, .wp-block-search__button, .wp-block-button__link, .s4-btn, .tm-btn-request, .header-nav-primary > li.become > a, .btn-primary, .btn-secondary, .tme-subject-more, .tm-footer-button):is(:hover, :focus-visible)::before { transform: translateX(130%); transition: transform .75s var(--tm-ease-out); }
html:not(.tm-motion-calm) body :is(.tm-btn-dark, .tm-btn-light, .tm-hero-cta, .tme-button, .button-primary, .wpcf7-submit, .tm-btn-primary, .tm-profile-cta, .tme-form button[type=submit], .tme-form button[data-next], .tme-form button[data-send], .tme-form button[data-back], .tme-panel button[type=submit], .tme-filters button, .wp-block-search__button, .wp-block-button__link, .s4-btn, .tm-btn-request, .header-nav-primary > li.become > a, .btn-primary, .btn-secondary, .tme-subject-more, .tm-footer-button) > svg:last-child { flex: none; transition: transform var(--tm-dur-2) var(--tm-ease-out); }
html:not(.tm-motion-calm) body :is(.tm-btn-dark, .tm-btn-light, .tm-hero-cta, .tme-button, .button-primary, .wpcf7-submit, .tm-btn-primary, .tm-profile-cta, .tme-form button[type=submit], .tme-form button[data-next], .tme-form button[data-send], .tme-form button[data-back], .tme-panel button[type=submit], .tme-filters button, .wp-block-search__button, .wp-block-button__link, .s4-btn, .tm-btn-request, .header-nav-primary > li.become > a, .btn-primary, .btn-secondary, .tme-subject-more, .tm-footer-button):is(:hover, :focus-visible) > svg:last-child { transform: translateX(4px); }
.tm-ripple { position: absolute; z-index: -1; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; background: currentColor; opacity: .28; pointer-events: none; transform: scale(0); animation: tm-ripple 600ms var(--tm-ease-out) forwards; }
@keyframes tm-ripple { to { transform: scale(var(--tm-ripple-scale, 30)); opacity: 0; } }
html.tm-motion-calm .tm-ripple { display: none; }

/* ---------- HM10 · stats row "5+ / IB · IGCSE / 6+" comes alive once in view ----------
 * JS marks the row .tm-stats-ready (so nothing is hidden without JS), then .is-live when 50% visible:
 * a light band sweeps the row, "IB" and "IGCSE" wipe in from the left, each "+" pops in after its number
 * finishes counting (800ms), and a teal accent line draws under every stat. Hover: the cell warms to mint
 * and the figure lifts. Calm mode shows the final state with no movement.
 */
.s2-stats { position: relative; }
.s2-stat { position: relative; transition: background-color var(--tm-dur-2) var(--tm-ease-out); }
.s2-stat .num { display: inline-block; transition: transform var(--tm-dur-2) var(--tm-ease-out); }
.s2-stat .num span { display: inline-block; }
.s2-stat::after {
  content: ""; position: absolute; left: 50%; bottom: 14px; width: 28px; height: 2px; margin-left: -14px; border-radius: 2px;
  background: var(--tm-mint-text, #07796C); transform-origin: center; transition: transform var(--tm-dur-3) var(--tm-ease-out), width var(--tm-dur-3) var(--tm-ease-out), margin var(--tm-dur-3) var(--tm-ease-out);
}
.s2-stat:hover { background: var(--tm-mint-soft, #E6F6F4); }
html:not(.tm-motion-calm) .s2-stat:hover .num { transform: translateY(-3px); }
.s2-stat:hover::after { width: 56px; margin-left: -28px; }
html:not(.tm-motion-calm) .s2-stats.tm-stats-ready:not(.is-live) .s2-stat::after { transform: scaleX(0); }
html:not(.tm-motion-calm) .s2-stats.tm-stats-ready:not(.is-live) .num span { opacity: 0; }
html:not(.tm-motion-calm) .s2-stats.is-live .s2-stat::after { animation: tm-stat-line 500ms var(--tm-ease-out) both; animation-delay: calc(350ms + var(--tm-si, 0) * 120ms); }
html:not(.tm-motion-calm) .s2-stats.is-live .s2-stat:not(.s2-stat--words) .num span { animation: tm-stat-plus 520ms var(--tm-ease-spring) both; animation-delay: calc(820ms + var(--tm-si, 0) * 60ms); }
html:not(.tm-motion-calm) .s2-stats.is-live .s2-stat--words .num span { animation: tm-stat-wipe 650ms var(--tm-ease-out) both; animation-delay: calc(200ms + var(--tm-w, 0) * 220ms); }
html:not(.tm-motion-calm) .s2-stats.is-live::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgb(56 156 148 / 14%) 50%, transparent 65%);
  animation: tm-stat-sweep 1.2s var(--tm-ease-out) 150ms both;
}
@keyframes tm-stat-line { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes tm-stat-plus { 0% { opacity: 0; transform: scale(.2) rotate(-90deg); } 70% { opacity: 1; transform: scale(1.3) rotate(8deg); } 100% { opacity: 1; transform: none; } }
@keyframes tm-stat-wipe { from { opacity: 1; clip-path: inset(0 100% 0 0); transform: translateY(6px); } to { opacity: 1; clip-path: inset(0 0 0 0); transform: none; } }
@keyframes tm-stat-sweep { from { transform: translateX(-100%); opacity: 1; } to { transform: translateX(100%); opacity: 0; } }
