/* ==========================================================================
   The assistant panel.
   ----------------------------------------------------------------------------
   This is deliberately styled as the PRODUCT, not as a section of the website.
   It is the same widget Demetris installs on a client's site: white body,
   brand-coloured header bar, circular business avatar, grey bot bubbles on the
   left, quick replies stacked on the right, a persistent input bar and a
   "Powered by" line at the bottom.

   That is the whole argument. A prospect looking at the hero is not looking at
   a graphic of a chatbot, they are looking at exactly what would appear on
   their own website, in their own colours.

   So: do NOT restyle this to match the dark page. It is meant to sit on top of
   the page as a separate object, the way it would on a client's site.
   ========================================================================== */

.assistant {
  width: 100%;
  max-width: 500px;
  background: #FFFFFF;
  border-radius: 18px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 30px 70px -25px rgba(2,10,24,.7), 0 0 0 1px rgba(255,255,255,.08);
  color: #1A1D23;
}

/* ---------- header bar ---------- */
.as-head {
  display: flex; align-items: center; gap: 13px;
  padding: 16px 18px;
  background: linear-gradient(120deg, var(--accent) 0%, #0B63D6 100%);
  flex: none;
}
.as-avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  font-family: var(--font-display); font-weight: 700; font-size: 15px;
  color: var(--accent); letter-spacing: -.02em;
}
.as-avatar img { width: 84%; height: auto; display: block; }
.as-id { flex: 1; min-width: 0; }
/* name only, the way the product does it. A status line under it was the last
   thing left over from the old website-panel look and it read as clutter. */
.as-id .an {
  font-family: var(--font-display); font-size: 18px; font-weight: 600;
  color: #fff; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.as-restart, .as-close {
  flex: none; background: none; border: none; cursor: pointer;
  color: rgba(255,255,255,.85);
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  transition: background .2s var(--ease-out), color .2s var(--ease-out);
}
.as-restart { width: 32px; height: 32px; font-size: 17px; letter-spacing: 1px; }
.as-close   { width: 32px; height: 32px; font-size: 21px; line-height: 1; }
.as-restart:hover, .as-close:hover { background: rgba(255,255,255,.18); color: #fff; }

/* ---------- conversation ---------- */
.as-body {
  flex: 1;
  min-height: 330px;
  max-height: 440px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 22px 18px 6px;
  display: flex; flex-direction: column; gap: 12px;
  background: #fff;
  scrollbar-width: thin;
  scrollbar-color: #D6D9DE transparent;
}
.as-body::-webkit-scrollbar { width: 6px; }
.as-body::-webkit-scrollbar-thumb { background: #D6D9DE; border-radius: 3px; }

.as-msg {
  max-width: 86%;
  padding: 14px 19px;
  font-size: 15.5px; line-height: 1.5;
  border-radius: 22px;
  animation: asin .38s var(--ease-out) both;
}
@keyframes asin { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .as-msg { animation: none; } }

.as-msg.bot  { align-self: flex-start; background: #F0F1F4; color: #1A1D23; border-bottom-left-radius: 7px; }
.as-msg.user { align-self: flex-end; background: var(--accent); color: #fff; border-bottom-right-radius: 7px; }
.as-msg strong { font-weight: 600; }
.as-msg.bot strong { color: #0B1B2E; }

.as-msg.system, .as-msg.guide {
  align-self: stretch; max-width: 100%;
  background: var(--accent-tint);
  border: 1px solid #CFE3FC;
  border-radius: 14px;
  color: #33445C; font-size: 14.5px;
}
.as-msg.system b, .as-msg.guide b { color: var(--accent-deep); font-weight: 600; }
.as-msg.guide .gl {
  display: block; margin-bottom: 7px;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--accent-deep);
}

.as-typing {
  align-self: flex-start; display: flex; gap: 5px; padding: 16px 19px;
  background: #F0F1F4; border-radius: 22px; border-bottom-left-radius: 7px;
}
.as-typing i { width: 7px; height: 7px; border-radius: 50%; background: #A8AEB8; animation: asbounce 1.25s var(--ease-out) infinite; }
.as-typing i:nth-child(2) { animation-delay: .16s; }
.as-typing i:nth-child(3) { animation-delay: .32s; }
@keyframes asbounce { 0%,60%,100% { transform: translateY(0); opacity: .45; } 30% { transform: translateY(-5px); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .as-typing i { animation: none; opacity: .7; } }

/* ---------- quick replies: stacked on the right, the way the product does ---------- */
.as-foot { flex: none; background: #fff; padding: 6px 18px 14px; }
.as-chips { display: flex; flex-direction: column; align-items: flex-end; gap: 9px; margin-bottom: 12px; }
.as-chip {
  font: inherit;
  font-family: var(--font-display); font-size: 15px; font-weight: 500;
  padding: 13px 22px;
  border-radius: 40px;
  border: 1px solid #D9DCE1;
  background: #fff;
  color: #1A1D23;
  cursor: pointer;
  text-align: center;
  max-width: 100%;
  transition: border-color .2s var(--ease-out), background .2s var(--ease-out),
              color .2s var(--ease-out), transform .2s var(--ease-out);
  animation: asin .32s var(--ease-out) both;
}
.as-chip:hover { border-color: var(--accent); color: var(--accent-deep); background: var(--accent-tint); transform: translateY(-1px); }
.as-chip.go { background: var(--accent); border-color: var(--accent); color: #fff; }
.as-chip.go:hover { background: #0B63D6; color: #fff; }

/* ---------- the input bar, always present ---------- */
.as-form {
  display: flex; align-items: center; gap: 10px;
  border: 1.5px solid #14171C;
  border-radius: 40px;
  padding: 6px 6px 6px 18px;
  background: #fff;
}
.as-form .clip, .as-form .mic {
  flex: none; width: 24px; height: 24px; color: #6B7280;
  display: inline-flex; align-items: center; justify-content: center;
}
.as-form input {
  flex: 1; min-width: 0;
  font: inherit; font-size: 15.5px;
  border: none; background: none; color: #1A1D23; padding: 8px 0;
}
.as-form input::placeholder { color: #9AA1AC; }
.as-form input:focus { outline: none; }
.as-form button.send {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  border: none; cursor: pointer;
  background: var(--accent); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .2s var(--ease-out), transform .2s var(--ease-out);
}
.as-form button.send:hover { background: #0B63D6; transform: translateY(-1px); }

.as-note { display: none; }
.as-powered {
  text-align: center; padding: 11px 10px 13px;
  font-family: var(--font-display); font-size: 12.5px; font-weight: 600;
  color: #9AA1AC; background: #fff;
  border-top: 1px solid #F0F1F4;
}

@media (max-width: 900px) { .assistant { max-width: 100%; } .as-body { min-height: 290px; } }
/* ==========================================================================
   THE TRAVELLING ASSISTANT
   --------------------------------------------------------------------------
   Leaving the hero, the panel does not disappear and get replaced by a chat
   icon in the corner. It physically collapses into an orb: a ghost element is
   flown from the panel's exact rect to the orb's exact rect with the Web
   Animations API, so the reader watches the same object shrink and travel.

   While scrolling, the orb tracks the pointer (a few pixels of lean, never a
   cursor replacement, which would break clicking and pointer accessibility)
   and carries a pill naming the section it is passing. When scrolling stops,
   it unfolds from the corner it occupies, so the panel visibly grows out of
   the orb rather than appearing over it.

   All of it is motion only. Every state is reachable and legible with
   prefers-reduced-motion on, where the morph becomes a cross fade.
   ========================================================================== */

.as-dock {
  position: fixed;
  right: 26px; top: 0;
  z-index: 950;
  display: flex; flex-direction: column; align-items: flex-end; gap: 13px;
  pointer-events: none;
  /* --dy is written on every scroll event. The transition IS the lag: the orb
     trails the page for a beat and catches up, which is what makes it read as
     carried along rather than pinned. */
  transform: translate3d(0, var(--dy, 0px), 0);
  transition: transform .42s cubic-bezier(.22,.9,.3,1);
}
.as-dock > * { pointer-events: auto; }
/* open: anchor to the bottom instead of riding, so a tall panel cannot hang off
   the viewport. The ghost morph carries the travel, so nothing is lost. */
body[data-as-state="open"] .as-dock { top: auto; bottom: 26px; transform: none; }

/* ---------- the orb ---------- */
.as-orb {
  position: relative;
  width: 64px; height: 64px;
  border: none; border-radius: 50%;
  padding: 0;
  background: linear-gradient(135deg, var(--cyan) 0%, var(--accent) 52%, #1E63E8 100%);
  box-shadow: 0 18px 38px -12px rgba(2,54,120,.75), 0 0 0 1px rgba(92,211,253,.34);
  cursor: pointer;
  display: none;
  align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700; font-size: 19px;
  color: #06182E; letter-spacing: -.02em;
  /* the magnetic lean and the scroll squash both ride these two properties,
     so nothing else has to touch transform and fight them */
  --ox: 0px; --oy: 0px; --oscale: 1;
  transform: translate3d(var(--ox), var(--oy), 0) scale(var(--oscale));
  transition: box-shadow .3s var(--ease-out);
  will-change: transform;
}
body[data-as-state="orb"] .as-orb { display: flex; }
body[data-as-state="away"] .as-dock { display: none; }
.as-orb:hover { box-shadow: 0 22px 46px -12px rgba(2,54,120,.85), 0 0 0 1px rgba(92,211,253,.6); }

/* the slow ring, so it reads as listening rather than as a static badge */
.as-orb::before {
  content: ""; position: absolute; inset: -7px;
  border-radius: 50%;
  border: 1px solid rgba(92,211,253,.5);
  opacity: 0;
  animation: asRing 3.4s var(--ease-out) infinite;
}
@keyframes asRing {
  0%   { opacity: .85; transform: scale(.9); }
  70%  { opacity: 0;   transform: scale(1.26); }
  100% { opacity: 0;   transform: scale(1.26); }
}
.as-ring {
  position: absolute; inset: -8px;
  width: calc(100% + 16px); height: calc(100% + 16px);
  transform: rotate(-90deg);
  pointer-events: none;
}
.as-ring circle { fill: none; stroke-width: 2; stroke-linecap: round; }
.as-ring .trk { stroke: rgba(255,255,255,.14); }
.as-ring .bar {
  stroke: var(--glow);
  transition: stroke-dashoffset .28s var(--ease-out);
  filter: drop-shadow(0 0 5px rgba(92,211,253,.6));
}

.as-orb .ping {
  position: absolute; top: 1px; right: 1px;
  width: 14px; height: 14px; border-radius: 50%;
  background: #3FD07E; border: 2px solid #0A1526;
  opacity: 0; transform: scale(.4);
  transition: opacity .3s var(--ease-out), transform .3s var(--ease-out);
}
.as-orb[data-ping="1"] .ping { opacity: 1; transform: none; }

/* ---------- the section pill that rides with it ---------- */
.as-pill {
  display: none;
  max-width: 300px;
  background: rgba(14,28,51,.94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(92,211,253,.26);
  border-radius: 30px;
  padding: 10px 17px;
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .15em; text-transform: uppercase;
  color: var(--glow);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 14px 30px -14px rgba(2,10,24,.8);
  transform-origin: right center;
  animation: asPillIn .34s var(--ease-out) both;
}
body[data-as-state="orb"] .as-pill:not(:empty) { display: block; }
@keyframes asPillIn { from { opacity: 0; transform: translateX(14px) scale(.94); } to { opacity: 1; transform: none; } }

/* ---------- the ghost that carries the morph ---------- */
.as-ghost {
  position: fixed;
  z-index: 949;
  pointer-events: none;
  background: #FFFFFF;
  border: none;
  box-shadow: 0 28px 60px -28px rgba(2,10,24,.75), 0 0 90px -30px rgba(2,136,253,.5);
  will-change: transform, width, height, border-radius, opacity;
}

/* ---------- panel states ---------- */
.as-dock .assistant { display: none; width: min(392px, calc(100vw - 44px)); max-width: none; }
body[data-as-state="open"] .as-dock .assistant { display: flex; }
/* it grows out of the corner the orb occupies */
body[data-as-state="open"] .as-dock .assistant {
  transform-origin: bottom right;
  animation: asUnfold .46s cubic-bezier(.2,1.25,.4,1) both;
}
@keyframes asUnfold {
  from { opacity: 0; transform: scale(.32) translate(38px, 46px); }
  60%  { opacity: 1; }
  to   { opacity: 1; transform: none; }
}

body[data-as-state="open"] .as-dock .as-body { min-height: 200px; max-height: min(44vh, 330px); }
body[data-as-state="open"] .as-dock .as-msg  { font-size: 14.5px; max-width: 90%; }
body[data-as-state="open"] .as-dock .as-head { padding: 14px 16px; }
body[data-as-state="open"] .as-dock .as-avatar { width: 36px; height: 36px; font-size: 13px; }
body[data-as-state="open"] .as-dock .as-foot { padding: 13px 15px 15px; }
body[data-as-state="open"] .as-dock .as-restart { width: 28px; height: 28px; font-size: 15px; }

.as-dock .as-close { display: none; }
body[data-as-state="open"] .as-dock .as-close { display: inline-flex; width: 28px; height: 28px; }

/* the hero panel has nowhere to minimise to, so its close button is not a
   button. Hiding it beats shipping a control that does nothing. */
.hero-stage .as-close { display: none; }

/* ---------- narration ---------- */
/* .as-msg.guide is styled with .as-msg.system at the top of this file */

@media (prefers-reduced-motion: reduce) {
  .as-orb::before { animation: none; opacity: 0; }
  .as-pill { animation: none; }
  body[data-as-state="open"] .as-dock .assistant { animation: none; }
  .as-orb { transition: none; }
}
@media (max-width: 640px) {
  /* no ride on a phone: the viewport is short, the orb would cross content the
     whole way down, and a moving tap target is worse than a parked one */
  .as-dock { right: 14px; left: 14px; top: auto; bottom: 14px; transform: none; }
  .as-pill { max-width: none; }
  body[data-as-state="open"] .as-dock .assistant { width: 100%; }
  body[data-as-state="open"] .as-dock .as-body { max-height: 40vh; }
}

.as-dock.as-noanim { transition: none !important; }

/* --------------------------------------------------------------------------
   Large screens. These live here rather than in style.css because this file is
   enqueued AFTER it: an .assistant rule over there loses to the base rule here
   at equal specificity, which is exactly what happened the first time.
   -------------------------------------------------------------------------- */
@media (min-width: 1500px) {
  .assistant { max-width: 540px; }
  .as-body { min-height: 340px; max-height: 500px; }
  .as-msg { font-size: 16px; }
  .as-chip { font-size: 12.5px; padding: 11px 17px; }
  .as-id .an { font-size: 17px; }
}
@media (min-width: 1900px) {
  .assistant { max-width: 580px; }
  .as-body { min-height: 370px; }
}
