/* Analyst chat (analyst_core.js) — SHARED between the extension panel and the
   website's company cards: the single source of truth for the chat's look.
   Served to the site through the Rails asset pipeline (extension/src/shared is
   on the Propshaft load path; the layout links "analyst") and to the extension
   via a plain <link> in panel.html — one file, two surfaces, no build step.

   Layout is the only thing that differs per surface, split behind modifier
   classes the mounting code applies (analyst_core.js `env.surfaceClass`):

     .analyst--panel  the extension's "fade-back" floating ask bar: sticky at
                      the panel bottom; opening fades the rest of the panel
                      back (.analyst-open on <body>).
     .analyst--card   the website's in-card chat: in flow between "Investors
                      who met" and the footer at rest; opening turns the zone
                      into an absolute white sheet sliding over the card.

   Everything else — composer, chips, bubbles, eyes, sources, pills — is
   shared verbatim. */

/* Self-contained palette (mirrors the extension's :root tokens and the site's
   Tailwind stone/gray scales) so the file needs no host-defined variables. */
.analyst {
  --stone-900: #1c1917;
  --stone-800: #292524;
  --stone-700: #44403c;
  --stone-600: #57534e;
  --stone-500: #78716c;
  --gray-200: #e5e7eb;
  --gray-100: #f3f4f6;
  --green-700: #15803d;
  --dark-btn: #2d2d2d;
}

/* ---------------------------------------------------------------------------
   Shared structure: at rest, suggested-question bubbles hovering over the
   pill composer. Gaps between the floating pieces click through to the
   surface behind (pointer-events dance below). */
.analyst {
  background: transparent;
  text-align: left;
  display: flex; flex-direction: column; gap: 8px;
  pointer-events: none;
}
.analyst > * { pointer-events: auto; }

/* ---------------------------------------------------------------------------
   Panel surface: docked (sticky) at the panel bottom; focusing anything in
   the zone opens the thread above the chips and fades the rest of the panel
   back — no shadows, no scrim; the content itself recedes. */
.analyst--panel {
  position: sticky; bottom: 0;
  /* Bleed across .wrap's 12px padding so the zone spans the panel; children
     re-indent via padding. */
  margin: 16px -12px -12px;
  padding: 6px 12px 12px;
}
.panel-surface .wrap > .analyst { margin-top: auto; }

/* Fade-back: while the chat is open, everything in the scroller except the
   analyst zone recedes and stops taking clicks — the first click outside
   just closes the chat. */
.panel-surface .wrap > :not(.analyst) { transition: opacity 0.18s ease; }
.panel-surface.analyst-open .wrap > :not(.analyst) { opacity: 0.12; pointer-events: none; }

/* Cap so the WHOLE zone (Close header + chips + composer + footer + wrap
   padding, ~210px) fits the panel: the sticky-bottom sheet clips anything
   taller at the top with no way to scroll to it. This lets a long thread
   expand to the top of the panel and no further. */
.analyst--panel .analyst-thread { max-height: calc(100vh - 210px); }

/* ---------------------------------------------------------------------------
   Card surface (website): at rest the zone is a quiet single-line composer as
   the card's LAST row, below the footer buttons — hairline border, nothing
   else (no chips, no pill — the resting card never grows). Clicking into the
   composer slides the sheet up over the whole card (the card container gets
   `relative`), headed by the company's logo + name and a Close pill;
   suggested questions and the thread live inside the sheet, which scrolls
   internally while the mount node keeps its resting height (setOpen floors
   it), so the card never changes height. */
[data-analyst-chat] { padding-top: 16px; }
.analyst--card .analyst-composer { border-width: 1px; border-color: #d1d5db; }
.analyst--card .analyst-spark { color: #d1d5db; }
.analyst--card:not(.open) .analyst-suggestions { display: none; }
/* The open ring thickens 1 → 1.5px; padding gives the half-pixel back on
   each side so the composer's outer box — which sits in the SAME spot closed
   and open — never moves a hair. */
.analyst--card.open .analyst-composer { border-width: 1.5px; padding: 8px 14px; }
.analyst--card.open .analyst-sheet-head {
  padding-bottom: 10px; margin-bottom: 8px;
  border-bottom: 1px solid var(--gray-100);
}
.analyst--card.open {
  position: absolute; inset: 0; z-index: 40;
  margin: 0; padding: 16px 20px 20px;
  background: #fff;
  /* Nested inside the card's rounded-xl (12px) border. */
  border-radius: 10px;
  /* The sheet itself must catch clicks — a click on its white ground is not
     "outside" (which would instantly close it, see analyst_core.js). */
  pointer-events: auto;
  /* Entrance: the composer must NOT move — closed and open it occupies the
     same spot at the card's bottom edge (matching paddings), so the sheet
     itself only fades its white ground in, and the CONTENT (header + thread,
     chips) slides up over the card behind the static input. */
  animation: analyst-sheet-bg 0.22s ease-out;
}
.analyst--card.open .analyst-thread-wrap,
.analyst--card.open .analyst-suggestions {
  animation: analyst-sheet-in 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes analyst-sheet-bg {
  from { background-color: rgba(255, 255, 255, 0); }
  to { background-color: #fff; }
}
@keyframes analyst-sheet-in {
  from { transform: translateY(18px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
/* Sheet column: Close header + thread take the slack, composer stays put at
   the bottom — mirroring the panel's docked composer. */
.analyst--card.open .analyst-thread-wrap {
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0;
}
.analyst--card.open .analyst-thread { flex: 1 1 auto; }

/* ---------------------------------------------------------------------------
   Thread: hidden at rest, revealed while open. */
.analyst-thread-wrap { display: none; }
.analyst.open .analyst-thread-wrap { display: block; }
.analyst--card.open .analyst-thread-wrap { display: flex; }
.analyst-thread {
  display: flex; flex-direction: column; gap: 8px;
  overflow-y: auto; overscroll-behavior: contain;
  padding-top: 2px;
  min-height: 0;
}
.analyst-thread:empty { display: none; }

.analyst-msg { max-width: 92%; border-radius: 12px; padding: 8px 10px; font-size: 13px; line-height: 1.45; }
.analyst-msg-user {
  align-self: flex-end; background: var(--dark-btn); color: #fff;
  border-bottom-right-radius: 4px; white-space: pre-wrap; overflow-wrap: anywhere;
}
.analyst-msg-assistant {
  position: relative; /* anchors the hover copy button */
  align-self: flex-start; background: var(--gray-100); color: var(--stone-800);
  border-bottom-left-radius: 4px;
}
/* Copy-response affordance: invisible (and click-through) until the bubble is
   hovered or it holds keyboard focus; flips to a green check after copying. */
.analyst-copy {
  position: absolute; top: 5px; right: 5px;
  width: 22px; height: 22px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: #fff; border: 1px solid var(--gray-200); border-radius: 6px;
  color: var(--stone-500); cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity 0.12s;
}
.analyst-msg-assistant:hover .analyst-copy,
.analyst-copy:focus-visible,
.analyst-copy.copied {
  opacity: 1; pointer-events: auto;
}
.analyst-copy:hover { color: var(--stone-800); }
.analyst-copy.copied { color: var(--green-700); }
.analyst-copy svg { width: 12px; height: 12px; }
.analyst-answer { overflow-wrap: anywhere; }
.analyst-answer p { margin: 0 0 6px; }
.analyst-answer p:last-child { margin-bottom: 0; }
.analyst-answer ul, .analyst-answer ol { margin: 4px 0; padding-left: 18px; }
.analyst-answer li { margin: 2px 0; }
.analyst-answer a { color: #2B4FD8; text-decoration: underline; }
/* Citations stay on ONE row and scroll sideways — a long source list must not
   push the answer's text up. Scrollbar hidden (the clipped last chip is the
   affordance). */
.analyst-sources {
  display: flex; flex-wrap: nowrap; gap: 8px; align-items: baseline; margin-top: 9px;
  overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
}
.analyst-sources::-webkit-scrollbar { display: none; }
.analyst-sources-label {
  flex: 0 0 auto;
  font-size: 9.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
  color: #a8a29e;
}
.analyst-source {
  flex: 0 0 auto; max-width: 150px;
  font-size: 11px; color: var(--stone-500);
  text-decoration: none; border-bottom: 1px solid var(--gray-200);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.analyst-source:hover { color: var(--stone-800); border-bottom-color: var(--stone-500); }
/* Hover tooltip with the cited page's title (positioned by analyst_core.js). */
.analyst-tooltip {
  position: absolute; z-index: 40;
  width: max-content; max-width: 230px;
  white-space: normal; overflow-wrap: anywhere;
  background: var(--stone-900); color: #fff;
  font-size: 11px; line-height: 1.35; font-weight: 500;
  border-radius: 8px; padding: 5px 8px;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(28, 25, 23, 0.25);
}
/* Typing indicator while the answer is pending: a pair of eyes scanning the
   page — pupils dart between rest points together, with one honest blink per
   loop (the whole pair scaleY-squints; a lid overlay would be more chrome
   than the joke needs). */
.analyst-pending { display: flex; gap: 4px; padding: 10px 12px; }
.analyst-eyes { display: flex; gap: 5px; animation: analyst-blink 4s infinite; }
.analyst-eye {
  position: relative; width: 13px; height: 13px; border-radius: 999px;
  background: #fff; border: 1.5px solid var(--stone-500);
}
.analyst-pupil {
  position: absolute; left: 50%; top: 50%; width: 4px; height: 4px; margin: -2px;
  border-radius: 999px; background: var(--stone-800);
  animation: analyst-dart 4s infinite;
}
@keyframes analyst-dart {
  0%, 12% { transform: translate(0, 0); }
  18%, 32% { transform: translate(-2.6px, 0.6px); }
  38%, 52% { transform: translate(2.6px, -0.6px); }
  58%, 68% { transform: translate(0, 0); }
  74%, 88% { transform: translate(1.6px, -1.8px); }
  94%, 100% { transform: translate(0, 0); }
}
@keyframes analyst-blink {
  0%, 69% { transform: scaleY(1); }
  71% { transform: scaleY(0.12); }
  73%, 100% { transform: scaleY(1); }
}

/* Variant looks for the pending eyes, picked at random per question in
   analyst_core.js (the default darting look above is one of the pool). The
   variant class rides on .analyst-eyes; extra elements (brows, hearts)
   exist only when their variant was drawn. */

/* Googly wobble: loose sticker pupils rattling around the bottom. */
.analyst-eyes.v-googly .analyst-pupil { animation: analyst-googly 2.6s infinite ease-in-out; }
.analyst-eyes.v-googly .analyst-eye:nth-child(2) .analyst-pupil { animation-delay: 0.35s; }
@keyframes analyst-googly {
  0%, 100% { transform: translate(0, 1.8px); }
  12% { transform: translate(-1.9px, 0.9px); }
  26% { transform: translate(1.4px, 1.5px); }
  40% { transform: translate(-0.9px, 1.8px); }
  55% { transform: translate(2px, 0.7px); }
  70% { transform: translate(-1.4px, 1.4px); }
  85% { transform: translate(0.8px, 1.9px); }
}

/* Speed reader: saccades along two lines of text (holds between the
   adjacent keyframe pairs make the jumps discrete, like real reading). */
.analyst-eyes.v-reader { animation-duration: 6s; }
.analyst-eyes.v-reader .analyst-pupil { animation: analyst-read 3s infinite; }
@keyframes analyst-read {
  0%, 11% { transform: translate(-2.4px, -1px); }
  12%, 23% { transform: translate(-0.8px, -1px); }
  24%, 35% { transform: translate(0.8px, -1px); }
  36%, 47% { transform: translate(2.4px, -1px); }
  48%, 59% { transform: translate(-2.4px, 0.8px); }
  60%, 71% { transform: translate(-0.8px, 0.8px); }
  72%, 83% { transform: translate(0.8px, 0.8px); }
  84%, 95% { transform: translate(2.4px, 0.8px); }
  96%, 100% { transform: translate(-2.4px, -1px); }
}

/* Skeptic: eyebrows — one arches while the pupils glance toward it, then
   both pop up. No wrapper blink (it would squash the brows). */
.analyst-eyes.v-skeptic { position: relative; padding-top: 6px; animation: none; }
.analyst-brow {
  position: absolute; top: 2px; width: 8px; height: 1.8px; border-radius: 1px;
  background: var(--stone-600);
}
.analyst-brow.brow-left { left: 2.5px; transform-origin: right center; animation: analyst-brow-left 3.4s infinite; }
.analyst-brow.brow-right { left: 20.5px; transform-origin: left center; animation: analyst-brow-right 3.4s infinite; }
.analyst-eyes.v-skeptic .analyst-pupil { animation: analyst-glance 3.4s infinite; }
@keyframes analyst-brow-left {
  0%, 20% { transform: translateY(0) rotate(0deg); }
  26%, 48% { transform: translateY(-2.4px) rotate(-8deg); }
  54%, 74% { transform: translateY(0) rotate(0deg); }
  78%, 88% { transform: translateY(-2.4px) rotate(-8deg); }
  94%, 100% { transform: translateY(0) rotate(0deg); }
}
@keyframes analyst-brow-right {
  0%, 74% { transform: translateY(0) rotate(0deg); }
  78%, 88% { transform: translateY(-2.4px) rotate(8deg); }
  94%, 100% { transform: translateY(0) rotate(0deg); }
}
@keyframes analyst-glance {
  0%, 20% { transform: translate(0, 0); }
  26%, 48% { transform: translate(-2px, -1.2px); }
  54%, 74% { transform: translate(0, 0); }
  78%, 88% { transform: translate(0, -1.6px); }
  94%, 100% { transform: translate(0, 0); }
}

/* Heart eyes: scan, then both pupils flip to beating hearts for a beat. */
.analyst-eyes.v-hearts { animation-duration: 6s; }
.analyst-eyes.v-hearts .analyst-pupil { animation: analyst-smitten 3.2s infinite; }
.analyst-heart {
  position: absolute; left: 50%; top: 50%; width: 5px; height: 5px; margin: -2.8px -2.5px;
  background: #dc2626; transform: rotate(45deg) scale(0);
  animation: analyst-heartbeat 3.2s infinite;
}
.analyst-heart::before, .analyst-heart::after {
  content: ''; position: absolute; width: 5px; height: 5px; border-radius: 999px; background: #dc2626;
}
.analyst-heart::before { left: -2.5px; }
.analyst-heart::after { top: -2.5px; }
@keyframes analyst-smitten {
  0%, 12% { transform: translate(0, 0); opacity: 1; }
  18%, 32% { transform: translate(-2.2px, 0.5px); opacity: 1; }
  38%, 50% { transform: translate(2.2px, -0.5px); opacity: 1; }
  55%, 85% { opacity: 0; transform: translate(0, 0); }
  90%, 100% { opacity: 1; transform: translate(0, 0); }
}
@keyframes analyst-heartbeat {
  0%, 52% { transform: rotate(45deg) scale(0); }
  58% { transform: rotate(45deg) scale(1.15); }
  63% { transform: rotate(45deg) scale(0.95); }
  68% { transform: rotate(45deg) scale(1.1); }
  73% { transform: rotate(45deg) scale(0.95); }
  78% { transform: rotate(45deg) scale(1.05); }
  84%, 100% { transform: rotate(45deg) scale(0); }
}

@media (prefers-reduced-motion: reduce) {
  .analyst-eyes, .analyst-pupil, .analyst-brow, .analyst-heart { animation: none; }
  .analyst--card.open,
  .analyst--card.open .analyst-thread-wrap,
  .analyst--card.open .analyst-suggestions { animation: none; }
}
.analyst-failed { background: #fef2f2; border: 1px solid #fecaca; }
.analyst-failed-text { font-size: 12.5px; color: #b91c1c; }
.analyst-retry {
  margin-top: 6px; font: inherit; font-size: 12px; font-weight: 500;
  color: var(--stone-700); background: #fff; border: 1px solid var(--gray-200);
  border-radius: 8px; padding: 4px 10px; cursor: pointer;
}
.analyst-retry:hover { background: var(--gray-100); }

/* Question recommendations: filled bubbles hovering over the text field on
   ONE row — overflow scrolls sideways (scrollbar hidden; the clipped last
   chip is the affordance). The first chip's auto margin right-aligns the row
   while it fits and collapses to a normal scroll row once it overflows
   (justify-content: flex-end would make the overflow unreachable). */
.analyst-suggestions {
  display: flex; flex-wrap: nowrap; gap: 6px;
  overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
  /* Never let the zone's column squeeze this row: overflow-x:auto makes it a
     vertical clipping context too, so any flex shrink cuts the chips in half
     instead of just tightening space. The thread is the only shrinker. */
  flex-shrink: 0;
}
.analyst-suggestions::-webkit-scrollbar { display: none; }
.analyst-suggestions:empty { display: none; }
.analyst-chip:first-child { margin-left: auto; }
.analyst-chip {
  flex: 0 0 auto; white-space: nowrap;
  font: inherit; font-size: 12px; color: var(--stone-600);
  background: #f4f5f8; border: 1px solid transparent;
  border-radius: 999px; padding: 6px 11px; cursor: pointer;
}
.analyst-chip:hover { background: #e9ebf1; color: var(--stone-900); }

/* Sheet header: a Close pill at the top right of an open conversation — and,
   when the mounting surface supplies a brand (the site's card sheet), the
   subject's logo + name on the left, vertically centered with the pill. */
.analyst-sheet-head {
  display: flex; align-items: center; justify-content: flex-end; padding-bottom: 4px;
  flex-shrink: 0; /* a long thread scrolls; it must not squash the header */
}
.analyst-brand { display: flex; align-items: center; gap: 10px; min-width: 0; margin-right: auto; }
.analyst-brand-logo {
  width: 32px; height: 32px; flex-shrink: 0;
  border-radius: 8px; background: var(--gray-100); object-fit: contain;
}
.analyst-brand-name {
  font-family: var(--font-display, Georgia, serif); font-size: 16px; font-weight: 600;
  color: var(--stone-900);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* When the mounting surface wires brand.onOpen (analyst_core.js), the
   identity is a control — same affordance as the card's own logo/name. */
.analyst-brand-click { cursor: pointer; }
.analyst-brand-click:hover .analyst-brand-name { text-decoration: underline; }
.analyst-close, .analyst-show {
  display: inline-flex; align-items: center; gap: 4px;
  font: inherit; font-size: 11.5px; font-weight: 500; color: var(--stone-500);
  background: #fff; border: 1px solid var(--gray-200); border-radius: 999px;
  padding: 4px 10px; cursor: pointer; white-space: nowrap;
}
.analyst-close:hover, .analyst-show:hover { color: var(--stone-800); border-color: #a8a29e; }
.analyst-close svg, .analyst-show svg { width: 11px; height: 11px; }

/* "Show convo" — visible at rest only once there is a conversation to show.
   Panel-only: on the site the quiet composer itself reopens the sheet (any
   click into it), so the card surface suppresses the pill entirely. */
.analyst-show { display: none; }
.analyst.has-messages:not(.open) .analyst-show { display: inline-flex; align-self: flex-end; }
.analyst--card.has-messages:not(.open) .analyst-show { display: none; }

/* The floating pill composer — "paper + ink ring" (round-10 option 5): a
   white field carrying a 1.5px #2d2d2d outline, noticeable by weight of
   line rather than fill; the open state deepens the ring to true black as
   the quiet focus cue. */
.analyst-composer {
  display: flex; align-items: center; gap: 9px;
  background: #fff; border: 1.5px solid var(--dark-btn); border-radius: 22px;
  padding: 8.5px 14.5px;
  transition: border-color 0.15s ease;
  flex-shrink: 0; /* the thread absorbs height pressure, never the input */
}
.analyst-spark { display: inline-flex; color: var(--stone-500); flex-shrink: 0; }
.analyst-spark svg { width: 15px; height: 15px; }
.analyst.open .analyst-composer { border-color: #000; }
.analyst-input {
  flex: 1; resize: none; font: inherit; font-size: 13px; color: var(--stone-800);
  /* Pinned, not inherited: `font: inherit` re-resolves a host's unitless
     line-height against OUR font-size (the site's card context computes it to
     13px — a line box shorter than the 19px field, so the placeholder rode
     high). 19px = min-height: one line sits dead-center on every surface. */
  line-height: 19px;
  caret-color: var(--stone-800);
  background: transparent; border: none; outline: none;
  padding: 0; min-height: 19px; max-height: 120px;
}
.analyst-input::placeholder { color: #a8a29e; }
.analyst-input:disabled { color: var(--stone-500); }
.analyst-hint { font-size: 12px; color: #b91c1c; min-height: 0; }
.analyst-hint:empty { display: none; }

/* The starter block rendered into a caller-owned slot (the panel's no-match
   body — analyst_core.js renderStarterRows): lead line + full-width question
   rows. The slot sits OUTSIDE .analyst, so it restates the tokens it needs. */
.nomatch-analyst-lead { margin-top: 10px; font-size: 13px; line-height: 1.5; color: #57534e; }
.analyst-qrow {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; margin-top: 8px; font: inherit; font-size: 13px; font-weight: 500;
  color: #292524; background: #fff; border: 1px solid #e5e7eb;
  border-radius: 10px; padding: 10px 12px; cursor: pointer; text-align: left;
  box-shadow: 0 1px 1px rgb(0 0 0 / 0.04);
}
.analyst-qrow:hover { background: #f9fafb; border-color: #d1d5db; }
.analyst-qrow-chevron { display: inline-flex; color: #a8a29e; }
.analyst-qrow-chevron svg { width: 13px; height: 13px; }
