/*
 * chat/chat.css
 * Streaming-text animation + VFX support styles.
 * Scoped exclusively to .chat-page — zero bleed to other pages.
 * No changes to layout, existing bubble colours, or global CSS.
 */

/* ─────────────────────────────────────────────
   Canvas VFX layers — INSIDE video and chat panel
   Two separate canvases for better visual hierarchy.
───────────────────────────────────────────── */
.chat-page #chatVfxCanvasVideo,
.chat-page #chatVfxCanvasPanel {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
  opacity: 0.85;
  border-radius: inherit;
}

/* Video and panel need position:relative to contain the canvas */
.chat-page .video-portrait,
.chat-page .chat-panel {
  position: relative;
  overflow: hidden; /* clip canvas to rounded corners */
}

/* Chat messages sit above the canvas */
.chat-page .chat-m,
.chat-page .chat-h,
.chat-page .chat-i {
  position: relative;
  z-index: 1;
}

/* ─────────────────────────────────────────────
   Processing indicator
   Replaces the plain "…" typing bubble.
───────────────────────────────────────────── */
.chat-page .cp-typing-indicator {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: .6rem .9rem;
}
.chat-page .cp-typing-indicator span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #3d6bff;
  opacity: .3;
  /* travel + scale reads far better than opacity alone on a small dot */
  animation: cp-dot-pulse 1.05s cubic-bezier(.4, 0, .6, 1) infinite;
}
.chat-page .cp-typing-indicator span:nth-child(2) { animation-delay: .14s; }
.chat-page .cp-typing-indicator span:nth-child(3) { animation-delay: .28s; }

@keyframes cp-dot-pulse {
  0%, 100% {
    opacity: .3;
    transform: translateY(0) scale(1);
    box-shadow: 0 0 0 rgba(61, 107, 255, 0);
  }
  45% {
    opacity: 1;
    transform: translateY(-5px) scale(1.18);
    box-shadow: 0 0 12px rgba(61, 107, 255, .7);
  }
}

/* ─────────────────────────────────────────────
   Word-by-word reveal
   JS sets opacity: 0→1 and transform on each word span.
   Text stays fully selectable — inline spans, no tricks.
───────────────────────────────────────────── */
.chat-page .cp-word {
  display: inline;
  opacity: 0;
  transform: translateY(3px);
}
/* JS appends the span, then adds .is-in on the next frame so the
   transition actually runs. Without the frame gap the browser
   collapses both states into one paint and the reveal is invisible. */
.chat-page .cp-word.is-in {
  opacity: 1;
  transform: translateY(0);
  transition: opacity .16s ease-out, transform .16s ease-out;
}

/* ─────────────────────────────────────────────
   Streaming cursor — on the bot bubble while responding
───────────────────────────────────────────── */
.chat-page .bubble.bot.cp-streaming::after {
  content: '▋';
  color: var(--cyan, #3d6bff);
  animation: cp-cursor-blink .55s steps(1) infinite;
  margin-left: 2px;
  font-size: .82em;
  vertical-align: middle;
  opacity: .9;
}
@keyframes cp-cursor-blink {
  0%, 100% { opacity: .9; }
  50%       { opacity: 0;  }
}

/* ─────────────────────────────────────────────
   Sentence-complete pulse
   Brief border glow on the bot bubble when a sentence ends.
───────────────────────────────────────────── */
.chat-page .bubble.bot.cp-sentence-pulse {
  animation: cp-sentence-pulse .45s cubic-bezier(.22, 1, .36, 1) forwards;
}
@keyframes cp-sentence-pulse {
  0%   { box-shadow: 0 0  0px rgba(61,107,255,0);   border-color: rgba(61,107,255,.14); }
  40%  { box-shadow: 0 0 18px rgba(61,107,255,.38);  border-color: rgba(61,107,255,.55); }
  100% { box-shadow: 0 2px 12px rgba(0,0,0,.3);     border-color: rgba(61,107,255,.14); }
}

/* ─────────────────────────────────────────────
   Response-complete glow settle
   Soft fade-in of a cyan edge on the panel when streaming ends.
───────────────────────────────────────────── */
.chat-page .chat-panel.cp-settled {
  animation: cp-panel-settle .7s cubic-bezier(.22, 1, .36, 1) forwards;
}
@keyframes cp-panel-settle {
  0%   { box-shadow: 0 0 60px rgba(61,107,255,.32), inset 0 0 40px rgba(61,107,255,.08); }
  100% { box-shadow: 0 0 60px rgba(61,107,255,.10), inset 0 0 40px rgba(61,107,255,.04); }
}

/* ─────────────────────────────────────────────
   Dot indicator in header — active state while responding
───────────────────────────────────────────── */
.chat-page .chat-panel.cp-responding .dot {
  animation: cp-dot-active .5s ease-in-out infinite alternate;
}
@keyframes cp-dot-active {
  from { box-shadow: 0 0  6px var(--cyan, #3d6bff); transform: scale(1);   }
  to   { box-shadow: 0 0 16px var(--cyan, #3d6bff); transform: scale(1.35); }
}

/* ─────────────────────────────────────────────
   Respect prefers-reduced-motion:
   Kill all custom animations, keep text visible.
───────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .chat-page .cp-word {
    opacity: 1;
    transform: none;
    animation: none;
  }
  .chat-page .cp-typing-indicator span,
  .chat-page .bubble.bot.cp-streaming::after,
  .chat-page .bubble.bot.cp-sentence-pulse,
  .chat-page .chat-panel.cp-settled,
  .chat-page .chat-panel.cp-responding .dot {
    animation: none !important;
  }
  .chat-page #chatVfxCanvasVideo,
  .chat-page #chatVfxCanvasPanel {
    display: none;
  }
}

/* ─────────────────────────────────────────────
   WhatsApp reveal

   The chat page previously had no #waBlock at all, so the API's
   showWhatsApp flag had nothing to act on and the reveal silently
   never happened. This sits between the message list and the input,
   so it reads as part of the conversation rather than a banner.

   Uses [hidden] rather than inline display so the reveal can animate.
───────────────────────────────────────────── */
.chat-page .wa-block {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .75rem;
  padding: .7rem clamp(.8rem, 2vw, 1.2rem);
  border-top: 1px solid rgba(61, 107, 255, .15);
  background: rgba(37, 211, 102, .05);
  position: relative;
  z-index: 1;
  animation: cp-wa-in .4s cubic-bezier(.22, 1, .36, 1) both;
}
.chat-page .wa-block[hidden] { display: none; }

@keyframes cp-wa-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.chat-page .wa-cta {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .55rem 1rem;
  min-height: 42px;
  border-radius: 999px;
  background: #25d366;
  color: #05210f;
  font-weight: 700;
  font-size: .92rem;
  letter-spacing: .01em;
  text-decoration: none;
  box-shadow: 0 4px 18px rgba(37, 211, 102, .3);
  transition: transform .18s ease, box-shadow .18s ease;
}
.chat-page .wa-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 24px rgba(37, 211, 102, .42);
}

.chat-page .wa-alt {
  font-size: .84rem;
  color: #9fb0cc;
}
.chat-page .wa-alt a {
  color: #3d6bff;
  text-decoration: none;
}
.chat-page .wa-alt a:hover { text-decoration: underline; }

@media (max-width: 560px) {
  .chat-page .wa-block { gap: .45rem .6rem; }
  .chat-page .wa-alt   { font-size: .78rem; width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .chat-page .wa-block { animation: none; }
  .chat-page .wa-cta:hover { transform: none; }
}
