/*
 * VIDIZMO blog read-aloud player.
 *
 * Shaped to match HubSpot's own narration player, measured from a live post:
 * full body width, 60px tall, 30px radius, a 40px round control on the left,
 * Roboto 16/24, and 20px of space beneath. The two sit above the post body and
 * have to read as the same piece of furniture.
 *
 * What is deliberately not matched is the colour. HubSpot's player is its default
 * blue-grey; this one uses the brand orange on a warm neutral, so that while both
 * are on the page it is obvious which one you are listening to.
 *
 * Tokens are scoped to the module so it drops into any template without leaking
 * variables, and it reads correctly on light and dark grounds.
 */
.vz-ra {
  --vz-ra-accent: #F26125;
  --vz-ra-accent-ink: #FFFFFF;
  --vz-ra-ink: #33475B;
  --vz-ra-muted: #565656;
  --vz-ra-line: #E3DDD9;
  --vz-ra-surface: #FAF6F3;
  --vz-ra-fill: rgba(242, 97, 37, 0.10);
  --vz-ra-chip: rgba(51, 71, 91, 0.07);
  --vz-ra-chip-hover: rgba(51, 71, 91, 0.14);

  position: relative;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  min-height: 60px;
  margin: 0 0 20px;
  /* More room on the right than the left: the play control is itself a pill and
     sits happily near the curve, while the controls at the other end would
     otherwise crowd it, which is what the expanded voice list exposed. */
  padding: 0 20px 0 10px;
  border-radius: 30px;
  background: var(--vz-ra-surface);
  font-family: Roboto, Arial, Calibri, sans-serif;
  font-size: 16px;
  line-height: 24px;
  color: var(--vz-ra-ink);
}

/*
 * No prefers-color-scheme block on purpose. vidizmo.ai renders light for every
 * visitor, so a module that follows the operating system instead of the site puts
 * a dark pill on a white page for anyone whose phone or laptop is set to dark.
 * If the theme ever gains a dark mode, this should key off whatever flag the
 * theme sets, not off the OS.
 */

/* Progress fills the pill from the left, behind everything else. */
.vz-ra__track {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  background: transparent;
  pointer-events: none;
}

.vz-ra__bar {
  display: block;
  width: 0;
  height: 100%;
  background: var(--vz-ra-fill);
  transition: width 240ms linear;
}

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

.vz-ra__head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  flex-wrap: wrap;
  gap: 8px 12px;
  min-height: 60px;
}

/* The round control, sized to HubSpot's 40px, filled so it reads as a button. */
.vz-ra__play {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: 40px;
  padding: 0 18px 0 15px;
  border: 0;
  border-radius: 20px;
  background: var(--vz-ra-accent);
  color: var(--vz-ra-accent-ink);
  font: 500 15px/1 Roboto, Arial, Calibri, sans-serif;
  cursor: pointer;
}

.vz-ra__play:hover { background: #D9531B; }
.vz-ra__play:focus-visible { outline: 2px solid var(--vz-ra-ink); outline-offset: 2px; }
.vz-ra__play[disabled] { background: var(--vz-ra-muted); cursor: not-allowed; }

.vz-ra__icon {
  width: 14px;
  height: 14px;
  fill: currentColor;
}

/* Shown only once a voice keeps us waiting past a beat. */
.vz-ra__spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  border-top-color: var(--vz-ra-accent-ink);
  border-radius: 50%;
  animation: vz-ra-spin 700ms linear infinite;
}

@keyframes vz-ra-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .vz-ra__spinner { animation-duration: 2s; }
}

/* Sits where HubSpot puts the duration: right-hand end, 15px of air. */
.vz-ra__meta {
  margin-left: auto;
  margin-right: 15px;
  font-size: 15px;
  color: var(--vz-ra-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.vz-ra__controls {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 0 0 2px;
}

.vz-ra__ghost {
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--vz-ra-line);
  border-radius: 16px;
  background: transparent;
  color: var(--vz-ra-muted);
  font: 400 13px/1 Roboto, Arial, Calibri, sans-serif;
  cursor: pointer;
}

.vz-ra__ghost:hover { color: var(--vz-ra-ink); border-color: var(--vz-ra-muted); }

/*
 * Speed: the current rate on its own, chevrons only once it is clicked. The
 * outline appears with them, so collapsed it is plain text in the bar exactly as
 * HubSpot's is, and it costs no width until someone wants it.
 */
.vz-ra__ratewrap {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  height: 32px;
  padding: 0 2px;
  border: 1px solid transparent;
  border-radius: 16px;
  transition: border-color 120ms linear;
}

.vz-ra__ratewrap[data-open="true"] {
  padding: 0 4px;
  border-color: var(--vz-ra-line);
}

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

/*
 * Both controls carry a faint pill at rest. Plain text in a bar reads as a label,
 * not a button: nobody clicks a word that looks like a caption, which is exactly
 * what happened with "Voice".
 */
.vz-ra__rate {
  min-width: 38px;
  height: 30px;
  padding: 0 8px;
  border: 0;
  border-radius: 15px;
  background: var(--vz-ra-chip);
  color: var(--vz-ra-ink);
  font: 500 14px/1 Roboto, Arial, Calibri, sans-serif;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 120ms linear;
}

.vz-ra__rate:hover { background: var(--vz-ra-chip-hover); }

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

.vz-ra__chev {
  width: 22px;
  height: 30px;
  border: 0;
  border-radius: 15px;
  background: transparent;
  color: var(--vz-ra-muted);
  font: 400 19px/1 Roboto, Arial, Calibri, sans-serif;
  cursor: pointer;
}

.vz-ra__chev:hover:not([disabled]) { color: var(--vz-ra-ink); }
.vz-ra__chev[disabled] { opacity: 0.3; cursor: default; }

.vz-ra__rate:focus-visible,
.vz-ra__chev:focus-visible {
  outline: 2px solid var(--vz-ra-accent);
  outline-offset: 1px;
}

/* Voice: the word alone, the list only once it is asked for. */
.vz-ra__voicewrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 2px;
  border: 1px solid transparent;
  border-radius: 16px;
  transition: border-color 120ms linear;
}

/*
 * No border when open. The select brings its own, and nesting one inside another
 * put two rounded outlines a few pixels apart with dead space between them.
 */
.vz-ra__voicewrap[data-open="true"] {
  padding: 0 2px;
  border-color: transparent;
}

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

.vz-ra__voicebtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 10px;
  border: 0;
  border-radius: 15px;
  background: var(--vz-ra-chip);
  color: var(--vz-ra-ink);
  font: 500 14px/1 Roboto, Arial, Calibri, sans-serif;
  cursor: pointer;
  transition: background-color 120ms linear;
}

.vz-ra__voicebtn:hover { background: var(--vz-ra-chip-hover); }

/*
 * The caret is drawn with borders, not a character. U+25BE renders as a stray
 * dash in Roboto on some platforms, which looked like a typo rather than a
 * control. A border triangle is identical everywhere.
 */
.vz-ra__voicebtn::after {
  content: "";
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.6;
}

.vz-ra__voicewrap[data-open="true"] .vz-ra__voicebtn::after {
  border-top: 0;
  border-bottom: 5px solid currentColor;
}

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

.vz-ra__voicebtn:focus-visible {
  outline: 2px solid var(--vz-ra-accent);
  outline-offset: 1px;
}

.vz-ra__select {
  height: 30px;
  max-width: 170px;
  padding: 0 6px 0 10px;
  border: 1px solid var(--vz-ra-line);
  border-radius: 15px;
  background: var(--vz-ra-chip);
  color: var(--vz-ra-ink);
  font: 400 13px/1 Roboto, Arial, Calibri, sans-serif;
}

.vz-ra__select:hover { border-color: var(--vz-ra-muted); }

/*
 * The native player shows no status line, so this one does not either. It stays
 * in the accessibility tree, where a screen reader still announces the state.
 */
.vz-ra__status {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Narrow screens: let the pill grow rather than crushing the controls. */
@media (max-width: 640px) {
  .vz-ra {
    padding: 10px 12px;
    border-radius: 22px;
  }
  .vz-ra__head { min-height: 40px; }
  .vz-ra__meta { margin-right: 4px; }
  .vz-ra__select { max-width: 130px; }
}

/* Sentence-level highlight where the Custom Highlight API exists. */
::highlight(vz-readaloud) {
  background-color: rgba(242, 97, 37, 0.18);
  color: inherit;
}

/* Block-level fallback, and the anchor for the follow-along scroll. */
.vz-ra-speaking {
  background-image: linear-gradient(rgba(242, 97, 37, 0.08), rgba(242, 97, 37, 0.08));
  box-shadow: -12px 0 0 rgba(242, 97, 37, 0.08);
}

@supports selector(::highlight(vz-readaloud)) {
  .vz-ra-speaking { background-image: none; }
}
