/* ---------------------------------------------------------------------------
   AI Speaking Tutor

   Loaded only by /ai-speaking-tutor/practice/. Everything is namespaced under
   .tutor- so nothing here can reach another page.

   IMPORTANT ORDERING NOTE: css/styles.css loads AFTER assets/tailwind.css, so
   an equal-specificity rule in a site stylesheet silently beats a Tailwind
   utility. This file loads after both, and deliberately does not restyle any
   bare element or Tailwind class name for that reason.

   Palette is taken from css/styles.css rather than restated as hex where it
   can be helped: navy #031f42, teal #00e2c5, light bg #f4f9ff, muted #5b6d84.
   --------------------------------------------------------------------------- */

/* The tokens live on :root, NOT on .tutor-shell.
 *
 * This has now caused the same bug twice. Anything rendered into document.body
 * (the briefing modal, any overlay) sits OUTSIDE .tutor-shell, so var(--t-navy)
 * resolved to nothing there, which makes `background` invalid at computed-value
 * time and drops it to transparent. .tutor-btn-primary keeps color:#fff, so the
 * result was white text on a white card: a button that was present, focusable
 * and clickable, and completely invisible.
 *
 * The bullets in that same modal were fine only because they used
 * var(--t-accent, #0f7a6a) WITH a fallback. That is the difference.
 *
 * This stylesheet is loaded by exactly one page and every name is --t- prefixed,
 * so :root is safe. Every rule below still has a literal fallback anyway. */
:root {
  --t-navy: #031f42;
  --t-teal: #00e2c5;
  --t-muted: #5b6d84;
  --t-light: #f4f9ff;
  --t-border: #e6efff;
  --t-gold: #ffd25d;
}

.tutor-shell {
  min-height: 70vh;
  background: var(--t-light);
  padding: 96px 16px 64px;
}
@media (min-width: 1024px) {
  .tutor-shell {
    padding: 128px 32px 80px;
  }
}

.tutor-stage {
  max-width: 1080px;
  margin: 0 auto;
}
.tutor-stage[hidden] {
  display: none;
}

/* THE HIDDEN BUG.
   `[hidden]` is a User Agent rule (display:none) and ANY author declaration of
   `display` on the same element beats it. .tutor-btn below sets
   display:inline-flex, so every button this file ever hid with the hidden
   attribute stayed on screen: "Ask again" sat next to "Microphone is on", and
   "Done speaking" sat next to "Start recording" through the whole question.
   The buttons were never meant to co-exist; the attribute simply did nothing.

   !important is correct here rather than lazy: the whole point is to outrank
   every author `display` in this file, including ones added later. */
[hidden] {
  display: none !important;
}
.tutor-stage-run {
  max-width: 720px;
}

/* ---------------------------------------------------------------- header -- */
.tutor-crumbs {
  font-size: 13px;
  color: var(--t-muted);
  margin-bottom: 18px;
}
.tutor-crumbs a {
  color: var(--t-muted);
  text-decoration: none;
}
.tutor-crumbs a:hover {
  color: var(--t-navy);
  text-decoration: underline;
}
.tutor-crumbs span {
  opacity: 0.5;
  margin: 0 4px;
}
.tutor-crumbs strong {
  color: var(--t-navy);
  font-weight: 600;
}

.tutor-head-row {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-end;
  justify-content: space-between;
}
.tutor-title {
  font-size: clamp(28px, 4vw, 40px);
  line-height: 1.15;
  font-weight: 700;
  color: var(--t-navy);
  letter-spacing: -0.8px;
}
.tutor-sub {
  color: var(--t-muted);
  margin-top: 8px;
  font-size: 15px;
}

/* ------------------------------------------------------------------- xp -- */
.tutor-xp {
  background: #fff;
  border: 1px solid var(--t-border);
  border-radius: 14px;
  padding: 14px 18px;
  min-width: 240px;
}
.tutor-xp-level {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.tutor-xp-num {
  font-size: 22px;
  font-weight: 700;
  color: var(--t-navy);
  background: var(--t-teal);
  border-radius: 8px;
  padding: 0 9px;
  line-height: 1.5;
}
.tutor-xp-title {
  font-weight: 600;
  color: var(--t-navy);
  font-size: 14px;
}
.tutor-xp-bar {
  height: 6px;
  background: var(--t-border);
  border-radius: 99px;
  margin: 10px 0 6px;
  overflow: hidden;
}
.tutor-xp-bar i {
  display: block;
  height: 100%;
  background: #00695c;
  border-radius: 99px;
  transition: width 0.6s ease;
}
.tutor-xp-meta {
  font-size: 12px;
  color: var(--t-muted);
}
.tutor-xp-gain {
  color: var(--t-navy);
  font-weight: 600;
  margin-top: 10px;
}

/* ----------------------------------------------------------------- tabs -- */
.tutor-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 28px 0 20px;
}
.tutor-tab {
  border: 1px solid var(--t-border);
  background: #fff;
  color: var(--t-muted);
  border-radius: 99px;
  padding: 9px 18px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
  font-family: inherit;
}
.tutor-tab:hover {
  border-color: var(--t-navy);
  color: var(--t-navy);
}
.tutor-tab[aria-selected='true'] {
  background: var(--t-navy);
  border-color: var(--t-navy);
  color: #fff;
}

.tutor-track-intro {
  background: #fff;
  border: 1px solid var(--t-border);
  border-radius: 14px;
  padding: 18px 20px;
  margin-bottom: 20px;
}
.tutor-track-intro h2 {
  font-size: 18px;
  font-weight: 700;
  color: var(--t-navy);
  margin-bottom: 6px;
}
.tutor-track-intro p {
  color: var(--t-muted);
  font-size: 14px;
  line-height: 1.6;
}
.tutor-track-intro .tutor-maps {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t-navy);
  background: var(--t-teal);
  border-radius: 6px;
  padding: 2px 8px;
  margin-bottom: 8px;
}

/* ---------------------------------------------------------------- bands -- */
.tutor-bands {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 16px;
  font-size: 12px;
  color: var(--t-muted);
}
.tutor-bands span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.tutor-bands i {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
  border: 1px solid rgba(3, 31, 66, 0.35);
}

/* ----------------------------------------------------------------- grid -- */
.tutor-grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
}
.tutor-cell {
  position: relative;
  background: #fff;
  border: 1px solid var(--t-border);
  border-radius: 12px;
  padding: 12px 10px 10px;
  text-align: center;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.tutor-cell:hover {
  border-color: var(--t-navy);
  transform: translateY(-2px);
}
.tutor-cell-no {
  font-size: 18px;
  font-weight: 700;
  color: var(--t-navy);
  line-height: 1.1;
}
.tutor-cell-band {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--t-muted);
}
.tutor-cell-stars {
  font-size: 11px;
  letter-spacing: 1px;
  color: #a9761a;
  min-height: 14px;
}
.tutor-cell-best {
  font-size: 11px;
  font-weight: 600;
  color: var(--t-muted);
}
.tutor-cell[data-hard='1'] {
  border-color: rgba(3, 31, 66, 0.25);
  background: linear-gradient(180deg, #fff 0%, #fdfaf1 100%);
}
.tutor-cell[data-free='1']::after {
  content: 'Free';
  position: absolute;
  top: -7px;
  right: -6px;
  background: var(--t-teal);
  color: var(--t-navy);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: 5px;
}
/* The locked state used to be dead code: nothing ever set data-locked, and the
   glyph masked on a --lock custom property that was never defined anywhere in
   the codebase, so it would have rendered nothing even if it had. Every cell
   looked identical and openable while 49 of 50 led to a paywall. A plain
   character needs no mask and cannot silently fail. */
.tutor-cell[data-locked='1'] {
  opacity: 0.62;
  background: #fbfcfe;
}
.tutor-cell[data-locked='1'] .tutor-cell-no::after {
  content: '\1F512';
  font-size: 10px;
  margin-left: 3px;
  opacity: 0.75;
  vertical-align: 2px;
}
.tutor-cell[data-locked='1']:hover {
  border-color: var(--t-muted);
}
.tutor-cell[data-done='1'] {
  border-color: #00695c;
  box-shadow: inset 0 0 0 1px #00695c;
}
/* The one the landing page means by "start the free exercise". Without this the
   student arrives at a grid of fifty and has to work out which one that was. */
.tutor-cell[data-start-here='1'] {
  border-color: var(--t-navy);
  box-shadow: 0 0 0 3px rgba(3, 31, 66, 0.14);
}

/* ---------------------------------------------------------------- panel -- */
.tutor-panel {
  background: #fff;
  border: 1px solid var(--t-border);
  border-radius: 18px;
  padding: 28px 24px;
}
@media (min-width: 768px) {
  .tutor-panel {
    padding: 36px 40px;
  }
}
.tutor-panel-narrow {
  max-width: 560px;
  margin: 0 auto;
}
.tutor-panel-centre {
  text-align: center;
}
.tutor-panel-title {
  font-size: 22px;
  font-weight: 700;
  color: var(--t-navy);
  margin-bottom: 10px;
}
.tutor-panel-text {
  color: var(--t-muted);
  line-height: 1.65;
  font-size: 15px;
}
.tutor-note,
.tutor-fineprint {
  color: var(--t-muted);
  font-size: 13px;
  margin-top: 16px;
  line-height: 1.6;
}
.tutor-fineprint a {
  color: var(--t-navy);
  font-weight: 600;
}

/* --------------------------------------------------------------- button -- */
.tutor-btn {
  font-family: inherit;
  font-weight: 700;
  font-size: 15px;
  border-radius: 12px;
  padding: 13px 24px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: all 0.15s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
}
.tutor-btn-primary {
  background: var(--t-navy, #031f42);
  color: #fff;
}
.tutor-btn-primary:hover {
  background: #06294f;
}
.tutor-btn-primary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
/* Measured 1.16:1 against white, so the button had no visible boundary at all. */
.tutor-btn-ghost {
  background: transparent;
  border-color: #6b81a0;
  color: var(--t-navy, #031f42);
}
.tutor-btn-ghost:hover {
  border-color: var(--t-navy, #031f42);
}
.tutor-btn-lg {
  font-size: 17px;
  padding: 16px 40px;
}
.tutor-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}
.tutor-actions-centre {
  justify-content: center;
}

/* --------------------------------------------------------------- loader --
   Three dots orbiting, so a wait reads as work rather than a hang.
   ------------------------------------------------------------------------- */
.tutor-loader {
  text-align: center;
  padding: 72px 16px;
}
.tutor-loader-orb {
  position: relative;
  width: 64px;
  height: 64px;
  margin: 0 auto 26px;
}
.tutor-loader-orb span {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--t-teal);
  opacity: 0;
  animation: tutorPulse 1.8s cubic-bezier(0.2, 0.6, 0.3, 1) infinite;
}
.tutor-loader-orb span:nth-child(2) {
  animation-delay: 0.6s;
}
.tutor-loader-orb span:nth-child(3) {
  animation-delay: 1.2s;
}
@keyframes tutorPulse {
  0% {
    transform: scale(0.35);
    opacity: 0;
  }
  35% {
    opacity: 0.9;
  }
  100% {
    transform: scale(1);
    opacity: 0;
  }
}
.tutor-loader-msg {
  font-size: 18px;
  font-weight: 700;
  color: var(--t-navy);
}
.tutor-loader-sub {
  color: var(--t-muted);
  font-size: 14px;
  margin-top: 8px;
}
.tutor-loader-bar {
  width: 220px;
  height: 5px;
  background: var(--t-border);
  border-radius: 99px;
  margin: 22px auto 0;
  overflow: hidden;
}
.tutor-loader-bar i {
  display: block;
  height: 100%;
  background: var(--t-teal);
  border-radius: 99px;
  transition: width 0.4s ease;
}

/* Visually hidden but read aloud. Carries the live-region announcements the
   app makes when the phase changes, because the whole state of a timed drill
   lives in a countdown and a one-word label. */
.tutor-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  white-space: nowrap;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
}

@media (prefers-reduced-motion: reduce) {
  /* STOPPED, not slowed. The previous rule set a 3.6s duration on an infinite
     scale animation, which is still continuous movement. Held at the largest
     frame so the dots remain visible as a shape. */
  .tutor-loader-orb span,
  .tutor-loader-orb span:nth-child(2),
  .tutor-loader-orb span:nth-child(3) {
    animation: none !important;
    opacity: 0.3;
    transform: scale(1);
  }
  .tutor-cell:hover {
    transform: none;
  }
  /* Everything that moves on its own stops. The canvas orb is handled in JS,
     which cannot be reached from here. */
  .tutor-xp-bar i,
  .tutor-loader-bar i,
  .tutor-metric-bar i,
  .tutor-score-ring .ring-fg {
    transition: none;
  }
}

/* Skip link. The shared mega-nav puts roughly 125 focusable elements ahead of
   the first control in this app, so without one a keyboard user Tabs 124 times
   to reach the Back button on the microphone screen. Hidden until focused. */
.tutor-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: #031f42;
  color: #fff;
  font-weight: 700;
  padding: 12px 20px;
  border-radius: 0 0 10px 0;
  text-decoration: none;
}
.tutor-skip:focus {
  left: 0;
  outline: 3px solid #00e2c5;
}

/* A visible focus ring on every control. The default was inherited from the
   page and disappeared entirely on the exercise grid, which is 50 buttons. */
.tutor-shell :focus-visible {
  outline: 3px solid var(--t-navy);
  outline-offset: 2px;
  border-radius: 6px;
}
.tutor-tab:focus-visible,
.tutor-cell:focus-visible {
  outline-color: var(--t-navy);
}

/* ------------------------------------------------------------------ run -- */
.tutor-run-top {
  display: flex;
  align-items: center;
  gap: 10px 14px;
  flex-wrap: wrap;
  margin-bottom: 26px;
  position: relative;
}
.tutor-quit {
  background: transparent;
  border: 1px solid var(--t-border);
  color: var(--t-muted);
  width: 34px;
  height: 34px;
  border-radius: 50%;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  flex-shrink: 0;
}
.tutor-quit:hover {
  border-color: var(--t-navy);
  color: var(--t-navy);
}
.tutor-run-meta {
  font-size: 13px;
  font-weight: 600;
  color: var(--t-muted);
}
.tutor-dot {
  opacity: 0.4;
  margin: 0 4px;
}
.tutor-progress {
  display: flex;
  gap: 4px;
  margin-left: auto;
  flex-wrap: wrap;
  justify-content: flex-end;
  max-width: 60%;
}
/* Measured 1.43:1 for teal on the pale track, against a 3:1 requirement for a
   graphical indicator. Both ends darkened. */
.tutor-progress i {
  width: 18px;
  height: 4px;
  border-radius: 99px;
  background: #e8eef7;
  display: block;
  transition: background 0.3s ease;
}
.tutor-progress i[data-done='1'] {
  background: #00695c;
}
.tutor-progress i[data-current='1'] {
  background: var(--t-navy);
}

.tutor-run-body {
  text-align: center;
}
.tutor-run-step {
  font-size: 13px;
  font-weight: 600;
  color: var(--t-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.tutor-prompt {
  font-size: clamp(19px, 3vw, 26px);
  line-height: 1.45;
  font-weight: 600;
  color: var(--t-navy);
  margin: 14px auto 0;
  max-width: 620px;
  min-height: 1.45em;
}
.tutor-prompt-hint {
  color: var(--t-muted);
  font-size: 14px;
  margin-top: 10px;
  font-style: italic;
}
.tutor-run-help {
  color: var(--t-muted);
  font-size: 14px;
  margin-top: 6px;
  min-height: 1.4em;
}

/* ------------------------------------------------------------------ orb --
   The visual is drawn on the canvas by js/speaking-tutor.js from live
   microphone data. CSS only positions it and supplies the resting glow, so a
   browser that blocks canvas still shows something coherent.
   ------------------------------------------------------------------------- */
/* Sized off the SHORTER axis as well as the width. It used to key off width
   alone, so at 200% zoom (a 640x400 viewport) the orb stayed 320px tall, the
   run body reached 530px, and the primary action sat below the fold while the
   countdown was running. */
.tutor-orb-wrap {
  position: relative;
  width: min(320px, 78vw, 42vh);
  aspect-ratio: 1;
  margin: 26px auto 18px;
  display: grid;
  place-items: center;
}
.tutor-orb-small {
  width: min(200px, 55vw);
  margin: 20px auto 14px;
}
.tutor-orb {
  width: 100%;
  height: 100%;
  display: block;
}
.tutor-orb-centre {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
.tutor-timer {
  font-size: clamp(38px, 8vw, 56px);
  font-weight: 700;
  color: var(--t-navy);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.tutor-phase {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--t-muted);
  margin-top: 8px;
}
.tutor-mic-status {
  font-size: 14px;
  color: var(--t-muted);
  text-align: center;
  min-height: 1.4em;
}

/* --------------------------------------------------------------- reveal -- */
.tutor-reveal {
  background: var(--t-light);
  border: 1px solid var(--t-border);
  border-radius: 14px;
  padding: 18px 20px;
  margin-top: 22px;
  text-align: left;
}
.tutor-reveal-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--t-muted);
}

/* Says what to DO with the text below it. Without this the only nearby label is
   "Question 1 of 10", which tells a student on Read Aloud that the declarative
   sentence in front of them is a question being asked. It is not; they have to
   read it out loud. */
.tutor-prompt-label {
  margin: 12px 0 0;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--t-accent, #0f7a6a);
}
.tutor-reveal-text {
  font-size: 17px;
  font-weight: 600;
  color: var(--t-navy);
  margin-top: 6px;
  line-height: 1.5;
}
.tutor-reveal-missed {
  font-size: 13px;
  color: var(--t-muted);
  margin-top: 8px;
}
.tutor-reveal-missed b {
  color: var(--t-navy);
}

/* --------------------------------------------------------------- report -- */
.tutor-score-head {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  align-items: center;
  margin-bottom: 28px;
}
.tutor-score-ring {
  position: relative;
  width: 132px;
  height: 132px;
  flex-shrink: 0;
}
.tutor-score-ring svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}
.tutor-score-ring .ring-bg {
  fill: none;
  stroke: var(--t-border);
  stroke-width: 10;
}
.tutor-score-ring .ring-fg {
  fill: none;
  stroke: #00695c;
  stroke-width: 10;
  stroke-linecap: round;
  stroke-dasharray: 327;
  stroke-dashoffset: 327;
  transition: stroke-dashoffset 1s ease;
}
.tutor-score-num {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  font-weight: 700;
  color: var(--t-navy);
}
.tutor-score-num i {
  font-size: 14px;
  font-style: normal;
  color: var(--t-muted);
  margin-left: 2px;
}
.tutor-score-side {
  flex: 1 1 240px;
}
/* Gold on white measured 1.44:1. Bronze keeps the star read and clears 3:1. */
.tutor-stars {
  font-size: 20px;
  letter-spacing: 3px;
  color: #a9761a;
  margin-bottom: 6px;
  min-height: 26px;
}

.tutor-metrics {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  margin-bottom: 26px;
}
.tutor-metric {
  background: var(--t-light);
  border-radius: 12px;
  padding: 14px 16px;
}
.tutor-metric-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.tutor-metric-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--t-navy);
}
.tutor-metric-val {
  font-size: 13px;
  font-weight: 700;
  color: var(--t-navy);
}
.tutor-metric-bar {
  height: 5px;
  background: #fff;
  border-radius: 99px;
  margin-top: 9px;
  overflow: hidden;
}
.tutor-metric-bar i {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: #00695c;
  transition: width 0.8s ease;
}
/* The weakest bar carried the whole "this is your problem" message in a colour
   measured at 2.31:1. Darkened, and the label now says it in words too. */
.tutor-metric-bar i[data-weak='1'] {
  background: #c2410c;
}
.tutor-metric-note {
  font-size: 12px;
  color: var(--t-muted);
  margin-top: 7px;
  line-height: 1.5;
}

.tutor-feedback {
  background: var(--t-light);
  border-radius: 14px;
  padding: 20px 22px;
  margin-bottom: 22px;
}
.tutor-feedback-title {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--t-muted);
  margin-bottom: 10px;
}
.tutor-focus {
  font-size: 17px;
  font-weight: 700;
  color: var(--t-navy);
  margin-bottom: 12px;
}
.tutor-feedback-body p {
  color: var(--t-navy);
  line-height: 1.75;
  font-size: 15px;
  margin-bottom: 12px;
}
.tutor-feedback-body p:last-child {
  margin-bottom: 0;
}
.tutor-drill {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--t-border);
  font-size: 14px;
  font-weight: 600;
  color: var(--t-navy);
}

.tutor-answers {
  margin-bottom: 22px;
}
.tutor-answers summary {
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  color: var(--t-navy);
  padding: 10px 0;
}
.tutor-answer {
  border-top: 1px solid var(--t-border);
  padding: 12px 0;
}
.tutor-answer-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--t-muted);
}
.tutor-answer-text {
  font-size: 14px;
  color: var(--t-navy);
  line-height: 1.6;
  margin-top: 6px;
}
.tutor-answer-text[data-silent='1'] {
  color: var(--t-muted);
  font-style: italic;
}

.tutor-lock-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--t-light);
  color: var(--t-navy);
  display: grid;
  place-items: center;
  margin: 0 auto 16px;
}

/* ---- what we heard, between questions --------------------------------------
   The scorer already measured all of this per answer and sent it back; it used
   to be discarded until the end-of-exercise report. Between questions is where
   it changes what the student does next. */
.tutor-heard {
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid rgba(3, 31, 66, 0.12);
  text-align: left;
}
.tutor-heard-label {
  margin: 0 0 5px;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #5b6d84;
}
.tutor-heard-text {
  margin: 0 0 11px;
  font-size: 15px;
  line-height: 1.6;
  color: #031f42;
}
.tutor-heard-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.tutor-heard-stats li {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 7px 11px;
  border-radius: 9px;
  background: rgba(3, 31, 66, 0.05);
  font-size: 12.5px;
}
.tutor-heard-stats li.is-warn {
  background: rgba(245, 158, 11, 0.14);
}
.tutor-heard-stats li span {
  color: #5b6d84;
  font-weight: 600;
}
.tutor-heard-stats li b {
  color: #031f42;
  font-weight: 800;
}
.tutor-heard-stats li i {
  color: #5b6d84;
  font-style: normal;
  font-size: 11.5px;
}
.tutor-heard-stats li.is-warn i {
  color: #92400e;
}

@media (max-width: 520px) {
  .tutor-heard-stats li {
    flex: 1 1 calc(50% - 8px);
  }
}

/* ---- the recording state of the single control ----------------------------
   Red, because every product in this category uses colour to carry the state
   when one button changes meaning: Reading Coach, Speechling, BoldVoice. The
   dot pulses so it is obvious the microphone is live. */
.tutor-btn-stop {
  background: #d92b2b;
  border-color: #d92b2b;
  color: #fff;
}
.tutor-btn-stop:hover {
  background: #c02424;
  border-color: #c02424;
}
.tutor-btn-stop::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #fff;
  animation: tutor-rec-pulse 1.15s ease-in-out infinite;
}
@keyframes tutor-rec-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.45;
    transform: scale(0.82);
  }
}

/* ---- hear your own answer back --------------------------------------------
   The clip has been stored per question since this engine was written and was
   never offered. The official ETS practice test does not let you replay a
   spoken answer at all, so this is a real advantage, not a nicety. */
.tutor-heard-top {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 5px;
}
.tutor-heard-top .tutor-heard-label {
  margin: 0;
}
.tutor-play-mine {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid rgba(3, 31, 66, 0.18);
  border-radius: 999px;
  background: #fff;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: #2c4a6e;
  cursor: pointer;
}
.tutor-play-mine:hover {
  border-color: var(--t-accent, #0f7a6a);
  color: var(--t-accent, #0f7a6a);
}

@media (prefers-reduced-motion: reduce) {
  .tutor-btn-stop::before {
    animation: none;
  }
}

/* ---- word by word on the target sentence -----------------------------------
   Three states on purpose. `tw-skip` is for words under three letters, which
   missedWords deliberately ignores as speech-recogniser noise: they were never
   checked, so they must not be coloured as if they passed. Colour is never the
   only signal, because roughly one man in twelve cannot separate these two
   hues: missed words also carry an underline. */
.tutor-reveal-text .tw {
  font-weight: 600;
}
.tutor-reveal-text .tw-ok {
  color: #0f7a3d;
}
.tutor-reveal-text .tw-no {
  color: #b3282c;
  text-decoration: underline;
  text-decoration-style: wavy;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.tutor-reveal-text .tw-skip {
  color: var(--t-muted, #5b6d84);
  font-weight: 400;
}

/* ---- the practice step ----------------------------------------------------- */
.tutor-drill {
  margin-top: 14px;
  padding: 13px 15px;
  border-radius: 12px;
  background: rgba(179, 40, 44, 0.06);
  border: 1px solid rgba(179, 40, 44, 0.16);
  text-align: left;
}
.tutor-drill-label {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #b3282c;
}
.tutor-drill-words {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin: 0 0 9px;
}
.tutor-drill-words b {
  padding: 5px 11px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid rgba(179, 40, 44, 0.25);
  color: #031f42;
  font-size: 14px;
  font-weight: 700;
}
.tutor-drill-note {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #5b6d84;
}

/* ---- what this exercise is about to do, before it does it ------------------
   The thinking time steps down as a student climbs and disappears entirely for
   the last fifteen, matching the real test. Nothing ever said so, and a silent
   rule change reads as a fault. */
.tutor-brief {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.tutor-brief-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(3, 31, 66, 0.55);
}
.tutor-brief-card {
  position: relative;
  max-width: 460px;
  width: 100%;
  padding: 26px 26px 22px;
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 24px 60px rgba(3, 31, 66, 0.3);
  text-align: left;
}
.tutor-brief-card h2 {
  margin: 0 0 14px;
  font-size: 20px;
  font-weight: 800;
  color: #031f42;
}
.tutor-brief-card ul {
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
}
.tutor-brief-card li {
  position: relative;
  padding: 0 0 11px 22px;
  font-size: 14.5px;
  line-height: 1.55;
  color: #2c4a6e;
}
.tutor-brief-card li::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--t-accent, #0f7a6a);
}
.tutor-brief-card button {
  width: 100%;
}

/* ---- where the permission control actually is ------------------------------
   Only shown in the blocked state, where the student has to find one specific
   browser control. "The lock or camera icon in the address bar" is not enough
   when every browser puts it somewhere slightly different, so it is drawn. */
.tutor-permhelp {
  margin: 16px auto 4px;
  max-width: 360px;
  padding: 14px 16px;
  border-radius: 12px;
  background: rgba(229, 72, 77, 0.05);
  border: 1px solid rgba(229, 72, 77, 0.18);
  text-align: left;
}
.tutor-permhelp[hidden] {
  display: none !important;
}
.tutor-permhelp-title {
  margin: 0 0 9px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #b3282c;
}
.tutor-permhelp-art {
  display: block;
  width: 100%;
  height: auto;
}
.tutor-permhelp-note {
  margin: 9px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #5b6d84;
}

/* ---- the suggestion box ----------------------------------------------------
   One actionable instruction per answer. It was an unstyled <p> running on
   from the delivery numbers, so the only sentence on the screen telling a
   student what to DO read as more commentary about what they had done.
   It is a labelled box now, and the label says what it is for. */
.tutor-coach {
  margin: 14px 0 0;
  padding: 13px 15px;
  border-radius: 12px;
  border: 1px solid #f0d9a8;
  border-left: 3px solid #e8a838;
  background: #fffaf0;
}
.tutor-coach-label {
  margin: 0 0 5px;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #8a5a12;
}
.tutor-coach-text {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: #3d2a08;
}
/* Nothing to fix is not a suggestion, so it does not wear the warning colours. */
.tutor-coach.is-good {
  border-color: #b7e4d4;
  border-left-color: var(--t-accent, #0f7a6a);
  background: #f2fbf8;
}
.tutor-coach.is-good .tutor-coach-label {
  color: #0b5e51;
}
.tutor-coach.is-good .tutor-coach-text {
  color: #10423a;
}

/* An empty transcript is a message, not a quotation. */
.tutor-heard-text.is-empty {
  color: var(--t-muted, #5b6d84);
  font-style: normal;
}

/* The instruction for the next answer. Separated from the diagnosis above it,
   because "what went wrong" and "what to do about it" are two different
   thoughts and a student acts on the second one. */
.tutor-coach-do {
  margin: 8px 0 0;
  padding: 8px 0 0;
  border-top: 1px dashed #eddcb8;
  font-size: 14.5px;
  line-height: 1.55;
  font-weight: 600;
  color: #3d2a08;
}
.tutor-coach.is-good .tutor-coach-do {
  border-top-color: #cbeadf;
  color: #10423a;
}

/* ==========================================================================
   SPEAKING EXERCISE, redesigned
   From the owner's Claude Design handoff, "Modern SaaS Recorder Redesign".

   Built to the handoff's measurements, with two deliberate departures, both
   agreed before starting:

   1. NO NEW FONTS. The handoff specified Space Grotesk and IBM Plex Mono.
      Layout, colour and spacing match; the type is the site's own face, so
      no page pays for two extra font downloads. Where the handoff leaned on
      mono for the timer and the tracked-out labels, that job is done here
      with tabular figures and letter-spacing instead.
   2. The "15 s prep" button is not built. The owner asked for it to be left
      out, and Interview's thinking time is automatic already.
   ========================================================================== */

.tutor-shell {
  --t-blue: #005bff;
  --t-blue-dark: #0049cc;
  --t-red: #f44336;
  --t-amber: #a07a12;
}

/* ---- the card --------------------------------------------------------- */
.tutor-card {
  width: 100%;
  max-width: 620px;
  margin: 0 auto;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--t-border, #e6efff);
  background: #fff;
  box-shadow: 0 18px 44px rgba(3, 31, 66, 0.07);
}
.tutor-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--t-border, #e6efff);
}
.tutor-card-head-l,
.tutor-card-head-r {
  display: flex;
  align-items: center;
  gap: 12px;
}
.tutor-card-head-r {
  gap: 8px;
}
.tutor-card .tutor-quit {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  padding: 0;
  border: 1px solid var(--t-border, #e6efff);
  background: #fff;
  display: grid;
  place-items: center;
  font-size: 15px;
  line-height: 1;
  color: var(--t-muted, #5b6d84);
  cursor: pointer;
  font-family: inherit;
}
.tutor-card .tutor-quit:hover {
  border-color: var(--t-blue, #005bff);
  color: var(--t-blue, #005bff);
}
.tutor-run-meta {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
  font-weight: 600;
}
.tutor-slash {
  opacity: 0.55;
  margin: 0 2px;
}
.tutor-qbar {
  width: 110px;
  height: 4px;
  border-radius: 2px;
  background: var(--t-border, #e6efff);
  overflow: hidden;
}
.tutor-qbar i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--t-blue, #005bff);
  transition: width 0.35s ease;
}
.tutor-qcount {
  font-size: 11px;
  color: var(--t-muted, #5b6d84);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.tutor-run-body {
  padding: 30px 34px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}

/* ---- the state line --------------------------------------------------- */
.tutor-eyebrow {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--t-blue, #005bff);
  display: flex;
  align-items: center;
  gap: 8px;
}
.tutor-eyebrow.is-prep {
  color: var(--t-amber, #a07a12);
}
.tutor-eyebrow.is-rec {
  color: var(--t-red, #f44336);
}
.tutor-eyebrow.is-rec::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--t-red, #f44336);
  animation: tutorBlink 1.1s ease-in-out infinite;
}
@keyframes tutorBlink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}

.tutor-card .tutor-prompt {
  margin: 0;
  text-align: center;
  font-size: 27px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--t-navy, #031f42);
  text-wrap: pretty;
}

/* ---- the dial ---------------------------------------------------------
   One 200px circle doing three jobs: fixed tick ring, conic progress arc
   over it, and the countdown in the middle. The arc angle is set from JS as
   --arc, so nothing here needs to know what is being counted. */
.tutor-dial {
  position: relative;
  width: 200px;
  height: 200px;
  display: grid;
  place-items: center;
  --arc: 0deg;
  --dial: var(--t-blue, #005bff);
}
.tutor-dial-ticks,
.tutor-dial-arc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* closest-side keeps the gradient radius at exactly half the box, so these
     stops stay the handoff's 84px and 98px at 200px and scale with it. */
  mask: radial-gradient(circle closest-side, transparent 0 84%, #000 84% 98%, transparent 98%);
  -webkit-mask: radial-gradient(
    circle closest-side,
    transparent 0 84%,
    #000 84% 98%,
    transparent 98%
  );
}
.tutor-dial-ticks {
  background: repeating-conic-gradient(
    from -90deg,
    rgba(3, 31, 66, 0.16) 0deg 0.7deg,
    rgba(3, 31, 66, 0) 0.7deg 6deg
  );
}
.tutor-dial-arc {
  background: conic-gradient(
    from -90deg,
    var(--dial) 0deg var(--arc),
    rgba(3, 31, 66, 0) var(--arc)
  );
  transition: none;
}
.tutor-dial-glow {
  position: absolute;
  inset: 20px;
  border-radius: 50%;
  border: 1px solid var(--t-border, #e6efff);
  background: radial-gradient(
    circle at 50% 30%,
    rgba(0, 91, 255, 0.07),
    rgba(255, 255, 255, 0) 70%
  );
}
.tutor-dial.is-rec .tutor-dial-glow {
  border-color: transparent;
  background: radial-gradient(circle, rgba(244, 67, 54, 0.09), rgba(255, 255, 255, 0) 70%);
  animation: tutorBreathe 2.4s ease-in-out infinite;
}
@keyframes tutorBreathe {
  0%,
  100% {
    opacity: 0.3;
  }
  50% {
    opacity: 0.8;
  }
}
.tutor-dial.is-send .tutor-dial-arc {
  background: conic-gradient(
    from -90deg,
    var(--t-blue, #005bff) 0deg 90deg,
    rgba(3, 31, 66, 0) 90deg
  );
  animation: tutorSpinArc 1.1s linear infinite;
}
@keyframes tutorSpinArc {
  to {
    transform: rotate(360deg);
  }
}
.tutor-dial-centre {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.tutor-card .tutor-timer {
  font-size: 50px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--t-navy, #031f42);
  font-variant-numeric: tabular-nums;
}
.tutor-card .tutor-timer.is-word {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--t-blue, #005bff);
}
.tutor-card .tutor-phase {
  margin: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  /* --t-muted measured 2.79:1 on the old orb centre, under the 4.5:1 floor.
     The state colour is both louder and more useful. */
  color: var(--t-blue, #005bff);
}
.tutor-dial.is-prep .tutor-phase {
  color: var(--t-amber, #a07a12);
}
.tutor-dial.is-rec .tutor-phase {
  color: var(--t-red, #f44336);
}

/* ---- level meter ------------------------------------------------------- */
.tutor-bars {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 52px;
  width: 100%;
}
.tutor-bars i {
  display: block;
  width: 5px;
  border-radius: 3px;
  height: 12%;
  background: #99bcff;
  transform-origin: center;
  transition:
    height 0.09s linear,
    background-color 0.2s linear;
}

/* ---- what is happening to the clip ------------------------------------- */
.tutor-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
}
.tutor-steps li {
  display: flex;
  justify-content: space-between;
  color: var(--t-muted, #5b6d84);
}
.tutor-steps li b {
  font-weight: 600;
  color: #2e7d32;
}
.tutor-steps li.is-live {
  color: var(--t-navy, #031f42);
}
.tutor-steps li.is-live b {
  color: var(--t-blue, #005bff);
  animation: tutorBlink 1.2s ease-in-out infinite;
}

.tutor-card .tutor-run-help {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  text-align: center;
  color: var(--t-muted, #5b6d84);
  max-width: 360px;
  text-wrap: pretty;
}

/* ---- buttons, restyled to the handoff ---------------------------------- */
.tutor-shell .tutor-btn-primary {
  background: var(--t-blue, #005bff);
  box-shadow: 0 8px 22px rgba(0, 91, 255, 0.24);
}
.tutor-shell .tutor-btn-primary:hover {
  background: var(--t-blue-dark, #0049cc);
}
.tutor-shell .tutor-btn-stop {
  background: var(--t-red, #f44336);
  border-color: var(--t-red, #f44336);
  box-shadow: none;
}
.tutor-shell .tutor-btn-stop:hover {
  background: #d8382c;
  border-color: #d8382c;
}
.tutor-card .tutor-actions {
  width: 100%;
  margin-top: 0;
}
.tutor-card .tutor-actions .tutor-btn {
  flex: 1;
  padding: 16px;
  border-radius: 12px;
  font-size: 16px;
}

/* ---- the reveal -------------------------------------------------------- */
.tutor-card .tutor-reveal {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 16px;
  text-align: left;
}
.tutor-panelbox,
.tutor-card .tutor-heard {
  padding: 18px 20px;
  border-radius: 16px;
  border: 1px solid var(--t-border, #e6efff);
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tutor-boxlabel {
  margin: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
}

/* score, and the components that produced it */
.tutor-scorecard {
  display: flex;
  gap: 18px;
  align-items: center;
  padding: 20px;
  border-radius: 16px;
  border: 1px solid var(--t-border, #e6efff);
  background: var(--t-light, #f4f9ff);
}
.tutor-scoredial {
  position: relative;
  width: 108px;
  height: 108px;
  display: grid;
  place-items: center;
  flex: none;
  --arc: 0deg;
}
.tutor-scoredial-arc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    from -90deg,
    var(--t-blue, #005bff) 0deg var(--arc),
    var(--t-border, #e6efff) var(--arc)
  );
  mask: radial-gradient(circle closest-side, transparent 0 78%, #000 78% 100%);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 78%, #000 78% 100%);
}
.tutor-scoredial-c {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.tutor-scoredial-num {
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  color: var(--t-navy, #031f42);
  font-variant-numeric: tabular-nums;
}
.tutor-scoredial-cap {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
  margin-top: 3px;
}
.tutor-compbars {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.tutor-compbar {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.tutor-compbar-top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
}
.tutor-compbar-top b {
  color: var(--t-navy, #031f42);
  font-variant-numeric: tabular-nums;
}
.tutor-compbar-track {
  height: 5px;
  border-radius: 3px;
  background: var(--t-border, #e6efff);
  overflow: hidden;
}
.tutor-compbar-track i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--t-blue, #005bff);
  transition: width 0.5s ease;
}
.tutor-compbar:nth-child(2n) .tutor-compbar-track i {
  background: #00b9a3;
}

.tutor-heard-legend {
  margin: 0;
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--t-muted, #5b6d84);
}

/* the coaching box, now with the handoff's AI badge */
.tutor-card .tutor-coach {
  flex-direction: row;
  gap: 12px;
  align-items: flex-start;
  padding: 18px 20px;
  border-radius: 16px;
  border: 1px solid rgba(0, 91, 255, 0.2);
  border-left-width: 1px;
  background: rgba(0, 91, 255, 0.05);
  display: flex;
}
.tutor-coach-badge {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  flex: none;
  background: var(--t-blue, #005bff);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.tutor-coach-body {
  flex: 1;
  min-width: 0;
}
.tutor-card .tutor-coach .tutor-coach-label {
  color: #0a3f8f;
}
.tutor-card .tutor-coach .tutor-coach-text,
.tutor-card .tutor-coach .tutor-coach-do {
  color: var(--t-navy, #031f42);
}
.tutor-card .tutor-coach .tutor-coach-do {
  border-top-color: rgba(0, 91, 255, 0.18);
}
.tutor-card .tutor-coach.is-good {
  border-color: rgba(15, 122, 106, 0.25);
  background: rgba(15, 122, 106, 0.06);
}
.tutor-card .tutor-coach.is-good .tutor-coach-badge {
  background: var(--t-accent, #0f7a6a);
}
.tutor-card .tutor-coach.is-good .tutor-coach-label {
  color: #0b5e51;
}

@media (max-width: 620px) {
  .tutor-run-body {
    padding: 24px 18px;
    gap: 18px;
  }
  .tutor-card-head {
    padding: 14px 16px;
  }
  .tutor-card .tutor-prompt {
    font-size: 22px;
  }
  .tutor-dial {
    width: 168px;
    height: 168px;
  }
  .tutor-card .tutor-timer {
    font-size: 42px;
  }
  .tutor-qbar {
    width: 72px;
  }
  .tutor-scorecard {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }
  .tutor-scoredial {
    margin: 0 auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tutor-dial.is-send .tutor-dial-arc,
  .tutor-dial.is-rec .tutor-dial-glow,
  .tutor-eyebrow.is-rec::before,
  .tutor-steps li.is-live b {
    animation: none;
  }
  .tutor-bars i {
    transition: none;
  }
}

/* ==========================================================================
   The same design, carried across the picker and the mic check.

   The handoff only covered the recording flow, so the two screens either side
   of it were still on the old navy-and-dots styling. The first thing a student
   sees was the one screen that had not been redesigned.
   ========================================================================== */

/* ---- mic check --------------------------------------------------------- */
.tutor-card-narrow {
  max-width: 560px;
}
.tutor-card .tutor-prompt-sm {
  font-size: 21px;
  line-height: 1.35;
}
/* The wrapper used to size a 320px canvas. It now just centres the dial. */
.tutor-card .tutor-orb-wrap {
  width: auto;
  height: auto;
  display: grid;
  place-items: center;
}
.tutor-card .tutor-permhelp,
.tutor-card .tutor-fineprint {
  width: 100%;
}
.tutor-card .tutor-actions {
  flex-wrap: wrap;
  justify-content: center;
}
/* Three or four buttons in one row must not each be forced to a third of the
   card; only the primary should stretch. */
.tutor-card .tutor-actions .tutor-btn {
  flex: 0 1 auto;
  padding: 14px 22px;
  font-size: 15px;
}
.tutor-card .tutor-actions .tutor-btn-lg {
  flex: 1 1 100%;
}

/* ---- picker ------------------------------------------------------------ */
.tutor-tab {
  border-radius: 99px;
  font-weight: 600;
}
.tutor-tab:hover {
  border-color: var(--t-blue, #005bff);
  color: var(--t-blue, #005bff);
}
.tutor-tab[aria-selected='true'] {
  background: var(--t-blue, #005bff);
  border-color: var(--t-blue, #005bff);
  color: #fff;
  box-shadow: 0 8px 22px rgba(0, 91, 255, 0.24);
}

.tutor-track-intro,
.tutor-shell .tutor-panel,
.tutor-xp {
  border-radius: 20px;
  border: 1px solid var(--t-border, #e6efff);
  box-shadow: 0 18px 44px rgba(3, 31, 66, 0.07);
}

/* The band legend reads as a section label, like every other label in the
   redesign, rather than as body text. */
.tutor-bands {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
  gap: 16px;
}

.tutor-cell {
  border-radius: 14px;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.15s ease;
}
.tutor-cell:hover {
  border-color: var(--t-blue, #005bff);
  box-shadow: 0 10px 24px rgba(0, 91, 255, 0.12);
  transform: translateY(-2px);
}
/* Fifty numbers in a grid: tabular figures stop them jittering column to
   column, which is the whole reason the design used a mono face here. */
.tutor-cell-no {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.tutor-cell-band {
  font-weight: 700;
  letter-spacing: 0.1em;
}
.tutor-xp-num,
.tutor-xp-meta {
  font-variant-numeric: tabular-nums;
}
.tutor-xp-bar i {
  background: var(--t-blue, #005bff);
}

@media (prefers-reduced-motion: reduce) {
  .tutor-cell:hover {
    transform: none;
  }
}
/* The stable section heading lives in the head bar; the sentence below it
   changes with the state, so it is body text, not a heading. */
.tutor-run-meta-h {
  margin: 0;
  font-size: 11px;
}

/* A perfect answer should read as one. The number stays (it is the score) and
   the word under it changes, rather than replacing the score with a slogan. */
.tutor-dial.is-perfect .tutor-phase {
  color: var(--t-accent, #0f7a6a);
}
.tutor-dial.is-perfect .tutor-timer {
  color: var(--t-accent, #0f7a6a);
}

/* Component averages cover only the answers actually spoken. Without this line
   "Pace 97" sits beside a total of 19 and reads as a contradiction. */
.tutor-metrics-note {
  grid-column: 1 / -1;
  margin: 0 0 4px;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--t-light, #f4f9ff);
  border: 1px solid var(--t-border, #e6efff);
  font-size: 13px;
  line-height: 1.5;
  color: var(--t-muted, #5b6d84);
}

/* Programmatic focus targets are not controls.
 *
 * screen() moves focus to the heading of whichever screen just appeared, so a
 * keyboard user is not dropped back to the top of a page carrying roughly 125
 * nav links ahead of the app. Browsers then apply :focus-visible to it, because
 * the heuristic cannot tell a scripted focus from a keyboard one and defaults to
 * showing the ring. The result was a 3px box drawn around "Speaking practice" on
 * every screen change, on every browser and device, clearing only when the
 * student clicked elsewhere.
 *
 * The focus still moves, which is the accessible behaviour. Only the ring goes,
 * and only on elements that exist to receive focus rather than be operated.
 */
.tutor-shell [data-focus-target]:focus,
.tutor-shell [data-focus-target]:focus-visible,
.tutor-shell h1[tabindex='-1']:focus-visible,
.tutor-shell h2[tabindex='-1']:focus-visible {
  outline: none;
}

/* The badge used to read "AI", which was not true: the quick tip is chosen by
   rules from the measured numbers, with no model call anywhere near it. A
   lightbulb says "tip" without claiming a machine wrote it. */
.tutor-coach-badge svg {
  display: block;
}

/* Where the real feedback is. One sentence of advice per answer reads as the
   whole of what the student gets unless we say otherwise. */
.tutor-coach-more {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #7a6528;
}
.tutor-coach.is-good .tutor-coach-more {
  color: #4a6b62;
}

.tutor-heard-top {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 5px;
}
.tutor-heard-top .tutor-heard-label {
  margin: 0;
}
.tutor-play-mine {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid rgba(3, 31, 66, 0.18);
  border-radius: 999px;
  background: #fff;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: #2c4a6e;
  cursor: pointer;
}
.tutor-play-mine:hover {
  border-color: var(--t-accent, #0f7a6a);
  color: var(--t-accent, #0f7a6a);
}

@media (prefers-reduced-motion: reduce) {
  .tutor-btn-stop::before {
    animation: none;
  }
}

/* ---- word by word on the target sentence -----------------------------------
   Three states on purpose. `tw-skip` is for words under three letters, which
   missedWords deliberately ignores as speech-recogniser noise: they were never
   checked, so they must not be coloured as if they passed. Colour is never the
   only signal, because roughly one man in twelve cannot separate these two
   hues: missed words also carry an underline. */
.tutor-reveal-text .tw {
  font-weight: 600;
}
.tutor-reveal-text .tw-ok {
  color: #0f7a3d;
}
.tutor-reveal-text .tw-no {
  color: #b3282c;
  text-decoration: underline;
  text-decoration-style: wavy;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.tutor-reveal-text .tw-skip {
  color: var(--t-muted, #5b6d84);
  font-weight: 400;
}

/* ---- the practice step ----------------------------------------------------- */
.tutor-drill {
  margin-top: 14px;
  padding: 13px 15px;
  border-radius: 12px;
  background: rgba(179, 40, 44, 0.06);
  border: 1px solid rgba(179, 40, 44, 0.16);
  text-align: left;
}
.tutor-drill-label {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #b3282c;
}
.tutor-drill-words {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin: 0 0 9px;
}
.tutor-drill-words b {
  padding: 5px 11px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid rgba(179, 40, 44, 0.25);
  color: #031f42;
  font-size: 14px;
  font-weight: 700;
}
.tutor-drill-note {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #5b6d84;
}

/* ---- what this exercise is about to do, before it does it ------------------
   The thinking time steps down as a student climbs and disappears entirely for
   the last fifteen, matching the real test. Nothing ever said so, and a silent
   rule change reads as a fault. */
.tutor-brief {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.tutor-brief-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(3, 31, 66, 0.55);
}
.tutor-brief-card {
  position: relative;
  max-width: 460px;
  width: 100%;
  padding: 26px 26px 22px;
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 24px 60px rgba(3, 31, 66, 0.3);
  text-align: left;
}
.tutor-brief-card h2 {
  margin: 0 0 14px;
  font-size: 20px;
  font-weight: 800;
  color: #031f42;
}
.tutor-brief-card ul {
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
}
.tutor-brief-card li {
  position: relative;
  padding: 0 0 11px 22px;
  font-size: 14.5px;
  line-height: 1.55;
  color: #2c4a6e;
}
.tutor-brief-card li::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--t-accent, #0f7a6a);
}
.tutor-brief-card button {
  width: 100%;
}

/* ---- where the permission control actually is ------------------------------
   Only shown in the blocked state, where the student has to find one specific
   browser control. "The lock or camera icon in the address bar" is not enough
   when every browser puts it somewhere slightly different, so it is drawn. */
.tutor-permhelp {
  margin: 16px auto 4px;
  max-width: 360px;
  padding: 14px 16px;
  border-radius: 12px;
  background: rgba(229, 72, 77, 0.05);
  border: 1px solid rgba(229, 72, 77, 0.18);
  text-align: left;
}
.tutor-permhelp[hidden] {
  display: none !important;
}
.tutor-permhelp-title {
  margin: 0 0 9px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #b3282c;
}
.tutor-permhelp-art {
  display: block;
  width: 100%;
  height: auto;
}
.tutor-permhelp-note {
  margin: 9px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #5b6d84;
}

/* ---- the suggestion box ----------------------------------------------------
   One actionable instruction per answer. It was an unstyled <p> running on
   from the delivery numbers, so the only sentence on the screen telling a
   student what to DO read as more commentary about what they had done.
   It is a labelled box now, and the label says what it is for. */
.tutor-coach {
  margin: 14px 0 0;
  padding: 13px 15px;
  border-radius: 12px;
  border: 1px solid #f0d9a8;
  border-left: 3px solid #e8a838;
  background: #fffaf0;
}
.tutor-coach-label {
  margin: 0 0 5px;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #8a5a12;
}
.tutor-coach-text {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: #3d2a08;
}
/* Nothing to fix is not a suggestion, so it does not wear the warning colours. */
.tutor-coach.is-good {
  border-color: #b7e4d4;
  border-left-color: var(--t-accent, #0f7a6a);
  background: #f2fbf8;
}
.tutor-coach.is-good .tutor-coach-label {
  color: #0b5e51;
}
.tutor-coach.is-good .tutor-coach-text {
  color: #10423a;
}

/* An empty transcript is a message, not a quotation. */
.tutor-heard-text.is-empty {
  color: var(--t-muted, #5b6d84);
  font-style: normal;
}

/* The instruction for the next answer. Separated from the diagnosis above it,
   because "what went wrong" and "what to do about it" are two different
   thoughts and a student acts on the second one. */
.tutor-coach-do {
  margin: 8px 0 0;
  padding: 8px 0 0;
  border-top: 1px dashed #eddcb8;
  font-size: 14.5px;
  line-height: 1.55;
  font-weight: 600;
  color: #3d2a08;
}
.tutor-coach.is-good .tutor-coach-do {
  border-top-color: #cbeadf;
  color: #10423a;
}

/* ==========================================================================
   SPEAKING EXERCISE, redesigned
   From the owner's Claude Design handoff, "Modern SaaS Recorder Redesign".

   Built to the handoff's measurements, with two deliberate departures, both
   agreed before starting:

   1. NO NEW FONTS. The handoff specified Space Grotesk and IBM Plex Mono.
      Layout, colour and spacing match; the type is the site's own face, so
      no page pays for two extra font downloads. Where the handoff leaned on
      mono for the timer and the tracked-out labels, that job is done here
      with tabular figures and letter-spacing instead.
   2. The "15 s prep" button is not built. The owner asked for it to be left
      out, and Interview's thinking time is automatic already.
   ========================================================================== */

.tutor-shell {
  --t-blue: #005bff;
  --t-blue-dark: #0049cc;
  --t-red: #f44336;
  --t-amber: #a07a12;
}

/* ---- the card --------------------------------------------------------- */
.tutor-card {
  width: 100%;
  max-width: 620px;
  margin: 0 auto;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid var(--t-border, #e6efff);
  background: #fff;
  box-shadow: 0 18px 44px rgba(3, 31, 66, 0.07);
}
.tutor-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--t-border, #e6efff);
}
.tutor-card-head-l,
.tutor-card-head-r {
  display: flex;
  align-items: center;
  gap: 12px;
}
.tutor-card-head-r {
  gap: 8px;
}
.tutor-card .tutor-quit {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  padding: 0;
  border: 1px solid var(--t-border, #e6efff);
  background: #fff;
  display: grid;
  place-items: center;
  font-size: 15px;
  line-height: 1;
  color: var(--t-muted, #5b6d84);
  cursor: pointer;
  font-family: inherit;
}
.tutor-card .tutor-quit:hover {
  border-color: var(--t-blue, #005bff);
  color: var(--t-blue, #005bff);
}
.tutor-run-meta {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
  font-weight: 600;
}
.tutor-slash {
  opacity: 0.55;
  margin: 0 2px;
}
.tutor-qbar {
  width: 110px;
  height: 4px;
  border-radius: 2px;
  background: var(--t-border, #e6efff);
  overflow: hidden;
}
.tutor-qbar i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--t-blue, #005bff);
  transition: width 0.35s ease;
}
.tutor-qcount {
  font-size: 11px;
  color: var(--t-muted, #5b6d84);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.tutor-run-body {
  padding: 30px 34px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}

/* ---- the state line --------------------------------------------------- */
.tutor-eyebrow {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--t-blue, #005bff);
  display: flex;
  align-items: center;
  gap: 8px;
}
.tutor-eyebrow.is-prep {
  color: var(--t-amber, #a07a12);
}
.tutor-eyebrow.is-rec {
  color: var(--t-red, #f44336);
}
.tutor-eyebrow.is-rec::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--t-red, #f44336);
  animation: tutorBlink 1.1s ease-in-out infinite;
}
@keyframes tutorBlink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}

.tutor-card .tutor-prompt {
  margin: 0;
  text-align: center;
  font-size: 27px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--t-navy, #031f42);
  text-wrap: pretty;
}

/* ---- the dial ---------------------------------------------------------
   One 200px circle doing three jobs: fixed tick ring, conic progress arc
   over it, and the countdown in the middle. The arc angle is set from JS as
   --arc, so nothing here needs to know what is being counted. */
.tutor-dial {
  position: relative;
  width: 200px;
  height: 200px;
  display: grid;
  place-items: center;
  --arc: 0deg;
  --dial: var(--t-blue, #005bff);
}
.tutor-dial-ticks,
.tutor-dial-arc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* closest-side keeps the gradient radius at exactly half the box, so these
     stops stay the handoff's 84px and 98px at 200px and scale with it. */
  mask: radial-gradient(circle closest-side, transparent 0 84%, #000 84% 98%, transparent 98%);
  -webkit-mask: radial-gradient(
    circle closest-side,
    transparent 0 84%,
    #000 84% 98%,
    transparent 98%
  );
}
.tutor-dial-ticks {
  background: repeating-conic-gradient(
    from -90deg,
    rgba(3, 31, 66, 0.16) 0deg 0.7deg,
    rgba(3, 31, 66, 0) 0.7deg 6deg
  );
}
.tutor-dial-arc {
  background: conic-gradient(
    from -90deg,
    var(--dial) 0deg var(--arc),
    rgba(3, 31, 66, 0) var(--arc)
  );
  transition: none;
}
.tutor-dial-glow {
  position: absolute;
  inset: 20px;
  border-radius: 50%;
  border: 1px solid var(--t-border, #e6efff);
  background: radial-gradient(
    circle at 50% 30%,
    rgba(0, 91, 255, 0.07),
    rgba(255, 255, 255, 0) 70%
  );
}
.tutor-dial.is-rec .tutor-dial-glow {
  border-color: transparent;
  background: radial-gradient(circle, rgba(244, 67, 54, 0.09), rgba(255, 255, 255, 0) 70%);
  animation: tutorBreathe 2.4s ease-in-out infinite;
}
@keyframes tutorBreathe {
  0%,
  100% {
    opacity: 0.3;
  }
  50% {
    opacity: 0.8;
  }
}
.tutor-dial.is-send .tutor-dial-arc {
  background: conic-gradient(
    from -90deg,
    var(--t-blue, #005bff) 0deg 90deg,
    rgba(3, 31, 66, 0) 90deg
  );
  animation: tutorSpinArc 1.1s linear infinite;
}
@keyframes tutorSpinArc {
  to {
    transform: rotate(360deg);
  }
}
.tutor-dial-centre {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.tutor-card .tutor-timer {
  font-size: 50px;
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--t-navy, #031f42);
  font-variant-numeric: tabular-nums;
}
.tutor-card .tutor-timer.is-word {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--t-blue, #005bff);
}
.tutor-card .tutor-phase {
  margin: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  /* --t-muted measured 2.79:1 on the old orb centre, under the 4.5:1 floor.
     The state colour is both louder and more useful. */
  color: var(--t-blue, #005bff);
}
.tutor-dial.is-prep .tutor-phase {
  color: var(--t-amber, #a07a12);
}
.tutor-dial.is-rec .tutor-phase {
  color: var(--t-red, #f44336);
}

/* ---- level meter ------------------------------------------------------- */
.tutor-bars {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 52px;
  width: 100%;
}
.tutor-bars i {
  display: block;
  width: 5px;
  border-radius: 3px;
  height: 12%;
  background: #99bcff;
  transform-origin: center;
  transition:
    height 0.09s linear,
    background-color 0.2s linear;
}

/* ---- what is happening to the clip ------------------------------------- */
.tutor-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
}
.tutor-steps li {
  display: flex;
  justify-content: space-between;
  color: var(--t-muted, #5b6d84);
}
.tutor-steps li b {
  font-weight: 600;
  color: #2e7d32;
}
.tutor-steps li.is-live {
  color: var(--t-navy, #031f42);
}
.tutor-steps li.is-live b {
  color: var(--t-blue, #005bff);
  animation: tutorBlink 1.2s ease-in-out infinite;
}

.tutor-card .tutor-run-help {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  text-align: center;
  color: var(--t-muted, #5b6d84);
  max-width: 360px;
  text-wrap: pretty;
}

/* ---- buttons, restyled to the handoff ---------------------------------- */
.tutor-shell .tutor-btn-primary {
  background: var(--t-blue, #005bff);
  box-shadow: 0 8px 22px rgba(0, 91, 255, 0.24);
}
.tutor-shell .tutor-btn-primary:hover {
  background: var(--t-blue-dark, #0049cc);
}
.tutor-shell .tutor-btn-stop {
  background: var(--t-red, #f44336);
  border-color: var(--t-red, #f44336);
  box-shadow: none;
}
.tutor-shell .tutor-btn-stop:hover {
  background: #d8382c;
  border-color: #d8382c;
}
.tutor-card .tutor-actions {
  width: 100%;
  margin-top: 0;
}
.tutor-card .tutor-actions .tutor-btn {
  flex: 1;
  padding: 16px;
  border-radius: 12px;
  font-size: 16px;
}

/* ---- the reveal -------------------------------------------------------- */
.tutor-card .tutor-reveal {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 16px;
  text-align: left;
}
.tutor-panelbox,
.tutor-card .tutor-heard {
  padding: 18px 20px;
  border-radius: 16px;
  border: 1px solid var(--t-border, #e6efff);
  background: #fff;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tutor-boxlabel {
  margin: 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
}

/* score, and the components that produced it */
.tutor-scorecard {
  display: flex;
  gap: 18px;
  align-items: center;
  padding: 20px;
  border-radius: 16px;
  border: 1px solid var(--t-border, #e6efff);
  background: var(--t-light, #f4f9ff);
}
.tutor-scoredial {
  position: relative;
  width: 108px;
  height: 108px;
  display: grid;
  place-items: center;
  flex: none;
  --arc: 0deg;
}
.tutor-scoredial-arc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    from -90deg,
    var(--t-blue, #005bff) 0deg var(--arc),
    var(--t-border, #e6efff) var(--arc)
  );
  mask: radial-gradient(circle closest-side, transparent 0 78%, #000 78% 100%);
  -webkit-mask: radial-gradient(circle closest-side, transparent 0 78%, #000 78% 100%);
}
.tutor-scoredial-c {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.tutor-scoredial-num {
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  color: var(--t-navy, #031f42);
  font-variant-numeric: tabular-nums;
}
.tutor-scoredial-cap {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
  margin-top: 3px;
}
.tutor-compbars {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
.tutor-compbar {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.tutor-compbar-top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
}
.tutor-compbar-top b {
  color: var(--t-navy, #031f42);
  font-variant-numeric: tabular-nums;
}
.tutor-compbar-track {
  height: 5px;
  border-radius: 3px;
  background: var(--t-border, #e6efff);
  overflow: hidden;
}
.tutor-compbar-track i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--t-blue, #005bff);
  transition: width 0.5s ease;
}
.tutor-compbar:nth-child(2n) .tutor-compbar-track i {
  background: #00b9a3;
}

.tutor-heard-legend {
  margin: 0;
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--t-muted, #5b6d84);
}

/* the coaching box, now with the handoff's AI badge */
.tutor-card .tutor-coach {
  flex-direction: row;
  gap: 12px;
  align-items: flex-start;
  padding: 18px 20px;
  border-radius: 16px;
  border: 1px solid rgba(0, 91, 255, 0.2);
  border-left-width: 1px;
  background: rgba(0, 91, 255, 0.05);
  display: flex;
}
.tutor-coach-badge {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  flex: none;
  background: var(--t-blue, #005bff);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.tutor-coach-body {
  flex: 1;
  min-width: 0;
}
.tutor-card .tutor-coach .tutor-coach-label {
  color: #0a3f8f;
}
.tutor-card .tutor-coach .tutor-coach-text,
.tutor-card .tutor-coach .tutor-coach-do {
  color: var(--t-navy, #031f42);
}
.tutor-card .tutor-coach .tutor-coach-do {
  border-top-color: rgba(0, 91, 255, 0.18);
}
.tutor-card .tutor-coach.is-good {
  border-color: rgba(15, 122, 106, 0.25);
  background: rgba(15, 122, 106, 0.06);
}
.tutor-card .tutor-coach.is-good .tutor-coach-badge {
  background: var(--t-accent, #0f7a6a);
}
.tutor-card .tutor-coach.is-good .tutor-coach-label {
  color: #0b5e51;
}

@media (max-width: 620px) {
  .tutor-run-body {
    padding: 24px 18px;
    gap: 18px;
  }
  .tutor-card-head {
    padding: 14px 16px;
  }
  .tutor-card .tutor-prompt {
    font-size: 22px;
  }
  .tutor-dial {
    width: 168px;
    height: 168px;
  }
  .tutor-card .tutor-timer {
    font-size: 42px;
  }
  .tutor-qbar {
    width: 72px;
  }
  .tutor-scorecard {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }
  .tutor-scoredial {
    margin: 0 auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tutor-dial.is-send .tutor-dial-arc,
  .tutor-dial.is-rec .tutor-dial-glow,
  .tutor-eyebrow.is-rec::before,
  .tutor-steps li.is-live b {
    animation: none;
  }
  .tutor-bars i {
    transition: none;
  }
}

/* ==========================================================================
   The same design, carried across the picker and the mic check.

   The handoff only covered the recording flow, so the two screens either side
   of it were still on the old navy-and-dots styling. The first thing a student
   sees was the one screen that had not been redesigned.
   ========================================================================== */

/* ---- mic check --------------------------------------------------------- */
.tutor-card-narrow {
  max-width: 560px;
}
.tutor-card .tutor-prompt-sm {
  font-size: 21px;
  line-height: 1.35;
}
/* The wrapper used to size a 320px canvas. It now just centres the dial. */
.tutor-card .tutor-orb-wrap {
  width: auto;
  height: auto;
  display: grid;
  place-items: center;
}
.tutor-card .tutor-permhelp,
.tutor-card .tutor-fineprint {
  width: 100%;
}
.tutor-card .tutor-actions {
  flex-wrap: wrap;
  justify-content: center;
}
/* Three or four buttons in one row must not each be forced to a third of the
   card; only the primary should stretch. */
.tutor-card .tutor-actions .tutor-btn {
  flex: 0 1 auto;
  padding: 14px 22px;
  font-size: 15px;
}
.tutor-card .tutor-actions .tutor-btn-lg {
  flex: 1 1 100%;
}

/* ---- picker ------------------------------------------------------------ */
.tutor-tab {
  border-radius: 99px;
  font-weight: 600;
}
.tutor-tab:hover {
  border-color: var(--t-blue, #005bff);
  color: var(--t-blue, #005bff);
}
.tutor-tab[aria-selected='true'] {
  background: var(--t-blue, #005bff);
  border-color: var(--t-blue, #005bff);
  color: #fff;
  box-shadow: 0 8px 22px rgba(0, 91, 255, 0.24);
}

.tutor-track-intro,
.tutor-shell .tutor-panel,
.tutor-xp {
  border-radius: 20px;
  border: 1px solid var(--t-border, #e6efff);
  box-shadow: 0 18px 44px rgba(3, 31, 66, 0.07);
}

/* The band legend reads as a section label, like every other label in the
   redesign, rather than as body text. */
.tutor-bands {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--t-muted, #5b6d84);
  gap: 16px;
}

.tutor-cell {
  border-radius: 14px;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.15s ease;
}
.tutor-cell:hover {
  border-color: var(--t-blue, #005bff);
  box-shadow: 0 10px 24px rgba(0, 91, 255, 0.12);
  transform: translateY(-2px);
}
/* Fifty numbers in a grid: tabular figures stop them jittering column to
   column, which is the whole reason the design used a mono face here. */
.tutor-cell-no {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.tutor-cell-band {
  font-weight: 700;
  letter-spacing: 0.1em;
}
.tutor-xp-num,
.tutor-xp-meta {
  font-variant-numeric: tabular-nums;
}
.tutor-xp-bar i {
  background: var(--t-blue, #005bff);
}

@media (prefers-reduced-motion: reduce) {
  .tutor-cell:hover {
    transform: none;
  }
}
/* The stable section heading lives in the head bar; the sentence below it
   changes with the state, so it is body text, not a heading. */
.tutor-run-meta-h {
  margin: 0;
  font-size: 11px;
}

/* A perfect answer should read as one. The number stays (it is the score) and
   the word under it changes, rather than replacing the score with a slogan. */
.tutor-dial.is-perfect .tutor-phase {
  color: var(--t-accent, #0f7a6a);
}
.tutor-dial.is-perfect .tutor-timer {
  color: var(--t-accent, #0f7a6a);
}

/* Component averages cover only the answers actually spoken. Without this line
   "Pace 97" sits beside a total of 19 and reads as a contradiction. */
.tutor-metrics-note {
  grid-column: 1 / -1;
  margin: 0 0 4px;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--t-light, #f4f9ff);
  border: 1px solid var(--t-border, #e6efff);
  font-size: 13px;
  line-height: 1.5;
  color: var(--t-muted, #5b6d84);
}

/* Programmatic focus targets are not controls.
 *
 * screen() moves focus to the heading of whichever screen just appeared, so a
 * keyboard user is not dropped back to the top of a page carrying roughly 125
 * nav links ahead of the app. Browsers then apply :focus-visible to it, because
 * the heuristic cannot tell a scripted focus from a keyboard one and defaults to
 * showing the ring. The result was a 3px box drawn around "Speaking practice" on
 * every screen change, on every browser and device, clearing only when the
 * student clicked elsewhere.
 *
 * The focus still moves, which is the accessible behaviour. Only the ring goes,
 * and only on elements that exist to receive focus rather than be operated.
 */
.tutor-shell [data-focus-target]:focus,
.tutor-shell [data-focus-target]:focus-visible,
.tutor-shell h1[tabindex='-1']:focus-visible,
.tutor-shell h2[tabindex='-1']:focus-visible {
  outline: none;
}

/* The badge used to read "AI", which was not true: the quick tip is chosen by
   rules from the measured numbers, with no model call anywhere near it. A
   lightbulb says "tip" without claiming a machine wrote it. */
.tutor-coach-badge svg {
  display: block;
}

/* Where the real feedback is. One sentence of advice per answer reads as the
   whole of what the student gets unless we say otherwise. */
.tutor-coach-more {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: #7a6528;
}
.tutor-coach.is-good .tutor-coach-more {
  color: #4a6b62;
}

/* The heard row now holds a label and one button. Kept wrapping because the
   label can be long on a narrow phone. */
.tutor-heard-top {
  flex-wrap: wrap;
  gap: 8px;
}

/* One way the question could have been answered, folded away under the
 * student's own answer in the end-of-exercise report.
 *
 * Collapsed by default and never auto-opened: the student's own words are the
 * subject of that panel, and a model answer sitting open above them invites
 * copying rather than comparing. */
.tutor-demo {
  margin: 10px 0 0;
  border-top: 1px solid rgba(3, 31, 66, 0.1);
  padding-top: 10px;
}
.tutor-demo > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  color: var(--t-accent, #0f7a6a);
  list-style: none;
}
.tutor-demo > summary::-webkit-details-marker {
  display: none;
}
.tutor-demo > summary::before {
  content: '\25B8';
  display: inline-block;
  margin-right: 6px;
  transition: transform 0.15s;
}
.tutor-demo[open] > summary::before {
  transform: rotate(90deg);
}
.tutor-demo-text {
  margin: 8px 0 0;
  font-size: 14px;
  line-height: 1.65;
  color: #24405f;
}
.tutor-demo-note {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: #6b7f96;
}

/* ------------------------------------------------------------------ */
/* Full screen (tutor)                                                 */
/* Same two paths as the drills: iOS Safari implements requestFullscreen */
/* on <video> only, so the fallback pins the shell instead.             */
/* ------------------------------------------------------------------ */
.tutor-fs {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 32px;
  padding: 0 10px;
  margin-left: 10px;
  border-radius: 8px;
  border: 1px solid rgba(3, 31, 66, 0.18);
  background: #fff;
  color: #2c4a6e;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}
.tutor-fs:hover {
  border-color: var(--t-accent, #0f7a6a);
  color: var(--t-accent, #0f7a6a);
}
.tutor-fs.is-on {
  background: var(--t-accent, #0f7a6a);
  border-color: var(--t-accent, #0f7a6a);
  color: #fff;
}
.tutor-fs svg {
  display: block;
}

/* The run head already holds a progress bar and a counter. */
@media (max-width: 560px) {
  .tutor-fs-label {
    display: none;
  }
  .tutor-fs {
    padding: 0;
    width: 32px;
    margin-left: 6px;
  }
}

/* SPLIT ON PURPOSE. One unsupported selector invalidates an entire selector
   list, and Safari before 16.4 does not know :fullscreen. Grouped, the whole
   rule died on exactly the browsers that have no element requestFullscreen and
   therefore always take the faux path: .is-faux-fs lost its overflow-y:auto
   while html.tutor-fs-lock held overflow:hidden, so anything below the fold was
   unreachable. Three rules cannot fail together. */
.tutor-shell.is-faux-fs {
  background: var(--t-bg, #f6f9fc);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tutor-shell:fullscreen {
  background: var(--t-bg, #f6f9fc);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tutor-shell:-webkit-full-screen {
  background: var(--t-bg, #f6f9fc);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.tutor-shell:fullscreen,
.tutor-shell:-webkit-full-screen {
  width: 100%;
  height: 100%;
  padding: 20px 16px 32px;
}
.tutor-shell.is-faux-fs {
  position: fixed;
  inset: 0;
  z-index: 9999;
  padding: max(16px, env(safe-area-inset-top)) 16px max(24px, env(safe-area-inset-bottom));
}
html.tutor-fs-lock,
html.tutor-fs-lock body {
  overflow: hidden;
  overscroll-behavior: none;
}

/* ------------------------------------------------------------------ */
/* The model reading, as its own card                                  */
/*                                                                     */
/* "Hear it read well" as a bare pill did not say what it was or why   */
/* it was worth pressing. This gives it a reason to exist on screen.   */
/* ------------------------------------------------------------------ */
.tutor-model {
  margin: 14px 0 0;
  border: 1px solid #d7e6f5;
  border-radius: 14px;
  padding: 16px;
  background: linear-gradient(180deg, #f5fbff 0%, #ffffff 100%);
}
.tutor-model-eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--t-accent, #0f7a6a);
  margin: 0 0 6px;
}
.tutor-model-title {
  margin: 0 0 6px;
  font-size: 16px;
  line-height: 1.35;
  font-weight: 700;
  color: #0e2440;
}
.tutor-model-body {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: #55697f;
}
.tutor-model-btn {
  margin-top: 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid var(--t-accent, #0f7a6a);
  background: var(--t-accent, #0f7a6a);
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.tutor-model-btn:hover {
  filter: brightness(1.08);
}
.tutor-model-btn.is-ghost {
  background: #fff;
  color: #2c4a6e;
  border-color: rgba(3, 31, 66, 0.18);
}
.tutor-model-pair {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.tutor-model-stats {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.tutor-model-stats li {
  display: grid;
  grid-template-columns: 74px auto 1fr;
  align-items: baseline;
  gap: 10px;
  font-size: 13px;
}
.tutor-model-stats span {
  color: #7b8ca1;
}
.tutor-model-stats b {
  color: #0e2440;
  font-weight: 700;
}
.tutor-model-stats i {
  font-style: normal;
  color: #8a9bb0;
  font-size: 12px;
}

/* The go button.
 *
 * "Test my mic" was primary and "Start exercise" was a ghost, so the optional
 * detour looked like the main action and the thing the student came for looked
 * like a link. Green rather than the navy primary because on this screen there
 * is already a navy primary ("Allow microphone") that has to be pressed first,
 * and two navy buttons side by side rank nothing. */
.tutor-btn-go {
  background: var(--t-accent, #0f7a6a);
  border-color: var(--t-accent, #0f7a6a);
  color: #fff;
}
.tutor-btn-go:hover {
  filter: brightness(1.08);
}
.tutor-btn-go:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Playing, not "press to play".
 *
 * The prompt slot showed a play triangle while the clip was already playing,
 * which reads as a button and is not one: the student cannot replay a
 * listen-and-repeat prompt, that is the exercise. Three bars that move say
 * "this is playing" without offering anything to press. */
.tutor-playing {
  display: inline-flex;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
  height: 34px;
}
.tutor-playing i {
  display: block;
  width: 5px;
  border-radius: 2px;
  background: var(--t-accent, #0f7a6a);
  animation: tutorEq 900ms ease-in-out infinite;
}
.tutor-playing i:nth-child(1) { height: 14px; animation-delay: 0ms; }
.tutor-playing i:nth-child(2) { height: 26px; animation-delay: 150ms; }
.tutor-playing i:nth-child(3) { height: 18px; animation-delay: 300ms; }

@keyframes tutorEq {
  0%, 100% { transform: scaleY(0.45); }
  50%      { transform: scaleY(1); }
}

/* Motion is decoration here; the state is already in the label underneath. */
@media (prefers-reduced-motion: reduce) {
  .tutor-playing i {
    animation: none;
    transform: scaleY(0.8);
  }
}

/* Escape controls must be tappable. .tutor-fs collapsed to 32x32 under 560px
   and .tutor-quit sits at 26x26; both are how a student gets OUT of a screen,
   which makes them the worst two controls on the page to make small. The visual
   size is unchanged, the touch area is grown underneath it. */
@media (max-width: 560px) {
  .tutor-fs,
  .tutor-quit {
    position: relative;
  }
  .tutor-fs::after,
  .tutor-quit::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }
}
