.chat-active .composer-tools {
  grid-column: 1;
  grid-row: 1;
  display: flex;
}
.message audio {
  display: none;
}
.message .audio-button {
  display: flex;
  align-items: center;
  gap: 6px;
  width: fit-content;
  max-width: 100%;
  min-height: 36px;
  margin: 6px 0 0 -6px;
  padding: 6px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.25;
  text-align: left;
  box-shadow: none;
}
.message .audio-button .icon {
  width: 16px;
  height: 16px;
}
.message .audio-button:hover {
  background: rgb(31 38 79 / 6%);
  color: var(--navy);
}
.message .audio-button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.message.user .audio-button {
  color: inherit;
}
.message .audio-button[data-state='loading'] .icon {
  animation: spin 1.2s linear infinite;
}
@media (pointer: coarse), (max-width: 850px) {
  .message .audio-button {
    min-height: 44px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .message .audio-button[data-state='loading'] .icon {
    animation: none;
  }
}
.chat-mode-switch {
  display: flex;
  flex-wrap: wrap;
  flex-shrink: 0;
  gap: 8px;
  margin: 0 0 12px;
}
/* Voice and text are independent switches; at least one stays on. */
.chat-mode-switch .mode-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 12px 8px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: white;
  color: var(--blue);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.mode-toggle .toggle-track {
  position: relative;
  width: 34px;
  height: 20px;
  margin-left: 4px;
  border-radius: 999px;
  background: #c9cfdf;
  transition: background var(--motion-ui, 0.15s) ease;
}
.mode-toggle .toggle-track::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: white;
  box-shadow: 0 1px 3px #1c244b40;
  transition: transform var(--motion-ui, 0.15s) ease;
}
.mode-toggle[aria-checked='true'] {
  border-color: var(--navy);
  color: var(--navy);
}
.mode-toggle[aria-checked='true'] .toggle-track {
  background: var(--navy);
}
.mode-toggle[aria-checked='true'] .toggle-track::after {
  transform: translateX(14px);
}
/* The voice switch shows a struck-through microphone when off and a green one when on. */
.mode-toggle .toggle-icon {
  display: flex;
}
#voice-mode[aria-checked='true'] .mic-off,
#voice-mode:not([aria-checked='true']) .mic-on {
  display: none;
}
#voice-mode[aria-checked='true'] .mic-on {
  color: #2f8a5f;
}
.mode-toggle:disabled {
  opacity: 0.6;
  cursor: default;
}
.chat-active #message-input,
.chat-active #send-button,
.chat-active #attach-button {
  height: 44px;
  min-height: 44px;
  max-height: 44px;
  box-sizing: border-box;
}
.chat-active #message-input {
  padding: 10px 12px;
  line-height: 22px;
}
#voice-screen {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: radial-gradient(ellipse at top, #e9edf8, #fff 65%);
  overflow: hidden;
}
.voice-stage {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 32px;
  padding: 42px 16px 20px;
  text-align: center;
}
.voice-stage h2 {
  font-size: 18px;
  color: var(--navy);
  margin: 0;
}
.voice-stage p {
  color: var(--muted);
  font-size: 12px;
  margin: 8px 0 0;
}
.voice-orb {
  --voice-energy: 0;
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  width: 208px;
  height: 208px;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid #ffffff60;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 20%, #405e93, #1c244b 70%);
  box-shadow: 0 12px 40px #1c244b25;
}
.voice-orb::before,
.voice-orb::after {
  content: '';
  position: absolute;
  inset: -9px;
  z-index: -1;
  border-radius: 44% 56% 53% 47% / 48% 42% 58% 52%;
  background: conic-gradient(from 30deg, #799fe8, #9880dc, #f2b73f, #f0a86e, #70c7cb, #799fe8);
  opacity: 0.5;
  transform: scale(calc(1 + var(--voice-energy) * 0.12));
  will-change: transform, opacity;
}
.voice-orb::after {
  inset: -16px;
  filter: blur(16px);
  opacity: calc(0.2 + var(--voice-energy) * 0.45);
}
.voice-orb:disabled {
  opacity: 1;
  cursor: default;
}
.voice-brand {
  display: block;
  overflow: hidden;
  width: 44%;
  aspect-ratio: 403 / 410;
  pointer-events: none;
  filter: drop-shadow(0 2px 4px #1c244b50);
}
.voice-brand img {
  display: block;
  width: 100%;
  max-width: none;
  height: auto;
}
/* Speech movement has one driver: the energy of the samples reaching the output. */
.voice-orb::before {
  opacity: calc(0.5 + var(--voice-energy) * 0.3);
  rotate: calc(var(--voice-energy) * 7deg);
}
.voice-loading {
  display: none;
  position: absolute;
  inset: 5px;
  border: 2px solid #ffffff20;
  border-top-color: #ffffff90;
  border-radius: 50%;
  pointer-events: none;
}
#voice-screen[data-loading='true'] .voice-loading {
  display: block;
  animation: spin 1.2s linear infinite;
}
#voice-screen[data-loading='true'] #voice-state {
  font-size: 12px;
  font-weight: 400;
  color: var(--muted);
}
#voice-screen[data-state='recording'] .voice-orb {
  box-shadow: 0 0 0 5px #f2b73f45;
}
/* Audio stays in the DOM for playback and history; the orb is its voice-mode control. */
#voice-transcript .message.user .attachment-open[data-mime-type^='audio/'] {
  display: none;
}
#chat-view.voice-and-text .message.user .attachment-open[data-mime-type^='audio/'],
#chat-view.voice-and-text audio {
  display: none;
}
#voice-transcript audio {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .voice-orb::before,
  .voice-orb::after {
    transform: none;
  }
}
#voice-transcript {
  flex: 1;
  min-height: 0;
  display: flex;
}
.chat-active #voice-transcript .messages {
  width: 100%;
  padding: 12px max(16px, calc((100% - 640px) / 2));
  gap: 14px;
}
#voice-transcript .message {
  align-self: stretch;
  max-width: 100%;
  background: #ffffffb8;
  color: var(--navy);
}
#voice-transcript .message.user {
  font-size: 11px;
  background: transparent;
  color: var(--muted);
  padding: 2px 12px;
}
#voice-transcript .message.assistant {
  font-size: 16px;
  line-height: 1.7;
}
#voice-transcript .chat-welcome {
  margin: auto;
}
#voice-transcript .chat-welcome h2 {
  font-size: 16px;
}
/* Choosing a situation is its own step: hide the voice controls until one is picked. */
#voice-screen:has(.situation-welcome) .voice-stage,
#voice-screen:has(.situation-welcome) .voice-controls,
#voice-transcript .situation-hint {
  display: none;
}
#voice-transcript .situation-welcome {
  margin: 0 auto;
  max-width: 960px;
}
.chat-active #voice-screen:has(.situation-welcome) #voice-transcript .messages {
  padding: 20px 24px;
}
.voice-controls {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 14px 16px;
  gap: 8px;
  border-top: 1px solid var(--line);
  background: #ffffffd9;
}
#record-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: min(100%, 300px);
  min-height: 56px;
  border: 0;
  border-radius: 30px;
  background: var(--navy);
  color: white;
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 6px 16px #1c244b20;
}
#record-button.recording {
  background: var(--gold);
  color: var(--navy);
}
.voice-control-status {
  display: flex;
  gap: 12px;
  align-items: center;
  font-size: 11px;
  color: var(--blue);
}
.voice-control-status:has(#record-status:empty):has(#cancel-recording[hidden]) {
  display: none;
}
#cancel-recording {
  border: 0;
  background: none;
  color: #a02b38;
  font-size: 11px;
  padding: 5px;
}
#voice-hint {
  margin: 0;
  font-size: 11px;
  color: var(--muted);
}
@media (max-width: 550px) {
  .chat-mode-switch {
    width: 100%;
    margin-bottom: 8px;
  }
  .voice-stage {
    padding-top: 40px;
  }
}
@media (max-height: 700px) {
  .voice-stage {
    flex-direction: row;
    gap: 14px;
    padding: 12px;
    text-align: left;
  }
  .voice-orb {
    width: 96px;
    height: 96px;
    box-shadow: none;
  }
  .voice-stage h2 {
    font-size: 14px;
  }
  .voice-stage p {
    display: none;
  }
  .voice-controls {
    padding: 8px;
    gap: 4px;
  }
  #record-button {
    min-height: 44px;
    font-size: 12px;
  }
  #voice-hint {
    display: none;
  }
}
@media (max-height: 450px) {
  .chat-mode-switch {
    margin-bottom: 4px;
    padding: 2px;
  }
  .chat-mode-switch button {
    min-height: 36px;
    padding: 4px 10px;
  }
  .voice-stage {
    padding: 5px 12px;
  }
  .voice-orb {
    width: 56px;
    height: 56px;
  }
}
@media (max-width: 400px) {
  .chat-active #send-button {
    font-size: 0;
    gap: 0;
    min-width: 38px;
    padding: 8px;
  }
}

@media (max-height: 700px) {
  .voice-orb::before {
    inset: -4px;
  }
  .voice-orb::after {
    inset: -7px;
    filter: blur(8px);
  }
}
/* The tutor's face (head to neck) replaces the EA symbol inside the orb; the glow stays around it. */
.voice-brand {
  /* A frame rendered from the same model and camera, so loading doesn't change the framing. */
  position: absolute;
  inset: 0;
  width: 100%;
  aspect-ratio: auto;
  border-radius: inherit;
  filter: none;
}
/* Record button: gold pill with the microphone in a dark disc; while recording it turns dark with a red pulse. */
#record-button {
  position: relative;
  justify-content: center;
  gap: 12px;
  width: auto;
  min-width: 190px;
  min-height: 58px;
  padding: 7px 60px;
  border-radius: 999px;
  background: var(--gold);
  color: var(--navy);
  font-size: 16px;
  font-weight: 700;
  box-shadow: 0 8px 20px #c9922a40;
}
/* the microphone disc sits at the left edge so the label stays centred in the button */
#record-button > .icon {
  position: absolute;
  top: 50%;
  left: 7px;
  transform: translateY(-50%);
  box-sizing: border-box;
  width: 2.75em;
  height: 2.75em;
  padding: 0.65em;
  border-radius: 50%;
  background: var(--navy);
  color: var(--gold);
}
#record-button.recording {
  background: var(--navy);
  color: white;
}
#record-button.recording > .icon {
  background: #e5484d;
  color: white;
  animation: record-pulse 1.2s ease-in-out infinite;
}
#record-button:disabled {
  opacity: 0.55;
}
@keyframes record-pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 #e5484d66;
  }
  50% {
    box-shadow: 0 0 0 9px #e5484d00;
  }
}
@media (prefers-reduced-motion: reduce) {
  #record-button.recording > .icon {
    animation: none;
  }
}
/* More room for the dialogue: no subtitle under the status, and the orb and status sit closer together. */
.voice-stage > div > p {
  display: none;
}
.voice-stage {
  gap: 22px;
  padding: 24px 16px 10px;
}
@media (max-width: 550px) {
  .voice-stage {
    padding-top: 20px;
  }
}

/* Use a still of the current 3D while loading, and when WebGL is unavailable. */
#voice-avatar {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
}
.voice-orb[data-avatar='ready'] #voice-avatar {
  opacity: 1;
}
.voice-orb[data-avatar='ready'] .voice-brand {
  opacity: 0;
}
.voice-avatar-loading {
  display: none;
  position: absolute;
  z-index: 2;
  bottom: 4px;
  padding: 3px 6px;
  border-radius: 8px;
  background: #1c244bd9;
  color: #fff;
  font-size: 9px;
  font-weight: 400;
  pointer-events: none;
}
.voice-orb[data-avatar='loading'] .voice-avatar-loading {
  display: block;
}

/* A soft gold aura follows audible speech; no autonomous flashing. Same look before the model is ready. */
.voice-orb:is([data-avatar], :not([data-avatar])) {
  background: radial-gradient(circle at 45% 30%, #59678c, #242e53 75%);
  box-shadow:
    0 10px 34px #1c244b25,
    0 0 calc(14px + var(--voice-energy) * 32px) #edbe7355;
}
.voice-orb:is([data-avatar], :not([data-avatar]))::before {
  border-radius: 50%;
  background: radial-gradient(circle, #ffe6af55 45%, #d6b1ff50 70%, transparent 75%);
  filter: blur(8px);
}
.voice-orb:is([data-avatar], :not([data-avatar]))::after {
  background: radial-gradient(circle, #ffe3a699, #c5b9ec66 55%, transparent 72%);
}
/* Thinking has its own visual state; speech and cheeks still follow audible PCM. */
.voice-neural-field {
  position: absolute;
  inset: -6px;
  border: 1px solid #6de7ff00;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 220ms ease;
}
.voice-neural-field::before,
.voice-neural-field::after {
  content: '';
  position: absolute;
  inset: -2px;
  border: 2px solid transparent;
  border-top-color: #72edffb3;
  border-bottom-color: #c495ff80;
  border-radius: 50%;
  box-shadow: 0 0 12px #78ddff30;
}
.voice-neural-field::after {
  inset: 7px;
  border-width: 1px;
  border-top-color: #de9fffb3;
  border-bottom-color: #8aeeff66;
  transform: rotate(100deg);
}
.voice-orb[data-thinking='true'] .voice-neural-field {
  opacity: 1;
  border-color: #6de7ff38;
}
.voice-orb[data-thinking='true'] .voice-neural-field::before {
  animation: neural-orbit 5s linear infinite;
}
.voice-orb[data-thinking='true'] .voice-neural-field::after {
  animation: neural-orbit 7s linear infinite reverse;
}
.voice-orb[data-thinking='true'] .voice-loading {
  border-top-color: #8beaff;
}
@keyframes neural-orbit {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .voice-neural-field {
    transition: none;
  }
  .voice-orb[data-thinking='true'] .voice-neural-field::before,
  .voice-orb[data-thinking='true'] .voice-neural-field::after,
  #voice-screen[data-loading='true'] .voice-loading {
    animation: none;
  }
}
@media (max-height: 450px) {
  .voice-stage {
    padding: 8px 12px;
    gap: 14px;
  }
}

/* Voice and text together: the conversation stays where it is and the tutor's face sits beside it. */
.chat-active .voice-and-text .chat-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
  grid-template-rows: auto minmax(0, 1fr);
}
.chat-active .voice-and-text .practice-settings {
  grid-column: 1 / -1;
}
.chat-active .voice-and-text .chat-panel {
  grid-column: 1;
  grid-row: 2;
}
.chat-active .voice-and-text #voice-screen {
  grid-column: 2;
  grid-row: 2;
  justify-content: center;
}
.voice-and-text #voice-transcript {
  display: none;
}
.voice-and-text .voice-stage {
  gap: 16px;
  padding: 24px 12px 12px;
}
.voice-and-text .voice-stage > div > p {
  display: none;
}
@media (max-width: 850px), (max-height: 620px) {
  .chat-active .voice-and-text .chat-layout {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr);
  }
  /* The phone voice screen is a size container, so it needs an explicit height above the chat. */
  .chat-active .voice-and-text #voice-screen {
    grid-column: 1;
    grid-row: 2;
    height: 96px;
    grid-template-columns: 76px minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    align-items: center;
    padding: 0 12px;
  }
  .chat-active .voice-and-text #voice-screen .voice-stage {
    grid-column: 1;
    grid-row: 1;
    padding: 0;
    border-top: 0;
  }
  .chat-active .voice-and-text #voice-screen .voice-stage > div {
    display: none;
  }
  .chat-active .voice-and-text #voice-screen .voice-controls {
    grid-column: 2;
    grid-row: 1;
    padding: 0;
    border-top: 0;
  }
  .chat-active .voice-and-text #voice-screen .voice-orb {
    width: 72px;
    height: 72px;
  }
  .chat-active .voice-and-text .chat-panel {
    grid-row: 3;
  }
  .voice-and-text .voice-stage {
    flex-direction: row;
    padding: 8px;
  }
  .voice-and-text .voice-orb {
    width: 72px;
    height: 72px;
  }
}

/* Same framing as the live v3 renderer, including during loading and fallback. */
.voice-brand {
  width: 100%;
  aspect-ratio: 1;
  margin-top: 0;
  -webkit-mask-image: none;
  mask-image: none;
}
/* Captions off: the tutor's screen without the written conversation. */
#chat-view.captions-off #voice-transcript {
  visibility: hidden;
}
/* The tutor fills more of the circle: scaled up from the base and nudged down, so the head keeps a little
   room under the top edge and the neck runs past the bottom edge (no background showing through).
   Clipped back to the circle: radius 0.5/1.16, centre (0.5 + 0.05)/1.16 above the base. */
#voice-avatar,
.voice-brand {
  border-radius: 0;
  transform: translateY(5%) scale(1.16);
  transform-origin: 50% 100%;
  clip-path: circle(43.1% at 50% 52.59%);
}
