/* ============================================================
   AI assistant window — vanilla embed for wassenger.com
   ============================================================
   Pairs with the +wrAiWindow(variant) Pug mixin and
   /js/embeds/ai-window.js.

   The root element carries .ai-window plus one variant class:
   .ai-window--claude | .ai-window--chatgpt | .ai-window--generic.
   The variant only re-points --aiw-accent; every other rule is
   shared, and the surface is the same in all three.

   Why the surface is dark
   -----------------------
   The bar is how linear.app renders a product surface (see
   docs/superpowers/specs/2026-09-04-ai-integrations-linear-bar.md).
   Linear's app window is one step lighter than its near-black
   canvas, edged with a hairline and lit from above — the depth is
   a light source, not a drop shadow under a flat card. A white
   window on that canvas has to be rescued with a heavy shadow and
   still reads as a screenshot pasted onto the page, so this embed
   renders the assistant in its dark theme, which both Claude and
   ChatGPT actually ship.

   Why there is no browser chrome
   ------------------------------
   This used to open with macOS traffic lights and a centred URL
   pill. That is the single clearest tell of a marketing mockup:
   it frames the product as a screenshot of a website. Linear shows
   no browser at all — the app's own top bar runs to the window
   edge, and the rounded corner plus the hairline ring is the
   chrome. The assistant's identity is already carried twice, by
   the sidebar lockup and the model chip, so the URL bar was
   costing 42px of fold for information the fold already had.

   Self-contained — no external dependencies.
   ============================================================ */

.ai-window {
  /* Surface. Four steps, each one small: window ground, content
     pane, raised panel, hover. Linear's whole product surface
     lives inside about 12 points of lightness. */
  --aiw-bg: #0e0f11;
  --aiw-pane: #131416;
  --aiw-raise: #191b1d;
  --aiw-raise-2: #212426;

  --aiw-line: rgba(255, 255, 255, 0.075);
  --aiw-line-soft: rgba(255, 255, 255, 0.045);

  --aiw-ink: #f0f1f2;
  --aiw-ink-2: #9ba0a8;
  --aiw-ink-3: #6a6f77;

  /* The only saturated things in the window: an unread marker and
     a connection state. Colour carries meaning, never decoration. */
  --aiw-live: #3fb950;

  /* Variant token — the assistant's own hue, used on the mono
     tool-call name and nowhere else. */
  --aiw-accent: #7f9cf5;

  /* The thread's measure. The pane is ~1100px wide in the fold and
     the type inside it is 13px: left to fill, a message row puts the
     contact's name and its timestamp 1,200px apart with nothing in
     between, which no chat client has ever looked like. Every real
     client caps the column and centres it — ChatGPT runs ~768px
     inside a ~1180px pane at this viewport — so the conversation
     reads as software instead of as a banner. */
  --aiw-measure: 772px;

  position: relative;
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  border-radius: 14px;
  background: var(--aiw-bg);
  overflow: hidden;
  font-family: var(--wr-ai-font, "Inter Variable", "Inter", ui-sans-serif,
               system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
  color: var(--aiw-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  contain: layout style;

  /* The light source, in three parts, all of them things a panel
     sitting on a dark desktop actually does — none of them a card
     shadow. A 1px highlight along the top edge where the light
     catches; a hairline ring so the window has an edge instead of
     bleeding into the canvas (Linear's window reads as an object
     because you can see its corner against the ground); and a wide,
     very dark, entirely offset-down wash that is occlusion under
     the object rather than a halo around a sticker. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.055),
    0 0 0 1px rgba(255, 255, 255, 0.055),
    0 32px 64px -32px rgba(0, 0, 0, 0.9);
}

.ai-window--claude {
  --aiw-accent: #d38b5d;
  --aiw-mark-ink: #d97757;
}
.ai-window--chatgpt {
  --aiw-accent: #8ad3b8;
  --aiw-mark-ink: #0d0d0d;
}
.ai-window--generic {
  --aiw-accent: #7f9cf5;
  --aiw-mark-ink: #3276ed;
}

/* ----- Layout: sidebar + content pane -----
   Fixed height so the conversation scrolls *inside* the window,
   the way the real clients do. */
.ai-window .aiw-layout {
  display: grid;
  grid-template-columns: 232px 1fr;
  height: 640px;
  position: relative;
}

/* ----- The assistant's mark, as an app icon tile -----
   ChatGPT ships a black-on-transparent PNG, which would vanish on
   this surface. Every mark therefore sits on a light tile, which is
   also what the marks look like in a dock. */
.ai-window .aiw-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: #f4f4f2;
  border-radius: 5px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}
.ai-window .aiw-mark--20 { width: 20px; height: 20px; }
.ai-window .aiw-mark--22 { width: 22px; height: 22px; border-radius: 6px; }
.ai-window .aiw-glyph { display: block; color: var(--aiw-mark-ink, #0d0d0d); }

/* ============================================================
   Sidebar
   ============================================================ */
/* `padding-top` matches the content pane's own top margin so the
   workspace lockup and the pane header sit on one line. */
.ai-window .aiw-side {
  background: var(--aiw-bg);
  padding: 8px 10px 10px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.ai-window .aiw-side-top {
  height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 2px;
  flex-shrink: 0;
}
.ai-window .aiw-workspace {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex: 1;
}
.ai-window .aiw-workspace-name {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--aiw-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ai-window .aiw-workspace-caret {
  color: var(--aiw-ink-3);
  flex-shrink: 0;
}

.ai-window .aiw-icon-btn {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--aiw-ink-2);
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.ai-window .aiw-icon-btn:hover {
  background: var(--aiw-raise-2);
  color: var(--aiw-ink);
}
.ai-window .aiw-icon-btn--ring { border-color: var(--aiw-line); }

.ai-window .aiw-side-heading {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--aiw-ink-3);
  padding: 0 8px;
  margin: 14px 0 4px;
}

/* The unlabelled nav block directly under the lockup, above the
   first dated group. Linear's sidebar opens the same way — Pulse,
   Inbox, My issues, Reviews with no heading over them, then the
   labelled Workspace and Favorites groups — and so does every
   assistant client this window is standing in for. It is the
   difference between a panel showing one list and a product with
   places to go, and it is what stops the sidebar running out of
   content two thirds of the way down. */
.ai-window .aiw-side-nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin-top: 6px;
}
.ai-window .aiw-side-nav .aiw-side-row { color: var(--aiw-ink); }
.ai-window .aiw-side-nav .aiw-side-row svg { opacity: 0.6; }

/* The dated groups, in a region that takes the sidebar's leftover
   height and clips. Before this the history simply stopped and left
   224px of measured dead ground above the account row — the panel
   read as a demo that ran out of data. A real client always holds
   more history than the panel is tall, so the correct fix is not
   more rows padded to the bottom edge but a list that runs past it
   and fades under the account row. The fade is a mask rather than a
   gradient overlay so it works over whatever the sidebar's ground
   happens to be on a given page theme. */
.ai-window .aiw-side-scroll {
  /* `flex-basis: 0`, not `auto`, and it is load-bearing rather than a
     style choice. `_ai-hero.scss` runs the fold's window at
     `height: auto; min-height: 640px` so the transcript lays out in
     full instead of scrolling inside the pane — which means the grid
     row is as tall as its TALLEST column. With `basis: auto` this
     list contributes its full content height to that maximum, so a
     history long enough to clip instead grew the whole window by
     154px and pushed the fold's crop down with it. At basis 0 the
     region contributes nothing, the pane keeps deciding the height,
     and the list takes whatever is left and clips inside it — which
     is the behaviour this region was added for. */
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 44px), transparent);
  mask-image: linear-gradient(180deg, #000 calc(100% - 44px), transparent);
}

.ai-window .aiw-side-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-height: 0;
}
.ai-window .aiw-side-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 12.5px;
  line-height: 16px;
  color: var(--aiw-ink-2);
  white-space: nowrap;
  overflow: hidden;
}
.ai-window .aiw-side-row > span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
}
.ai-window .aiw-side-row svg { flex-shrink: 0; opacity: 0.75; }
.ai-window .aiw-side-row.is-active {
  background: var(--aiw-raise-2);
  color: var(--aiw-ink);
}

/* Account row, pinned to the bottom of the sidebar — the piece of
   ambient state that says this window belongs to somebody and is
   wired to something. */
.ai-window .aiw-side-foot {
  margin-top: auto;
  padding: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  border-top: 1px solid var(--aiw-line-soft);
  font-size: 11.5px;
  color: var(--aiw-ink-2);
  min-width: 0;
}
/* Neutral, not a brand-blue chip. It sits three inches from the
   assistant's own mark, and a second saturated hue down there is a
   palette accumulating rather than being decided — the same reason
   `_ai-hero.scss` collapses --aiw-live and --aiw-accent onto the
   assistant's hue for the fold instance. That override cannot reach
   this rule, so it is settled here. */
.ai-window .aiw-side-avatar {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: var(--aiw-raise-2);
  border: 1px solid var(--aiw-line);
  color: var(--aiw-ink-2);
  font-size: 9.5px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.ai-window .aiw-side-foot-name {
  color: var(--aiw-ink);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ai-window .aiw-side-foot-state {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--aiw-ink-3);
  white-space: nowrap;
}
.ai-window .aiw-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--aiw-live);
  flex-shrink: 0;
}

/* ============================================================
   Content pane — an inset panel, exactly as Linear insets its
   record view inside the sidebar's ground.
   ============================================================ */
.ai-window .aiw-main {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  margin: 8px 8px 8px 0;
  border: 1px solid var(--aiw-line-soft);
  border-radius: 10px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.022), rgba(255, 255, 255, 0) 180px),
    var(--aiw-pane);
  overflow: hidden;
}

.ai-window .aiw-header {
  height: 44px;
  flex-shrink: 0;
  padding: 0 14px;
  border-bottom: 1px solid var(--aiw-line-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* ----- Pane body: thread + rail -----
   Two columns under the header, which is how Linear lays out a
   record: the thing you are reading on the left, and a rail of
   what the workspace knows about it on the right. One column in
   an 1,100px pane leaves ~45% of it empty however wide the
   measure is set, and widening the measure past ~780px only
   trades the empty ground for unreadable line lengths.

   The `min-width` and `min-height` zeroes are load-bearing: a flex
   item defaults to `min-*: auto`, which refuses to shrink below
   content size, and the transcript would then push the rail off
   the pane instead of scrolling inside it. */
.ai-window .aiw-body {
  display: flex;
  flex: 1;
  min-height: 0;
  min-width: 0;
}
.ai-window .aiw-thread {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
}

.ai-window .aiw-rail {
  width: 280px;
  flex-shrink: 0;
  border-left: 1px solid var(--aiw-line-soft);
  padding: 16px 16px 18px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.ai-window .aiw-rail-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--aiw-ink-3);
  margin-bottom: 8px;
}
.ai-window .aiw-rail-count {
  font-variant-numeric: tabular-nums;
  color: var(--aiw-ink-3);
  opacity: 0.7;
}
.ai-window .aiw-rail-label + * + .aiw-rail-label { margin-top: 22px; }

.ai-window .aiw-rail-conn {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 2px 8px;
}
.ai-window .aiw-rail-conn .aiw-dot { grid-row: 1; }
.ai-window .aiw-rail-conn-num {
  font-size: 12.5px;
  color: var(--aiw-ink);
  font-variant-numeric: tabular-nums;
}
.ai-window .aiw-rail-conn-kind {
  grid-column: 2;
  font-size: 11px;
  color: var(--aiw-ink-3);
}

/* The tool inventory, in three states that mean three different
   things. The old version drew the same check on all six rows and
   separated them only by opacity, so `send_message` read as SENT —
   on a window whose entire argument is that nothing goes out until
   you say so. Now the glyph carries it: a check for a call that
   ran, a hollow ring for the one being held for approval, a bare
   dash for a tool this conversation never touched.

   Only the check is coloured. `held` stays monochrome and earns its
   emphasis from ink weight instead, because a third saturated hue
   in here would be a palette accumulating rather than a decision —
   the failure the design language records in §5.3. */
.ai-window .aiw-rail-tools {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ai-window .aiw-rail-tool {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.ai-window .aiw-rail-tool svg {
  flex-shrink: 0;
  color: var(--aiw-ink-3);
  opacity: 0.3;
}
.ai-window .aiw-rail-tool.is-done svg {
  color: var(--aiw-live);
  opacity: 1;
}
.ai-window .aiw-rail-tool.is-held svg {
  color: var(--aiw-ink-2);
  opacity: 1;
}
.ai-window .aiw-rail-tool code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11.5px;
  color: var(--aiw-ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ai-window .aiw-rail-tool.is-done code { color: var(--aiw-ink-2); }
.ai-window .aiw-rail-tool.is-held code { color: var(--aiw-ink); }
.ai-window .aiw-rail-tool-note {
  margin-left: auto;
  padding-left: 8px;
  font-size: 10px;
  line-height: 14px;
  color: var(--aiw-ink-3);
  white-space: nowrap;
  flex-shrink: 0;
}

/* ----- Response viewer -----
   The raw body the last tool call returned. It is the only surface
   in the window a developer recognises on sight, and it is what
   makes the draft above checkable rather than asserted: the
   tracking number in the message is the tracking number in the
   payload. It is machine data, so unlike every other string here it
   carries no translation.

   `flex: 1` with `min-height: 0` is what closes the rail's hole for
   good — measured at 412px of a 743px rail before this. The block
   takes whatever height is left over and clips, so the panel is
   full at any window height instead of being padded to one. A body
   longer than its box is also exactly what a response viewer looks
   like, which is why the fade is honest here. */
.ai-window .aiw-rail-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: -2px 0 7px;
  min-width: 0;
}
.ai-window .aiw-rail-meta code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11px;
  color: var(--aiw-ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ai-window .aiw-rail-meta span {
  font-size: 10.5px;
  color: var(--aiw-ink-3);
  white-space: nowrap;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.ai-window .aiw-rail-json {
  /* `basis: 0` for the same reason as `.aiw-side-scroll` — see the
     note there. The viewer takes the rail's leftover height; it must
     never be what decides it. */
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  margin-bottom: 12px;
  padding: 9px 10px;
  border: 1px solid var(--aiw-line-soft);
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.28);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 10.5px;
  line-height: 16px;
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 26px), transparent);
  mask-image: linear-gradient(180deg, #000 calc(100% - 26px), transparent);
}
/* Clipped horizontally, never wrapped. A wrapped JSON line breaks
   its indentation and drops the value to column 0, which reads as a
   layout bug rather than as data; every real response viewer clips
   on the right instead. The rail is sized so the longest authored
   line — the tracking number, which has to stay legible because the
   drafted message quotes it — clears the edge with room to spare. */
.ai-window .aiw-json-line {
  white-space: pre;
  overflow: hidden;
}
/* Three inks, no syntax rainbow: keys read as labels, values as the
   content, punctuation recedes. Rule 6 — colour carries meaning —
   and a type system is not a meaning this page needs to convey. */
.ai-window .aiw-json-k { color: var(--aiw-ink-2); }
.ai-window .aiw-json-p { color: var(--aiw-ink-3); }
.ai-window .aiw-json-v { color: var(--aiw-ink); }

.ai-window .aiw-rail-foot {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--aiw-line-soft);
  display: flex;
  align-items: flex-start;
  gap: 9px;
  color: var(--aiw-ink-3);
}
.ai-window .aiw-rail-foot svg { flex-shrink: 0; margin-top: 1px; }
.ai-window .aiw-rail-foot-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.ai-window .aiw-rail-foot-text b {
  font-size: 12px;
  font-weight: 500;
  color: var(--aiw-ink-2);
}
.ai-window .aiw-rail-foot-text span {
  font-size: 11px;
  line-height: 1.35;
  color: var(--aiw-ink-3);
}
.ai-window .aiw-header h3 {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--aiw-ink);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ai-window .aiw-header-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.ai-window .aiw-chip {
  height: 22px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  border: 1px solid var(--aiw-line);
  border-radius: 6px;
  font-size: 11.5px;
  line-height: 1;
  color: var(--aiw-ink-2);
  white-space: nowrap;
}
.ai-window .aiw-chip b {
  font-weight: 500;
  color: var(--aiw-ink);
}
.ai-window .aiw-chip-sep {
  width: 1px;
  height: 10px;
  background: var(--aiw-line);
}

/* ============================================================
   Conversation
   ============================================================ */
.ai-window .aiw-messages {
  padding: 18px 22px 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  flex: 1;
  /* `min-height: 0` is required for `overflow-y: auto` to actually clip
     inside a flex column — otherwise the item grows to fit its content. */
  min-height: 0;
  overflow-y: auto;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.14) transparent;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.ai-window .aiw-messages::-webkit-scrollbar { width: 6px; }
.ai-window .aiw-messages::-webkit-scrollbar-track { background: transparent; }
.ai-window .aiw-messages::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.14);
  border-radius: 3px;
}
.ai-window .aiw-messages::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.24);
}

/* The thread is a fixed-measure column centred in the pane.
   `flex-shrink: 0` because a flex column will otherwise squeeze its
   items once the transcript is taller than the pane, which is the
   normal state here.

   It is deliberately NOT bottom-anchored. Hanging the stack off the
   composer is what the real clients do and it reads well in
   isolation — but the fold crops this window ~300px down from its
   top edge, so anchoring the conversation to the bottom put every
   word of it below the fold and left the visitor looking at an
   empty pane. Top-aligned, the first thing in frame is the question
   being asked, which is the whole point of the artifact. */
.ai-window .aiw-messages > * {
  width: 100%;
  max-width: var(--aiw-measure);
  margin-left: auto;
  margin-right: auto;
  flex-shrink: 0;
}

.ai-window .aiw-day {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 11px;
  color: var(--aiw-ink-3);
  margin-bottom: -4px;
}
.ai-window .aiw-day::before,
.ai-window .aiw-day::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--aiw-line-soft);
}

.ai-window .aiw-msg-user {
  display: flex;
  justify-content: flex-end;
}
.ai-window .aiw-msg-user > div {
  background: var(--aiw-raise);
  border: 1px solid var(--aiw-line);
  color: var(--aiw-ink);
  padding: 9px 13px;
  border-radius: 12px;
  max-width: 62%;
  font-size: 13.5px;
  line-height: 1.5;
}

.ai-window .aiw-msg-assistant {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.ai-window .aiw-msg-body {
  flex: 1;
  min-width: 0;
  padding-top: 1px;
}

/* ----- Tool call -----
   One compact row, the way the real clients disclose a tool use:
   a status glyph, the server and the function in mono, and the
   result count hung off the right. */
.ai-window .aiw-tool {
  background: var(--aiw-raise);
  border: 1px solid var(--aiw-line);
  border-radius: 7px;
  padding: 6px 10px;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  line-height: 18px;
  color: var(--aiw-ink-2);
}
.ai-window .aiw-tool-check { color: var(--aiw-live); flex-shrink: 0; }
.ai-window .aiw-tool b { color: var(--aiw-ink); font-weight: 500; }
.ai-window .aiw-tool code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 11.5px;
  color: var(--aiw-accent);
}
.ai-window .aiw-tool .aiw-tool-meta {
  margin-left: auto;
  padding-left: 10px;
  font-size: 11px;
  white-space: nowrap;
  color: var(--aiw-ink-3);
  font-variant-numeric: tabular-nums;
}

/* ----- Streamed paragraph (typewriter target) -----
   The colour is set explicitly: host pages carry a legacy global
   `p { color: #677294 }` from src/scss/_typography.scss that otherwise wins
   over the colour inherited from .ai-window and tints this paragraph blue. */
.ai-window .aiw-intro {
  margin: 0 0 12px;
  color: var(--aiw-ink);
  font-size: 13.5px;
  line-height: 1.6;
  min-height: 22px;
  white-space: pre-wrap;
}
/* A real caret, drawn by the stylesheet, instead of a literal pipe
   character sitting in the text node. */
.ai-window .is-typing::after {
  content: '';
  display: inline-block;
  width: 1.5px;
  height: 1.05em;
  margin-left: 2px;
  vertical-align: -0.18em;
  background: currentColor;
  opacity: 0.85;
}
@media (prefers-reduced-motion: no-preference) {
  .ai-window .is-typing::after { animation: aiw-caret 1.05s steps(1, end) infinite; }
}
@keyframes aiw-caret {
  0%, 50% { opacity: 0.85; }
  51%, 100% { opacity: 0; }
}

/* ----- Result list -----
   One panel with hairline row separators, not a stack of floating
   cards. A list is what an application renders; five rounded cards
   with gaps between them is what a landing page renders.

   The surface belongs to the ROWS, not to a wrapper. Rows arrive one
   at a time and a wrapper that owns the background paints its full
   reserved height the moment the assistant starts answering — an
   empty grey box sitting in the fold, waiting. Each row carries its
   own border instead and overlaps its neighbour by a pixel, so the
   list draws itself as the results stream in. */
.ai-window .aiw-list {
  display: flex;
  flex-direction: column;
}
.ai-window .aiw-item {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  background: var(--aiw-raise);
  border: 1px solid var(--aiw-line);
}
.ai-window .aiw-item + .aiw-item { margin-top: -1px; }
.ai-window .aiw-item:first-child { border-radius: 9px 9px 0 0; }
.ai-window .aiw-item:last-child { border-radius: 0 0 9px 9px; }
.ai-window .aiw-item:only-child { border-radius: 9px; }
.ai-window .aiw-unread {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--aiw-live);
  flex-shrink: 0;
}
.ai-window .aiw-item-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 9.5px;
  letter-spacing: 0.01em;
  flex-shrink: 0;
}
.ai-window .aiw-item-info { min-width: 0; }
.ai-window .aiw-item-name {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 550;
  color: var(--aiw-ink);
  line-height: 16px;
}
.ai-window .aiw-item-phone {
  font-weight: 400;
  font-size: 11px;
  color: var(--aiw-ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ai-window .aiw-item-msg {
  font-size: 12px;
  line-height: 16px;
  color: var(--aiw-ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ai-window .aiw-item-time {
  font-size: 11px;
  color: var(--aiw-ink-3);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ----- Draft card -----
   The one element in the window that is a *panel* rather than a
   row: it carries the message that will actually be sent, and the
   two buttons that decide whether it is. It gets the same treatment
   Linear gives its agent panel — a step brighter than the pane it
   sits on, a lit top edge, and occlusion under it — so the payload
   sits proud of the transcript instead of reading as one more
   grey block in the stack. */
.ai-window .aiw-draft {
  border: 1px solid var(--aiw-line);
  border-radius: 9px;
  background: var(--aiw-raise-2);
  overflow: hidden;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 12px 28px -14px rgba(0, 0, 0, 0.85);
}
.ai-window .aiw-draft-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--aiw-line-soft);
}
.ai-window .aiw-draft-to {
  font-size: 11.5px;
  color: var(--aiw-ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ai-window .aiw-draft-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--aiw-line);
  color: var(--aiw-ink-2);
  padding: 2px 7px;
  border-radius: 5px;
  font-size: 10.5px;
  white-space: nowrap;
  flex-shrink: 0;
}
.ai-window .aiw-draft-body {
  padding: 12px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--aiw-ink);
}
.ai-window .aiw-draft-actions {
  padding: 0 12px 12px;
  display: flex;
  gap: 8px;
}
.ai-window .aiw-draft-btn {
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  height: 28px;
  padding: 0 12px;
  border-radius: 7px;
  border: 1px solid var(--aiw-line);
  background: transparent;
  color: var(--aiw-ink-2);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.15s ease, color 0.15s ease;
}
.ai-window .aiw-draft-btn:hover {
  background: var(--aiw-raise-2);
  color: var(--aiw-ink);
}
/* Rule 5: the one action that matters is monochrome, near-white on
   dark. No brand hue anywhere in this window. */
.ai-window .aiw-draft-btn.is-primary {
  background: #e9eaeb;
  color: #0b0c0d;
  border-color: #e9eaeb;
}
.ai-window .aiw-draft-btn.is-primary:hover { background: #ffffff; }

/* ============================================================
   Composer
   ============================================================ */
.ai-window .aiw-composer {
  flex-shrink: 0;
  padding: 0 14px 14px;
}
.ai-window .aiw-composer-inner {
  background: var(--aiw-raise);
  border: 1px solid var(--aiw-line);
  border-radius: 11px;
  padding: 7px 7px 7px 11px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--aiw-ink-3);
  min-height: 40px;
}
.ai-window .aiw-composer-ph {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ai-window .aiw-kbd {
  font-size: 10.5px;
  color: var(--aiw-ink-3);
  border: 1px solid var(--aiw-line);
  border-radius: 4px;
  padding: 2px 5px;
  white-space: nowrap;
  flex-shrink: 0;
}
.ai-window .aiw-send {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 0;
  padding: 0;
  flex-shrink: 0;
  background: var(--aiw-raise-2);
  color: var(--aiw-ink-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

/* ============================================================
   Reveal — every scripted step starts hidden and is switched on
   by /js/embeds/ai-window.js in the order written in the markup.

   A hidden step is taken OUT OF FLOW, not just made transparent.
   A transparent step still reserves its full height, so from the
   first frame the pane laid out the whole finished conversation as
   empty ground: measured, ~400px of black between the newest
   message and the composer for most of the loop. Nothing in a real
   client looks like that — a thread is exactly as tall as what has
   been said. Removing unplayed steps from flow means the thread
   grows as it streams, which is also the only way the bottom
   anchor on `.aiw-messages` can work.

   Restoring `display` per type is the cost of that: the value has
   to come back to the one the element was designed with, because
   `display` cannot be transitioned. The entry motion is therefore
   an animation rather than a transition — an animation runs when
   an element becomes rendered, a transition does not.
   ============================================================ */
.ai-window [data-aiw-step] { display: none; }

.ai-window .aiw-msg-user[data-aiw-step].is-in,
.ai-window .aiw-msg-assistant[data-aiw-step].is-in,
.ai-window .aiw-tool.is-in { display: flex; }
.ai-window .aiw-item.is-in { display: grid; }
.ai-window .aiw-intro.is-in,
.ai-window .aiw-draft.is-in { display: block; }

@media (prefers-reduced-motion: no-preference) {
  .ai-window [data-aiw-step].is-in {
    animation: aiw-step-in 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
}
@keyframes aiw-step-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* Between 720px and 1000px the pane is not wide enough to hold a
   772px measure and a 244px rail at once, and the rail is the part
   the visitor can do without: drop it and give the width back to
   the transcript. */
@media (max-width: 1000px) {
  .ai-window .aiw-rail { display: none; }
}

/* ----- Responsive: collapse to the conversation under 720px -----
   At 350px every column costs something the message needs, so the
   pieces that are pure chrome give way: the sidebar, the per-turn
   mark, the contact's number and the keyboard hint. The real
   clients drop the same things on a phone. */
@media (max-width: 720px) {
  .ai-window .aiw-layout {
    grid-template-columns: 1fr;
    height: 520px;
  }
  .ai-window .aiw-side { display: none; }
  .ai-window .aiw-rail { display: none; }
  .ai-window .aiw-main { margin: 0; border: 0; border-radius: 0; }
  .ai-window .aiw-messages { padding: 14px 14px 18px; }
  .ai-window .aiw-header { padding: 0 12px; }
  .ai-window .aiw-msg-user > div { max-width: 82%; }
  .ai-window .aiw-header-tools .aiw-chip--conn { display: none; }
  .ai-window .aiw-composer { padding: 0 12px 12px; }
  .ai-window .aiw-kbd { display: none; }

  .ai-window .aiw-msg-assistant > .aiw-mark { display: none; }

  /* A wrapped tool label leaves the check floating against the
     middle of two lines; pin it to the first one. */
  .ai-window .aiw-tool { align-items: flex-start; }
  .ai-window .aiw-tool-check { margin-top: 2px; }
  .ai-window .aiw-tool .aiw-tool-meta { align-self: flex-end; }

  /* The number wraps the name onto a second line and buys nothing
     the name and the timestamp do not already say. */
  .ai-window .aiw-item-phone { display: none; }
}
