/* ============================================================
   Kit — chat.css   (reusable parts: the conversation + input)
   The back-and-forth between the user and the agent:
     .bp-msg / .bp-msg--user   a message row (avatar + content)
     .bp-bubble                the bot output bubble (squared
                               top-left, toward the avatar)
     .bp-thinking              a bubble with a bulb + animated dots
     .bp-hint                  a "Hint:" line under a message
     .bp-chatbar               the compact input (mic + send)
     .bp-suggests/.bp-suggest  quick suggestion chips
   Bot bubbles are neutral grey; the user bubble + send pick up
   the accent. Behaviour (type -> reply) is in chat.js.
   ============================================================ */

.bp-chat { display: flex; flex-direction: column; gap: 16px; }

/* ---------- a message row ---------- */
.bp-msg { display: flex; gap: 12px; align-items: flex-start; }
.bp-msg__avatar {
  flex: none; width: 38px; height: 38px;
  border-radius: 50%; object-fit: cover; background: var(--bp-surface);
}

/* ---------- figure avatar (the head pokes out of the circle) ----------
   The illustration is masked by its circle at the bottom, but its hair / the top
   of the head pokes out the top. The SVG carries the circle + the figure (sized
   so the circle is the full width and the hair sits above it); this wrapper just
   sets the circle size and lets the top overflow. Drop it in where a plain round
   <img> avatar would go — same footprint, minus the CSS clip. */
.bp-fig-avatar { position: relative; flex: none; width: 38px; height: 38px; overflow: visible; }
.bp-fig-avatar img { position: absolute; left: 0; bottom: 0; width: 100%; height: auto; display: block; }
.bp-msg__content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.bp-msg__head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 12px; line-height: 18px;          /* name + role read at the timestamp's size */
}
.bp-msg__who { display: flex; align-items: center; gap: 4px; min-width: 0; }
.bp-msg__name { font-weight: 600; color: #3f3f46; }
.bp-msg__role { font-weight: 400; color: #a0a0ab; }
.bp-msg__time { flex: none; font-size: 12px; font-weight: 400; color: #a0a0ab; }

/* ---------- the bot bubble ---------- */
.bp-bubble {
  align-self: stretch;                  /* runs full width, so its right edge lines up with
                                           the timestamp above and any answer widget below */
  max-width: 100%;
  background: var(--bp-bubble-bg);
  border: 1px solid var(--bp-bubble-border);
  border-radius: var(--bp-radius-btn); corner-shape: squircle;   /* same radius as the buttons */
  border-top-left-radius: 0;            /* sharp tail toward the avatar */
  padding: 8px 12px;
  font-size: 15px; line-height: 23px; font-weight: 400;
  color: var(--bp-surface-foreground);
}
.bp-bubble p { margin: 0; }
.bp-bubble p + p { margin-top: 14px; }

/* ---------- the user message ----------
   Avatar on the right; the name row keeps its natural order (name left, time
   right) and the bubble runs full width, like the bot's — the speakers read by
   which side the avatar + tail sit on, not by a chat-app right-alignment. */
.bp-msg--user { flex-direction: row-reverse; }
.bp-bubble--user {
  align-self: stretch;
  background: transparent;
  border-color: var(--bp-bubble-border);
  border-radius: var(--bp-radius-btn); corner-shape: squircle;
  border-top-right-radius: 0;          /* sharp tail toward the right-side avatar */
  color: var(--bp-surface-foreground);
}
/* an unknown user: a light-gray circle with a slightly darker ring, holding
   initials (e.g. "ME") when there's no photo. A <span>, no src. */
.bp-msg__avatar--empty {
  box-sizing: border-box;          /* the 1px ring stays inside the avatar's size, so it matches the photo avatars exactly */
  background: var(--bp-gray-100, #f0efed);
  border: 1px solid var(--bp-gray-300, #d6d4d1);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
  color: var(--bp-surface-muted);
}

/* ---------- thinking ---------- */
.bp-thinking {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--bp-bubble-bg);
  border: 1px solid var(--bp-bubble-border);
  border-radius: var(--bp-radius-btn); corner-shape: squircle;
  border-top-left-radius: 0;
  padding: 8px 12px;
  font-size: 15px; color: var(--bp-surface-foreground);
}
/* the bulb is a Lottie (doodle-motif-296-bulb): reveals in, cycles twice,
   then reverses out as the bubble morphs into the answer. mounted by the
   slice via BPMotif. No more three-dots. */
.bp-thinking__bulb { width: 26px; height: 26px; flex: none; color: var(--bp-accent); display: block; }
/* the Lottie bulb's own parts: dark-grey outline, light-grey fill */
.bp-thinking__bulb .primary   { stroke: #525252; }
.bp-thinking__bulb .secondary { fill: #cccccc; stroke: #cccccc; }

/* thinking as a bubble VARIANT (same bubble later expands into the reply, via
   BPConvo.thinkSay) + the dots fallback when the Lottie bulb is unavailable */
.bp-bubble--thinking { align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; }
.bp-thinklbl { color: var(--bp-surface-foreground); }
.bp-dots { display: inline-flex; align-items: center; gap: 4px; color: var(--bp-accent); }
.bp-dots i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .35; }
@media (prefers-reduced-motion: no-preference) {
  .bp-dots i { animation: bp-dots 1s ease-in-out infinite; }
  .bp-dots i:nth-child(2) { animation-delay: .16s; } .bp-dots i:nth-child(3) { animation-delay: .32s; }
}
@keyframes bp-dots { 0%,100% { opacity: .3; } 50% { opacity: 1; } }
/* inline answer options attached under an agent bubble */
.bp-answer { margin-top: 0; }
.bp-answer.is-done { pointer-events: none; }   /* once answered, the widget is a static record */

/* ---------- elapsed / "thought for" divider ----------
   Sits between a user turn and the agent's considered reply, showing how long
   the agent took: a centred, quiet label with a hairline running out each side. */
.bp-chat__elapsed {
  display: flex; align-items: center; gap: 12px;
  margin: 2px 0;
  font-size: 12px; line-height: 18px; color: var(--bp-surface-muted);
  white-space: nowrap;
}
.bp-chat__elapsed::before,
.bp-chat__elapsed::after {
  content: ""; flex: 1; height: 1px; background: var(--bp-border);
}

/* ---- sequenced-build variant (BPConvo.thinkSay) ----
   Instead of the whole divider hard-cutting in, it assembles in two beats: the
   hairline draws out from the centre first, then the label pops in. Uses explicit
   line spans (the base ::before/::after hairlines are dropped here) so each part
   carries its own delay. The row's height also eases in (set inline) to push the
   reply below it down; the chat's follow-scroll keeps the newest turn in view. */
.bp-elapsed::before, .bp-elapsed::after { display: none; }
.bp-elapsed__line { flex: 1 1 auto; height: 1px; background: var(--bp-border); transform-origin: center; }
.bp-elapsed__txt  { flex: none; }
/* the row first opens its gap (height eased in) with its parts HIDDEN; only once the gap is
   open does .is-build get added, so the hairline-draw then label-pop play fully in view
   instead of being clipped inside a 0-height row (which read as a hard cut) */
.bp-elapsed:not(.is-build) .bp-elapsed__line,
.bp-elapsed:not(.is-build) .bp-elapsed__txt { opacity: 0; }
.bp-elapsed.is-build .bp-elapsed__line { animation: bp-elapsed-line .4s var(--bp-ease-emphasized, cubic-bezier(.22,1,.36,1)) both; }
.bp-elapsed.is-build .bp-elapsed__txt  { animation: bp-elapsed-txt .34s var(--bp-ease-back, cubic-bezier(.68,-0.6,.32,1.6)) .22s both; }
@keyframes bp-elapsed-line { from { transform: scaleX(0); opacity: 0; } to { transform: scaleX(1); opacity: 1; } }
@keyframes bp-elapsed-txt  { from { opacity: 0; transform: translateY(3px) scale(.92); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .bp-elapsed.is-build .bp-elapsed__line, .bp-elapsed.is-build .bp-elapsed__txt { animation: none; }
}

/* ---------- hint ---------- */
.bp-hint {
  padding: 0 4px;
  font-size: 12px; line-height: 18px; color: #9a9aa0;   /* lighter than the body */
}
.bp-hint b { font-weight: 600; }

/* ---------- the compact chat input ---------- */
.bp-chatbar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 8px 8px 14px;
  background: var(--bp-surface);
  border: 1px solid var(--bp-border-strong);
  border-radius: var(--bp-radius);
}
.bp-chatbar:focus-within { border-color: var(--bp-accent); }
.bp-chatbar__input {
  flex: 1; min-width: 0; border: none; outline: none; background: transparent;
  font: inherit; font-size: 14px; color: var(--bp-surface-foreground);
}
.bp-chatbar__input::placeholder { color: var(--bp-surface-muted); }
.bp-chatbar__btn {
  flex: none; width: 36px; height: 36px;
  display: grid; place-items: center;
  border: none; border-radius: var(--bp-radius-sm);
  background: transparent; color: var(--bp-surface-muted); cursor: pointer;
}
.bp-chatbar__btn:hover { background: rgba(17,24,39,.05); }
.bp-chatbar__btn--send {
  background: var(--bp-accent-tint); color: var(--bp-accent);
  border: 1px solid color-mix(in srgb, var(--bp-accent) 30%, white);
}
.bp-chatbar__btn svg { width: 18px; height: 18px; }

/* ---------- composer: the chat input row ----------
   The reply/follow-up bar: the standard input FIELD on the left, with the send
   button OUTSIDE it on the right (vs .bp-chatbar, which nests the send inside one
   box). Built from the DS field + a light reveal-label send button, so it inherits
   the field's border/focus and the button's states/motion:
     <div class="bp-composer">
       <div class="bp-field"><div class="bp-field__control">
         <input class="bp-field__input" placeholder="Follow up…"></div></div>
       <button class="bp-btn bp-btn--secondary bp-btn--reveal-label" aria-label="Send">
         <span class="bp-btn__label">Send</span>
         <span class="bp-btn__icon bp-btn__icon--fly"><svg …paper-plane…></svg></span>
       </button>
     </div>
   The send is icon-only at rest and grows a "Send" label (the plane flies) on hover. */
.bp-composer { display: flex; align-items: center; gap: 8px; }
.bp-composer > .bp-field { flex: 1 1 auto; min-width: 0; }

/* ---------- suggestion chips ---------- */
.bp-suggests { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.bp-suggest {
  height: 36px; padding: 0 14px;
  display: inline-flex; align-items: center;
  border: 1px solid var(--bp-border-strong);
  border-radius: var(--bp-radius);
  background: var(--bp-surface);
  font: inherit; font-size: 13px; font-weight: 600;
  color: var(--bp-surface-foreground); cursor: pointer;
}
.bp-suggest:hover { background: color-mix(in srgb, #101010 4%, var(--bp-surface)); }   /* neutral hover (rule 4) */

/* ---------- build-out entrances ----------
   Conversation parts don't just appear — each atomic part builds out with one
   quick, snappy move: a scale-up from 70% + fade on an ease-in-out-back curve,
   so it anticipates on the way in and overshoots slightly on the way out (a
   little bounce at both ends). The parts of a message enter one after another
   as an overlapping wave — avatar → name/role → time → bubble → the content
   inside the bubble — and the next block continues the same wave. The instance
   staggers them by writing a per-element animation-delay (the `both` fill keeps
   each part hidden at its start frame until its turn). Bubbles grow from their
   tail corner (origin set inline per row side); other parts from top-left. */
@keyframes bp-build-in {
  0%   { opacity: 0; transform: scale(.7); }
  100% { opacity: 1; transform: scale(1); }
}
.bp-anim-in {
  animation: bp-build-in var(--bp-dur-snap, .3s) var(--bp-ease-back, cubic-bezier(.68,-0.6,.32,1.6)) both;
  transform-origin: top left;
}
@media (prefers-reduced-motion: reduce) {
  .bp-anim-in { animation: none; }
}

/* ---------- rise-in (for parts that shouldn't scale) ----------
   Some parts read wrong when scaled from 70% — full-width rows like answer
   options, CTAs, cards. They enter by sliding up from just below + fading, on
   the same ease-in-out-back curve, so they still carry the little anticipate/
   overshoot bounce without the zoom. Staggered by the instance like .bp-anim-in. */
@keyframes bp-rise-in {
  0%   { opacity: 0; transform: translateY(14px); }
  100% { opacity: 1; transform: translateY(0); }
}
.bp-anim-rise {
  /* `backwards` (not `both`): hide at the 0% frame during the stagger delay, but DON'T hold
     the 100% frame afterward — revert to the element's own styles so a rule like
     `.bp-btn:disabled { opacity:.45 }` still wins once the rise finishes. */
  animation: bp-rise-in var(--bp-dur-snap, .3s) var(--bp-ease-back, cubic-bezier(.68,-0.6,.32,1.6)) backwards;
}
@media (prefers-reduced-motion: reduce) {
  .bp-anim-rise { animation: none; }
}

/* ---------- line-by-line text reveal ----------
   Bubble copy isn't scaled in as one block — each wrapped line rises up from the
   bottom of its own clip, one after another. `.bp-line` is the clip; `.bp-line__in`
   is the text that slides (nowrap, so a pre-measured line never re-wraps while its
   bubble is mid-expand — the clip hides the overflow until the width catches up).
   A clean ease-out (not the back-bounce) keeps the text crisp and readable. The
   instance stages each line with a per-line animation-delay, continuing the wave. */
.bp-line { display: block; overflow: hidden; }
.bp-line__in { display: block; white-space: nowrap; }
.bp-anim-line {
  animation: bp-line-rise var(--bp-dur-snap, .3s) var(--bp-ease-emphasized, cubic-bezier(.22,1,.36,1)) both;
}
@keyframes bp-line-rise {
  0%   { opacity: 0; transform: translateY(100%); }
  100% { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .bp-anim-line { animation: none; } }
