/* stt-ghost.css - the ONE dictation interim-preview skin for every mic.
   Extracted from chat/css/chat-ny-blod-bolge.css (ghost program #5891-#5932)
   and generalized: rules scope on .ss-stt-ghost-host, which shared/js/
   stt-ghost.js stamps on the composer box at ensure-time - so /chat/, the
   public anon shell and /skrivebord/ share one skin. Chat keeps two local
   crutches in its own css: the ID-specificity growth rule and the canonical
   reduced-motion stills (both must outrank chat-local !important pins). */

/* ── Live dictation preview (inline interim ghost) ────────────────────────────
   Display-only overlay positioned by chat-stt.js so the muted-italic spoken
   words continue the committed sentence INLINE (text-indent = measured end of
   text), never as a separate line below. While it is visible the composer
   placeholder is suppressed (.chat-stt-ghosting on the box). The overlay and
   its measuring mirror are absolute — they never participate in the composer
   grid/flex flow. */
.ss-stt-ghost-host.chat-stt-ghosting {
  position: relative;
}

.ss-stt-ghost-host .chat-stt-interim {
  display: none;
}

.ss-stt-ghost-host .chat-stt-interim--visible {
  display: block;
  position: absolute;
  font-style: italic;
  color: var(--warm-text-light, #8A7E72);
  pointer-events: none;
  user-select: none;
  white-space: pre-wrap;
  word-break: break-word;
  overflow: hidden;
  z-index: 1;
}

.ss-stt-ghost-host .chat-stt-interim-mirror {
  position: absolute;
  visibility: hidden;
  inset-inline-start: -9999px;
  top: 0;
  white-space: pre-wrap;
  word-break: break-word;
  pointer-events: none;
}

[data-theme="dark"] .ss-stt-ghost-host .chat-stt-interim--visible {
  color: #E8DDD4;
  opacity: 0.62;
}

/* While dictating, the ghost IS the composer text — the placeholder under it
   read as double text (Morten's staging verdict 15/7). */
.ss-stt-ghost-host.chat-stt-ghosting textarea::placeholder,
.ss-stt-ghost-host.chat-stt-ghosting input::placeholder {
  color: transparent !important;
}
.ss-stt-ghost-host.chat-stt-ghosting .ql-editor.ql-blank::before {
  content: none !important;
}

/* While dictating, the caret rides AHEAD at the end of the spoken words —
   a blinking mark on the ghost's tail; the real caret is
   parked (transparent) so two cursors never show and the text never appears
   to land "behind" the caret. */
.ss-stt-ghost-host.chat-stt-ghosting textarea,
.ss-stt-ghost-host.chat-stt-ghosting input[type="text"],
.ss-stt-ghost-host.chat-stt-ghosting .chat-input-field,
.ss-stt-ghost-host.chat-stt-ghosting .ql-editor {
  caret-color: transparent;
}

.ss-stt-ghost-host .chat-stt-interim--visible::after {
  content: '';
  display: inline-block;
  width: 1px;
  height: 1em;
  margin-inline-start: 1px;
  vertical-align: -0.15em;
  background: var(--warm-text-light, #8A7E72);
  animation: chat-stt-caret-blink 1.06s steps(2, start) infinite;
}

[data-theme="dark"] .ss-stt-ghost-host .chat-stt-interim--visible::after {
  background: #E8DDD4;
}

@keyframes chat-stt-caret-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* Ghost overhang growth: the composer css pins editor min-heights with
   !important, so the ghost's growth wins the same cascade via a scoped class
   + variable. Applies only while chat-stt.js marks the editor. */
.ss-stt-ghost-host.chat-stt-ghosting #chat-direct-input .ql-editor.chat-stt-grown,
.ss-stt-ghost-host.chat-stt-ghosting textarea.chat-stt-grown {
  min-height: var(--stt-ghost-minh, 24px) !important;
}

/* Variant B+shimmer (Morten 15/7, for ordblinde brugere): de u-faerdige ord er
   en bloed graa form med et levende lys-sweep - man ser AT der arbejdes, ikke
   hvilke ord. Gradient-clip + blur ligger SAMLET paa ORD-spans: et span med
   filter forlader foraelderens background-clip (ordene blev usynlige da
   clippet laa paa elementet - fanget af screenshot-proben), og elementet
   holdes rent saa caret-maerket (::after, egen baggrund) forbliver skarpt. */
.ss-stt-ghost-host .chat-stt-interim--visible .w {
  color: transparent;
  background-image: linear-gradient(100deg,
    var(--warm-text-light, #8A7E72) 0%,
    var(--warm-text-light, #8A7E72) 38%,
    #D6CCC0 50%,
    var(--warm-text-light, #8A7E72) 62%,
    var(--warm-text-light, #8A7E72) 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  filter: blur(2.75px);
  opacity: 0.8;
  animation: chat-stt-shimmer 2s linear infinite;
}

[data-theme="dark"] .ss-stt-ghost-host .chat-stt-interim--visible .w {
  background-image: linear-gradient(100deg,
    #9F9184 0%, #9F9184 38%, #F2EAE1 50%, #9F9184 62%, #9F9184 100%);
}

@keyframes chat-stt-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -20% 0; }
}

.ss-stt-ghost-host .chat-stt-interim--visible .w.newest {
  animation: chat-stt-word-settle 420ms ease-out,
    chat-stt-shimmer 2s linear infinite;
}

@keyframes chat-stt-word-settle {
  from { filter: blur(5px); opacity: 0.3; }
  to { filter: blur(2.75px); opacity: 0.8; }
}


/* Growth (generic): consumer pages without !important min-height pins only
   need class-level specificity. Chat's ID-level twin lives in its own css. */
.ss-stt-ghost-host.chat-stt-ghosting .chat-stt-grown {
  min-height: var(--stt-ghost-minh, 24px) !important;
}

/* Reduced motion (generic twin of chat's canonical-block stills). */
@media (prefers-reduced-motion: reduce) {
  .ss-stt-ghost-host .chat-stt-interim--visible::after,
  .ss-stt-ghost-host .chat-stt-interim--visible .w,
  .ss-stt-ghost-host .chat-stt-interim--visible .w.newest {
    animation: none !important;
  }
}
