/* Narrator: a compact rounded panel (speaking circle, karaoke caption, controls, timeline),
   only as tall as its content. Its width follows the screen, and it is centred on the page. */
.narrator {
  --level: 0;
  --area-left: 0px;
  --panel-width: min(calc(100% - var(--area-left) - 32px), clamp(340px, 44vw, 720px));
  position: fixed;
  bottom: clamp(14px, 3vh, 32px);
  left: calc(var(--area-left) + (100% - var(--area-left)) / 2);
  z-index: 5;
  width: var(--panel-width);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(14px, 2vh, 20px) clamp(16px, 2vw, 28px) clamp(12px, 1.6vh, 16px);
  text-align: center;
  color: var(--ink);
  border-radius: 24px;
  /* Plain translucent black, no blur, so the panel has no visible edge on the black page. */
  background: rgba(0, 0, 0, .6);
  transform: translateX(-50%);
  transition: opacity .4s ease, transform .4s ease, left .5s ease, width .5s ease;
}
.narrator[data-state="loading"] { opacity: 0; transform: translate(-50%, 8px); }

.narrator-orb { position: relative; width: 45px; height: 45px; display: grid; place-items: center; transition: translate .8s cubic-bezier(.45, 0, .2, 1); }
/* Quiet (the chapter's voice is done): the caption fades, and the orb settles slowly into its place. */
.narrator-caption { transition: opacity .7s ease; }
.narrator.is-quiet .narrator-caption { opacity: 0; }
.narrator.is-quiet .narrator-orb { translate: 0 var(--quiet-drop, 50px); transition: translate 1.8s cubic-bezier(.45, 0, .2, 1) .3s; }
.narrator-orb::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid rgba(244, 244, 244, .5);
  transform: scale(calc(1 + var(--level) * 1.1));
  opacity: calc(.25 + var(--level) * .75);
}
.narrator-orb-core {
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: var(--ink);
  transform: scale(calc(.8 + var(--level) * .55));
  box-shadow: 0 0 calc(var(--level) * 27px) rgba(244, 244, 244, .55);
}
/* Shine while the narrator talks: a light glint circles the orb and a soft halo breathes out. */
.narrator-orb::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* Grows with the voice exactly like the outer ring; the rotation runs separately. */
  scale: calc(1 + var(--level) * 1.1);
  background: conic-gradient(from 0deg, transparent 0 62%, rgba(255, 255, 255, .15) 72%, #fff 82%, rgba(255, 255, 255, .15) 90%, transparent 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px));
  filter: drop-shadow(0 0 4px rgba(255, 255, 255, .8));
  opacity: 0;
  transition: opacity .4s ease;
}
.narrator[data-state="playing"] .narrator-orb::after { opacity: 1; animation: orb-glint 2.2s linear infinite; }
.narrator[data-state="playing"] .narrator-orb-core { animation: orb-shine 1.8s ease-in-out infinite; }
@keyframes orb-glint { to { transform: rotate(1turn); } }
@keyframes orb-shine { 50% { filter: brightness(1.25) drop-shadow(0 0 10px rgba(255, 255, 255, .7)); } }

/* Timeline sits under the controls, deliberately quiet. */
.narrator-timeline { display: flex; margin-top: 14px; opacity: .5; }
.narrator-progress { width: clamp(120px, 14vw, 200px); height: 2px; border-radius: 2px; background: #2a2a2a; overflow: hidden; }
.narrator-progress span { display: block; height: 100%; background: var(--ink); transform: scaleX(0); transform-origin: left; }

/* A window two lines tall; longer lines slide up inside it as they are spoken (narrator.js). */
.narrator-caption {
  max-width: 100%;
  height: 2.8em;
  margin-top: 10px;
  overflow: hidden;
  font-size: clamp(1.125rem, 1.6vw, 1.5rem);
  line-height: 1.4;
  letter-spacing: -.015em;
}
.narrator-lines { position: relative; display: block; text-wrap: balance; transition: transform .45s cubic-bezier(.3, .7, .2, 1); }
.narrator-word { color: rgba(244, 244, 244, .3); transition: color .18s ease; }
.narrator-word.is-lit { color: var(--ink); }
.narrator-word.is-key.is-lit { color: var(--brain-accent, var(--ink)); }

.narrator-controls { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 16px; }
:where(.narrator button) { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
.narrator button:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.narrator svg { width: 18px; height: 18px; display: block; }
.narrator-control { width: 36px; height: 36px; display: grid; place-items: center; border: 1px solid #3a3a3a; border-radius: 50%; transition: border-color .2s ease, opacity .2s ease; }
.narrator-control:hover:not(:disabled) { border-color: var(--ink); }
.narrator-control:disabled { opacity: .3; cursor: default; }
.narrator[data-state="playing"] .icon-play, .narrator:not([data-state="playing"]) .icon-pause { display: none; }
.narrator .icon-restart, .narrator[data-state="finished"] .icon-next { display: none; }
.narrator[data-state="finished"] .icon-restart { display: block; }
.narrator[data-state="finished"] #narrator-next { color: #000; background: var(--ink); border-color: var(--ink); }
.narrator-sound {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 36px;
  margin-left: 6px;
  padding: 0 14px;
  font-size: .8125rem;
  border: 1px solid #3a3a3a;
  border-radius: 999px;
  white-space: nowrap;
}
.narrator-speed { min-width: 64px; min-height: 36px; padding: 0 14px; font-size: .8125rem; font-variant-numeric: tabular-nums; border: 1px solid #3a3a3a; border-radius: 999px; white-space: nowrap; transition: border-color .2s ease, background-color .2s ease, color .2s ease; }
.narrator-speed:hover { border-color: var(--ink); }
.narrator-speed[aria-pressed="true"] { color: #000; background: var(--ink); border-color: var(--ink); }
/* The speed label (1×, 1.25×, 1.5×) in Reddit Mono; "Skip" on the opening film keeps the general font. */
.narrator-speed[data-mode="speed"] { font-family: "Reddit Mono", ui-monospace, Menlo, monospace; }
.narrator[data-sound="off"] .narrator-sound { color: #000; background: var(--ink); border-color: var(--ink); }
.narrator[data-sound="off"] .sound-waves, .narrator[data-sound="on"] .sound-off { display: none; }

@media (prefers-reduced-motion: reduce) {
  .narrator, .narrator-word, .narrator-caption, .narrator-orb, .narrator-lines { transition: none !important; }
  .narrator[data-state="playing"] .narrator-orb::after, .narrator[data-state="playing"] .narrator-orb-core { animation: none; }
}
/* Lights up when an elastic pull is nearly complete, offering a click instead. */
#narrator-next.is-ready { color: #000; background: var(--ink); border-color: var(--ink); animation: next-ready .9s ease-in-out infinite alternate; }
@keyframes next-ready { to { box-shadow: 0 0 0 6px rgba(244, 244, 244, .15); } }
@media (prefers-reduced-motion: reduce) { #narrator-next.is-ready { animation: none; } }
