/* ───────────────────────────────────────────────────────────────
 * <agent-chat-panel> — shared styles for every chat surface.
 *
 * The component renders a `.agent-chat-host` root with one of two
 * `agent-chat-host--<layout>` modifiers:
 *
 *   --floating       fixed-position FAB + anchored panel
 *   --rail           small chip inside another sidebar; panel slides out
 *
 * (`embedded` is a third layout used only inside agent deploy cards;
 * it renders inline and has no special selectors here.)
 *
 * Class prefix is configurable via the panel's `class-prefix` attribute
 * (defaults to `agent-chat`). All selectors below use the prefix
 * literally — consumers that need a separate visual identity should
 * scope a sibling stylesheet instead of switching the prefix.
 * ─────────────────────────────────────────────────────────────── */

/* Custom elements default to display: inline — without an explicit
   block rule the element has zero size, which made the embedded
   panel look empty (its inner .agent-chat-host couldn't grow inside
   a zero-size custom-element ancestor). */
agent-chat-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}

.agent-chat-host {
  --agent-accent: var(--color-accent-primary, #818cf8);
  --agent-accent-text: #f8fafc;
  --agent-bg: var(--color-surface, #0f172a);
  --agent-bg-elev: var(--color-surface-elevated, #1e293b);
  --agent-bg-muted: var(--color-surface-muted, #334155);
  --agent-border: var(--color-border, #334155);
  --agent-text: var(--color-text, #f1f5f9);
  --agent-text-muted: var(--color-text-muted, #94a3b8);
  --agent-danger: var(--color-danger, #ef4444);
  --agent-success: var(--color-success, #22c55e);
}

/* ─── Floating FAB ──────────────────────────────────────────── */

.agent-chat-host--floating {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9000;
}

.agent-chat-host--floating > * {
  pointer-events: auto;
}

/* Floating FAB — frosted-glass disc with accent-tinted glow.
   Mirrors the canonical look ported from the per-agent chat-fab and
   the platform-agent panel: a 3.5rem disc with a `.agent-chat-fab-
   glass` ::before-style backdrop-blur layer underneath the icon, an
   accent-tint inset shadow + outer drop shadow, and a snappy
   cubic-bezier bounce on hover/active. */
.agent-chat-fab {
  position: fixed;
  width: 3.5rem;
  height: 3.5rem;
  padding: 0;
  border-radius: 50%;
  background: transparent;
  color: color-mix(in srgb, var(--agent-accent) 80%, white);
  border: 1px solid color-mix(in srgb, var(--agent-accent) 60%, transparent);
  cursor: grab;
  box-shadow:
    0 8px 22px rgba(0, 0, 0, 0.45),
    0 0 0 1px color-mix(in srgb, var(--agent-accent) 25%, transparent) inset;
  display: grid;
  place-items: center;
  z-index: 1000;
  /* left/top ease so the FAB GLIDES when something else is driving it
     (a panel drag pushing it around, a viewport dodge) instead of
     teleporting. "--agent-glide" is set per frame by the panel, scaled
     to how far the solver moved it. "is-dragging" drops the easing for
     the surface under the pointer so a direct drag tracks the cursor
     exactly. */
  transition:
    transform   0.18s cubic-bezier(.2, .7, .3, 1.4),
    box-shadow  0.18s ease,
    border-color 0.18s ease,
    left        var(--agent-glide, 0.12s) ease-out,
    top         var(--agent-glide, 0.12s) ease-out;
  touch-action: none;
  user-select: none;
  /* Keeps the glass layer's backdrop-blur inside this stacking ctx so
     it doesn't bleed over sibling FABs at high z-index. */
  isolation: isolate;
}

.agent-chat-fab-glass {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  /* Layered as: accent-tinted highlight up top, faint accent wash
     for body color, then a very light fill of surface-elevated. The
     backdrop-blur is what carries the look — keep the fills thin so
     the workspace beneath stays visible. Previous values (`45%`
     elev, `22%` accent) read as nearly-opaque discs and lost the
     frosted feel users were asking for. */
  background:
    radial-gradient(at 30% 22%,
      color-mix(in srgb, var(--agent-accent) 35%, transparent),
      transparent 65%),
    color-mix(in srgb, var(--agent-accent) 10%, transparent),
    color-mix(in srgb, var(--agent-bg-elev) 18%, transparent);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  z-index: 0;
  pointer-events: none;
}

@supports not (backdrop-filter: blur(1px)) {
  /* No backdrop-filter support — fall back to a thicker fill so the
     icon stays legible without the blur to lean on. */
  .agent-chat-fab-glass {
    background:
      radial-gradient(at 30% 22%,
        color-mix(in srgb, var(--agent-accent) 40%, transparent),
        transparent 65%),
      color-mix(in srgb, var(--agent-bg-elev) 70%, transparent);
    opacity: 0.92;
  }
}

.agent-chat-fab > app-icon,
.agent-chat-fab > .agent-chat-fab-logo {
  position: relative;
  z-index: 1;
  display: flex;
  color: color-mix(in srgb, var(--agent-accent) 95%, white);
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45));
}

.agent-chat-fab > app-icon {
  width: 1.5rem;
  height: 1.5rem;
}

.agent-chat-fab > .agent-chat-fab-logo {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  object-fit: cover;
}

.agent-chat-fab:hover {
  transform: translateY(-2px) scale(1.04);
  border-color: var(--agent-accent);
  box-shadow:
    0 12px 28px rgba(0, 0, 0, 0.55),
    0 0 0 1px color-mix(in srgb, var(--agent-accent) 45%, transparent) inset,
    0 0 18px color-mix(in srgb, var(--agent-accent) 35%, transparent);
}

.agent-chat-fab:active {
  transform: translateY(-1px) scale(0.97);
}

/* Rail-docked chip — small rounded-square (1.7rem) that lives inline
   in the sidebar's `.sidebar-agents-rail` wrapper. The agent's logo
   (or chat-bubble fallback) fills 75% of the chip so the brand reads
   at a glance; accent-tinted background + border lets multiple chips
   distinguish themselves without overpowering the sidebar palette.
   No frosted glass here — the chip is small enough that the glass
   recipe just looks muddy. */
.agent-chat-rail-fab {
  position: relative;
  flex-shrink: 0;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--agent-accent) 18%, transparent);
  color: var(--agent-accent-text);
  border: 1px solid color-mix(in srgb, var(--agent-accent) 55%, transparent);
  border-radius: 0.45rem;
  cursor: pointer;
  font: inherit;
  isolation: isolate;
  transition:
    transform   0.18s cubic-bezier(.2, .7, .3, 1.4),
    background  0.18s ease,
    border-color 0.18s ease,
    box-shadow  0.18s ease;
  touch-action: none;
  user-select: none;
}

/* The rail chip suppresses the frosted-glass layer (it's the same
   element class as the floating FAB so the shared markup keeps
   working, but at 1.7rem the blur looks like dirt). */
.agent-chat-rail-fab > .agent-chat-fab-glass { display: none; }

.agent-chat-rail-fab > .agent-chat-fab-logo {
  width: 75%;
  height: 75%;
  border-radius: 0.2rem;
  object-fit: contain;
  /* No drop-shadow — at 1.7rem the 2px-blur shadow paints a visible
     dark sliver below the logo that reads as a tooltip artifact. The
     floating FAB keeps its drop-shadow because it's larger and the
     extra depth helps it pop off the canvas; rail chips don't need
     the depth cue (the rail itself is the visual anchor). */
}

.agent-chat-rail-fab > app-icon {
  width: 75%;
  height: 75%;
  color: var(--agent-accent);
}

.agent-chat-rail-fab:hover {
  transform: translateY(-1px) scale(1.04);
  background: color-mix(in srgb, var(--agent-accent) 28%, transparent);
  border-color: var(--agent-accent);
  box-shadow: 0 0 14px color-mix(in srgb, var(--agent-accent) 30%, transparent);
}

.agent-chat-rail-fab.open {
  background: color-mix(in srgb, var(--agent-accent) 32%, transparent);
  border-color: var(--agent-accent);
  box-shadow:
    0 0 14px color-mix(in srgb, var(--agent-accent) 40%, transparent),
    inset 0 0 0 1px var(--agent-accent);
}

/* Instant macOS-style tooltips for the lower-right dock. We bypass the
   browser's native title-attribute delay (~1.5s) — the dock is meant
   to be glanceable, and a delayed label defeats the point of pinning
   things here. The selector keys off `data-tooltip` on anything inside
   the rail, so future dock items just opt in by setting the attribute
   (no class plumbing). Position anchors to the LEFT of the item because
   the dock sits on the right edge of the viewport; rightward growth
   would clip off-screen.

   The ::before paints the label pill; the ::after paints the small
   triangular caret pointing at the item. Both pseudo-elements are
   non-interactive (`pointer-events: none`) so they never steal a
   pointerdown that opens a chat panel or runs an item's action. */
.docked-agents-rail [data-tooltip] {
  position: relative;
}

.docked-agents-rail [data-tooltip]::before,
.docked-agents-rail [data-tooltip]::after {
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.08s ease;
}

.docked-agents-rail [data-tooltip]::before {
  content: attr(data-tooltip);
  position: absolute;
  right: calc(100% + 0.55rem);
  top: 50%;
  transform: translateY(-50%);
  padding: 0.3rem 0.55rem;
  background: var(--color-surface-elevated, #1e293b);
  color: var(--color-text, #f1f5f9);
  border: 1px solid color-mix(in srgb, var(--color-border, #475569) 80%, transparent);
  border-radius: 0.35rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  /* Tooltip needs to escape the rail container's stacking context so
     it paints over the chat panel when the dock has both. */
  z-index: 10;
}

.docked-agents-rail [data-tooltip]::after {
  content: '';
  position: absolute;
  right: calc(100% + 0.15rem);
  top: 50%;
  transform: translateY(-50%);
  /* `box-sizing: border-box` (set globally on *::after) + a default
     auto-computed width was rendering this as a 24x16 dark rectangle
     instead of the intended CSS-triangle. Force the box to 0x0,
     content-box, transparent background so only the borders paint —
     the standard triangle trick. Same fix applied to every tooltip
     ::after below. */
  width: 0;
  height: 0;
  box-sizing: content-box;
  background: transparent;
  border: 4px solid transparent;
  border-left-color: var(--color-surface-elevated, #1e293b);
  z-index: 10;
}

.docked-agents-rail [data-tooltip]:hover::before,
.docked-agents-rail [data-tooltip]:hover::after,
.docked-agents-rail [data-tooltip]:focus-visible::before,
.docked-agents-rail [data-tooltip]:focus-visible::after {
  opacity: 1;
}

/* Same instant-tooltip pattern for the floating agent-chat FABs and
   rail chips that live OUTSIDE `.docked-agents-rail` — e.g. an
   undocked agent's bottom-right floating button. Without this, the
   floating FAB used to render `title="Open …"` and the browser's
   native delayed (~1.5s) tooltip would paint as a "shadow tooltip"
   alongside the chip's instant one. Switched the title to
   `data-tooltip` and key the same pseudo-element pill off it here. */
/* No `position: relative` override here — the base rules already
   establish positioning contexts (`position: fixed` on
   `.agent-chat-fab`, `position: relative` on `.agent-chat-rail-fab`),
   both of which serve as containing blocks for absolutely-positioned
   pseudo-elements. An earlier version set `position: relative` on the
   floating FAB and stripped its `position: fixed`, hiding all the
   detached-window FABs from the viewport (they laid out in normal
   flow inside whatever ancestor was the closest layout box). */
.agent-chat-fab[data-tooltip]::before,
.agent-chat-fab[data-tooltip]::after,
.agent-chat-rail-fab[data-tooltip]::before,
.agent-chat-rail-fab[data-tooltip]::after {
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.08s ease;
}
.agent-chat-fab[data-tooltip]::before,
.agent-chat-rail-fab[data-tooltip]::before {
  content: attr(data-tooltip);
  position: absolute;
  right: calc(100% + 0.55rem);
  top: 50%;
  transform: translateY(-50%);
  padding: 0.3rem 0.55rem;
  background: var(--color-surface-elevated, #1e293b);
  color: var(--color-text, #f1f5f9);
  border: 1px solid color-mix(in srgb, var(--color-border, #475569) 80%, transparent);
  border-radius: 0.35rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  z-index: 10;
}
.agent-chat-fab[data-tooltip]::after,
.agent-chat-rail-fab[data-tooltip]::after {
  content: '';
  position: absolute;
  right: calc(100% + 0.15rem);
  top: 50%;
  transform: translateY(-50%);
  width: 0;
  height: 0;
  box-sizing: content-box;
  background: transparent;
  border: 4px solid transparent;
  border-left-color: var(--color-surface-elevated, #1e293b);
  z-index: 10;
}
.agent-chat-fab[data-tooltip]:hover::before,
.agent-chat-fab[data-tooltip]:hover::after,
.agent-chat-fab[data-tooltip]:focus-visible::before,
.agent-chat-fab[data-tooltip]:focus-visible::after,
.agent-chat-rail-fab[data-tooltip]:hover::before,
.agent-chat-rail-fab[data-tooltip]:hover::after,
.agent-chat-rail-fab[data-tooltip]:focus-visible::before,
.agent-chat-rail-fab[data-tooltip]:focus-visible::after {
  opacity: 1;
}

/* ─── Panel chrome (shared by all layouts) ─────────────────── */

/* Frosted-glass background. Same recipe as the `.agent-chat-fab-glass`
   layer (faint accent wash + surface fill + backdrop-filter), but
   tinted DARKER so the message transcript stays legible — readable
   text needs more opaque body than a small icon disc does.
   The accent tint hints at the agent's brand color through the
   surface so multiple open panels for different agents stay
   visually distinct. */
.agent-chat-panel {
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(at 30% 22%,
      color-mix(in srgb, var(--agent-accent) 12%, transparent),
      transparent 70%),
    color-mix(in srgb, var(--agent-accent) 6%, transparent),
    color-mix(in srgb, var(--agent-bg) 78%, transparent);
  border: 1px solid color-mix(in srgb, var(--agent-accent) 28%, var(--agent-border));
  border-radius: 0.75rem;
  box-shadow:
    0 18px 40px rgba(0, 0, 0, 0.45),
    0 0 22px color-mix(in srgb, var(--agent-accent) 14%, transparent);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  overflow: hidden;
  color: var(--agent-text);
  font-family: var(--font-family);
}

@supports not (backdrop-filter: blur(1px)) {
  /* Browsers without backdrop-filter — fall back to a thicker fill
     so the panel doesn't look semi-transparent over a busy workspace
     with no blur to lean on. */
  .agent-chat-panel {
    background: var(--agent-bg);
  }
}

.agent-chat-panel--floating {
  position: fixed;
  /* JS owns the size (it clamps to both the resize minimums and the
     viewport) — a CSS minimum here would win over the inline width on a
     window too small to honour it and push the panel off-screen. */
  min-width: 0;
  min-height: 0;
  resize: none; /* handles below own this */
  transition:
    left var(--agent-glide, 0.12s) ease-out,
    top  var(--agent-glide, 0.12s) ease-out;
}

/* The surface under the pointer is pinned to the cursor: no easing, or
   the drag reads as laggy. Its partner keeps the transition and follows. */
.agent-chat-fab.is-dragging,
.agent-chat-panel--floating.is-dragging {
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .agent-chat-fab,
  .agent-chat-panel--floating {
    transition: none;
  }
}

.agent-chat-panel--rail {
  position: fixed;
  /* Slide-out from the sidebar's right edge; the rail chip lives at
     ~64–88 px from the left, so this puts the panel just outside the
     sidebar without overlapping any chip badges. */
  left: 200px;
  top: 80px;
  width: 380px;
  height: 540px;
  z-index: 9000;
}

/* ─── Embedded layout ───────────────────────────────────────────────
 *
 * Used by the sidebar's docked-tabset surface. No FAB, no fixed
 * positioning — the panel chrome fills whatever container it's
 * dropped into. The host (`.sidebar-docked-agent`) handles the actual
 * size + slide-out behaviour.
 */
.agent-chat-host--embedded {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
}

.agent-chat-host--embedded .agent-chat-panel {
  position: static;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: 100%;
  border-radius: 0;
  box-shadow: none;
  border: none;
  /* Parent `.docked-agents-panel` already paints the frosted-glass
     background. Suppress the panel's own glass here so we don't
     blur on top of a blur (Chromium does technically allow nested
     backdrop-filter, but the result reads as muddy + the bound box
     of an inner filter clips at the dock panel's edge anyway). */
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ─── Docked-agents bar (lower-right dock) ──────────────────────────
 *
 * Lower-right vertical chip rail + optional pop-out panel. Replaces
 * the previous sidebar-rail integration; sits at fixed position so
 * it's reachable from anywhere on the workspace. Mirrors Foyer
 * Studio's right-dock recipe — chip rail on the right edge, panel
 * slides out to its LEFT with a frosted-dark-glass surface.
 */
docked-agents-bar {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 9000;
  pointer-events: none;
  /* The element itself doesn't lay out; .docked-agents-bar inside it
     is the actual flex container. */
}
docked-agents-bar > .docked-agents-bar {
  display: flex;
  flex-direction: row;
  align-items: flex-end;
  gap: 0.5rem;
  pointer-events: auto;
}

.docked-agents-rail {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.4rem;
  background: color-mix(in srgb, var(--color-surface, #0f172a) 65%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-border, #475569) 50%, transparent);
  border-radius: 0.6rem;
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}

/* Drop-zone hint shown while a floating FAB is being dragged AND the
   bar would otherwise be empty (no chips, no active panel). Gives
   the user something to drop onto on first dock. */
.docked-agents-drop-hint {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  width: 4rem;
  height: 4rem;
  padding: 0.5rem;
  border: 2px dashed color-mix(in srgb, var(--color-accent-primary, #818cf8) 60%, transparent);
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--color-accent-primary, #818cf8) 8%, transparent);
  color: color-mix(in srgb, var(--color-accent-primary, #818cf8) 80%, white);
  font-size: 0.625rem;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Drop-target highlight: paints an accent ring around the whole bar
   when the cursor is hovering over it mid-drag. The bar element
   itself reflects the attribute so the outline encompasses both
   the chip rail + the active panel (if any). */
docked-agents-bar[drop-target] > .docked-agents-bar {
  outline: 2px solid var(--color-accent-primary, #818cf8);
  outline-offset: 6px;
  border-radius: 0.75rem;
}
docked-agents-bar[drop-target] .docked-agents-drop-hint {
  background: color-mix(in srgb, var(--color-accent-primary, #818cf8) 20%, transparent);
  border-color: var(--color-accent-primary, #818cf8);
  color: var(--color-text, #f1f5f9);
}

.docked-agents-panel {
  /* Width / height are written inline by <docked-agents-bar> from
     localStorage (`pai.docked-panel.size.v1`). The fallbacks here are
     only used when the JS hasn't applied its inline style yet — they
     also have to match DEFAULT_DOCKED_W / DEFAULT_DOCKED_H in
     docked-agents-bar.js so first-paint matches first-script-paint. */
  width: 380px;
  height: 480px;
  position: relative;
  display: flex;
  flex-direction: column;
  background: color-mix(in srgb, var(--color-surface, #0f172a) 78%, transparent);
  border: 1px solid color-mix(in srgb, var(--agent-accent, var(--color-accent-primary, #818cf8)) 35%, var(--color-border, #475569));
  border-radius: 0.75rem;
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.55),
    0 0 22px color-mix(in srgb, var(--agent-accent, var(--color-accent-primary, #818cf8)) 18%, transparent);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  overflow: hidden;
  color: var(--color-text, #f1f5f9);
  font-family: var(--font-family);
}

/* Resize handles on the docked pop-out (left edge + left corners only).
   Same visual idiom as .agent-chat-resize but scoped to the docked
   wrapper so the chrome doesn't leak into floating mode. */
.docked-agents-resize {
  position: absolute;
  background: transparent;
  z-index: 5;
}
.docked-agents-resize--w  { left: -3px;   top: 12px;     bottom: 12px;  width: 6px;   cursor: w-resize;  }
.docked-agents-resize--nw { left: -3px;   top: -3px;                    width: 12px; height: 12px; cursor: nw-resize; }
.docked-agents-resize--sw { left: -3px;   bottom: -3px;                 width: 12px; height: 12px; cursor: sw-resize; }

.docked-agents-panel-titlebar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid color-mix(in srgb, var(--color-border, #475569) 50%, transparent);
  background: color-mix(in srgb, var(--color-surface-elevated, #1e293b) 60%, transparent);
  cursor: grab;
  user-select: none;
  font-size: 0.875rem;
}

.docked-agents-panel-titlebar:active { cursor: grabbing; }

.docked-agents-panel-titlebar > strong {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.docked-agents-panel-titlebar > small {
  color: var(--color-text-muted, #94a3b8);
  font-size: 0.6875rem;
  flex-shrink: 0;
}

.docked-agents-panel-icon {
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 0.25rem;
}

.docked-agents-panel-undock {
  appearance: none;
  background: none;
  border: none;
  width: 24px;
  height: 24px;
  border-radius: 0.375rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted, #94a3b8);
  cursor: pointer;
  flex-shrink: 0;
}
.docked-agents-panel-undock:hover {
  background: color-mix(in srgb, var(--color-text, #f1f5f9) 12%, transparent);
  color: var(--color-text, #f1f5f9);
}

/* The shared agent-chat-panel renders its panel chrome inside this
   region. It expects to fill its parent in embedded layout. */
.docked-agents-panel > agent-chat-panel {
  flex: 1;
  min-height: 0;
}
.docked-agents-panel .agent-chat-host--embedded {
  /* The panel's own header is the title bar in embedded mode — it
     carries the icon, label, and session controls (new chat, history,
     settings, debug, undock). */
  background: transparent;
}
.docked-agents-panel .agent-chat-host--embedded .agent-chat-panel {
  background: transparent;
  border: none;
  border-radius: 0;
}

/* ─── Header ───────────────────────────────────────────────── */

.agent-chat-header {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 0.75rem;
  background: var(--agent-bg-elev);
  border-bottom: 1px solid var(--agent-border);
  cursor: grab;
  user-select: none;
}

.agent-chat-panel--rail .agent-chat-header {
  cursor: default;
}

.agent-chat-header-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  flex-shrink: 0;
}

.agent-chat-header-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  font-size: 0.875rem;
  line-height: 1.2;
}

.agent-chat-header-text small {
  color: var(--agent-text-muted);
  font-size: 0.6875rem;
}

.agent-chat-header-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.125rem;
}

.agent-chat-icon-btn {
  appearance: none;
  background: none;
  border: none;
  width: 28px;
  height: 28px;
  border-radius: 0.375rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--agent-text-muted);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.agent-chat-icon-btn:hover {
  background: var(--agent-bg-muted);
  color: var(--agent-text);
}

/* ─── Status banner ─────────────────────────────────────────── */

.agent-chat-banner {
  padding: 0.375rem 0.75rem;
  font-size: 0.75rem;
  text-align: center;
  border-bottom: 1px solid var(--agent-border);
}

.agent-chat-banner--pending     { background: rgba(245, 158, 11, 0.15); color: #fbbf24; }
.agent-chat-banner--unreachable { background: rgba(239, 68, 68, 0.15);  color: #fca5a5; }
.agent-chat-banner--probing     { background: rgba(148, 163, 184, 0.15); color: var(--agent-text-muted); }

/* ─── Transcript ────────────────────────────────────────────── */

.agent-chat-list {
  flex: 1;
  overflow-y: auto;
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  scroll-behavior: auto;
}

.agent-chat-empty {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--agent-text-muted);
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.agent-chat-empty strong { color: var(--agent-text); font-size: 1rem; }
.agent-chat-empty small  { font-size: 0.75rem; }

.agent-chat-msg {
  max-width: 88%;
  padding: 0.5rem 0.75rem;
  border-radius: 0.625rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  word-wrap: break-word;
}

.agent-chat-msg-user {
  align-self: flex-end;
  background: var(--agent-accent);
  color: var(--agent-accent-text);
  white-space: pre-wrap;
}

.agent-chat-msg-user-text {
  display: block;
  margin-bottom: 0.375rem;
}

.agent-chat-msg-user-text:last-child { margin-bottom: 0; }

/* Wrapper used by `renderUserMessage` when a user message carries
   attachments — stacks the text bubble + attachment row vertically,
   right-aligned. Each child sizes to its own content so a 140 px
   thumbnail doesn't ride inside a wide bubble with acres of padding,
   and a short text bubble doesn't get stretched out to match the
   attachment row's width. */
.agent-chat-msg-userwrap {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  align-self: flex-end;
  gap: 0.25rem;
  max-width: 88%;
}
.agent-chat-msg-userwrap > .agent-chat-msg-user {
  /* Defer to the wrap's max-width so the bubble can shrink past the
     normal 88%-of-parent cap when it's the narrower of the two children. */
  max-width: 100%;
}
.agent-chat-msg-userwrap > .agent-chat-msg-attachments {
  margin-top: 0;
}

.agent-chat-msg-assistant {
  align-self: flex-start;
  background: var(--agent-bg-elev);
  border: 1px solid var(--agent-border);
}

.agent-chat-msg-assistant > * + * { margin-top: 0.5rem; }

.agent-chat-msg-error {
  border-color: var(--agent-danger);
  background: color-mix(in srgb, var(--agent-danger) 12%, var(--agent-bg-elev));
}

.agent-chat-msg pre {
  background: rgba(0, 0, 0, 0.3);
  padding: 0.5rem;
  border-radius: 0.375rem;
  overflow-x: auto;
  font-size: 0.75rem;
  margin: 0.375rem 0;
}

.agent-chat-msg code {
  font-size: 0.85em;
  font-family: var(--font-family-mono, monospace);
}

.agent-chat-msg :not(pre) > code {
  padding: 0.1em 0.3em;
  background: rgba(148, 163, 184, 0.15);
  border-radius: 0.25rem;
  /* Model URIs and cluster hostnames are single unbreakable tokens; without
     this they push their container wider than the panel. */
  overflow-wrap: anywhere;
}

/* Markdown tables. The agent answers with them constantly (deploy summaries,
   status rollups) and they carry long single-token values like
   hf://org/model@rev or a .svc.cluster.local URL. Left to browser defaults the
   table sizes to its content and overflows the bubble, clipping the last
   column. Cells wrap those tokens instead, and the table keeps its own
   horizontal scroll for genuinely wide ones rather than widening the panel. */
.agent-chat-msg table {
  display: block;
  width: fit-content;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  margin: 0.5rem 0;
  font-size: 0.8125rem;
}

.agent-chat-msg th,
.agent-chat-msg td {
  border: 1px solid var(--agent-border, rgba(148, 163, 184, 0.25));
  padding: 0.3rem 0.5rem;
  text-align: left;
  vertical-align: top;
  overflow-wrap: anywhere;
}

.agent-chat-msg thead th {
  background: rgba(148, 163, 184, 0.12);
  font-weight: 600;
}

.agent-chat-msg .pai-agent-link {
  color: var(--agent-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

/* Inline external-link glyph appended by lib/markdown.js's `link`
   renderer override. The SVG ships without width/height attributes so
   it inherits from this rule — without it the browser falls back to
   the path bounding box at full pixel scale (huge). Scoped to .agent-chat-msg
   so the icon style applies wherever the shared panel renders chat
   bubbles. */
.agent-chat-msg .pai-agent-link-icon,
.pai-agent-link-icon {
  display: inline-block;
  width: 0.85em;
  height: 0.85em;
  margin-left: 0.15em;
  vertical-align: -0.05em;
  text-decoration: none;
  flex-shrink: 0;
}

/* ─── Thinking block ───────────────────────────────────────── */

.agent-chat-think {
  font-size: 0.75rem;
  color: var(--agent-text-muted);
  border-left: 2px solid var(--agent-border);
  padding-left: 0.5rem;
  align-self: flex-start;
  max-width: 88%;
}

.agent-chat-think summary {
  cursor: pointer;
  user-select: none;
  font-weight: 500;
  padding: 0.125rem 0;
}

.agent-chat-think-content {
  padding: 0.25rem 0 0.25rem 0;
  white-space: pre-wrap;
  opacity: 0.85;
}

/* ─── Tool cards ────────────────────────────────────────────── */

.agent-chat-toolcalls {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  align-self: flex-start;
  max-width: 88%;
  width: 100%;
}

.agent-chat-toolcard {
  background: rgba(139, 92, 246, 0.08);
  border: 1px solid rgba(139, 92, 246, 0.3);
  border-radius: 0.5rem;
  font-size: 0.75rem;
  overflow: hidden;
}

/* Only a failure earns colour. A completed call is the normal case, so it keeps
   the base card and the transcript stops reading as a string of lights. */
.agent-chat-toolcard--error { border-color: var(--agent-danger); background: color-mix(in srgb, var(--agent-danger) 8%, transparent); }

.agent-chat-toolcard summary {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.375rem 0.5rem;
  cursor: pointer;
  user-select: none;
}

.agent-chat-toolcard-name { font-weight: 600; }
.agent-chat-toolcard-summary {
  flex: 1;
  color: var(--agent-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.agent-chat-toolcard-badge {
  display: inline-flex;
  align-items: center;
  color: var(--agent-text-muted);
}
.agent-chat-toolcard--running .agent-chat-toolcard-badge { color: var(--agent-accent); }
.agent-chat-toolcard--error   .agent-chat-toolcard-badge { color: var(--agent-danger); }
.agent-chat-toolcard--running .agent-chat-toolcard-badge app-icon {
  animation: agent-chat-toolcard-spin 1.4s linear infinite;
}
@keyframes agent-chat-toolcard-spin { to { transform: rotate(360deg); } }

.agent-chat-toolcard-status {
  font-size: 0.6875rem;
  color: var(--agent-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.agent-chat-toolcard-body {
  padding: 0.5rem;
  border-top: 1px solid var(--agent-border);
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.agent-chat-toolcard-label {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--agent-text-muted);
}
.agent-chat-toolcard-block {
  background: rgba(0, 0, 0, 0.3);
  padding: 0.375rem;
  border-radius: 0.25rem;
  overflow-x: auto;
  margin: 0;
  font-family: var(--font-family-mono, monospace);
  font-size: 0.6875rem;
  white-space: pre-wrap;
}

.agent-chat-toolcard-thumb {
  appearance: none;
  background: none;
  border: 1px solid var(--agent-border);
  border-radius: 0.375rem;
  padding: 0;
  cursor: zoom-in;
  overflow: hidden;
  display: inline-block;
  max-width: 220px;
}
.agent-chat-toolcard-thumb img,
.agent-chat-toolcard-thumb video {
  display: block;
  max-width: 220px;
  max-height: 220px;
  width: auto;
  height: auto;
}
.agent-chat-toolcard-thumb--video { position: relative; }
.agent-chat-toolcard-thumb-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  color: rgba(255, 255, 255, 0.8);
  text-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}
.agent-chat-toolcard-audio { width: 100%; }
.agent-chat-toolcard-file  { color: var(--agent-accent); text-decoration: underline; }

/* ─── Composer / input row ─────────────────────────────────── */

.agent-chat-inputrow {
  position: relative;
  display: flex;
  gap: 0.375rem;
  padding: 0.5rem;
  background: var(--agent-bg-elev);
  border-top: 1px solid var(--agent-border);
}

.agent-chat-inputrow--drop {
  outline: 2px dashed var(--agent-accent);
  outline-offset: -4px;
}

.agent-chat-resize-handle {
  position: absolute;
  top: -3px;
  left: 0;
  right: 0;
  height: 6px;
  cursor: ns-resize;
}

.agent-chat-input {
  flex: 1;
  resize: none;
  background: var(--agent-bg);
  border: 1px solid var(--agent-border);
  border-radius: 0.375rem;
  color: var(--agent-text);
  font-family: inherit;
  font-size: 0.8125rem;
  padding: 0.5rem;
  line-height: 1.4;
  min-height: 38px;
}

.agent-chat-input:focus {
  outline: none;
  border-color: var(--agent-accent);
}

.agent-chat-send {
  appearance: none;
  background: var(--agent-accent);
  color: var(--agent-accent-text);
  border: none;
  border-radius: 0.375rem;
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-end;
  cursor: pointer;
  transition: filter 0.12s ease;
}

.agent-chat-send:hover { filter: brightness(1.1); }
.agent-chat-send:disabled { opacity: 0.5; cursor: not-allowed; }
.agent-chat-send--stop { background: var(--agent-danger); color: white; }

/* ─── Slash-command menu ───────────────────────────────────── */

.agent-chat-slash {
  position: absolute;
  bottom: calc(100% - 0.25rem);
  left: 0.5rem;
  right: 0.5rem;
  z-index: 2;
  max-height: 13rem;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  background: var(--agent-bg-elev);
  border: 1px solid var(--agent-border);
  border-radius: 0.375rem;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
}

.agent-chat-slash-item {
  appearance: none;
  background: none;
  border: none;
  border-radius: 0;
  text-align: left;
  cursor: pointer;
  color: var(--agent-text);
  font-family: inherit;
  font-size: 0.75rem;
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  padding: 0.3125rem 0.5rem;
}

.agent-chat-slash-item--active,
.agent-chat-slash-item:hover {
  background: color-mix(in srgb, var(--agent-accent) 18%, transparent);
}

.agent-chat-slash-name {
  font-weight: 600;
  white-space: nowrap;
}

.agent-chat-slash-hint {
  font-style: italic;
  opacity: 0.65;
  white-space: nowrap;
}

.agent-chat-slash-desc {
  opacity: 0.7;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ─── Attachments (composer chips) ─────────────────────────── */

.agent-chat-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  padding: 0.5rem;
  background: var(--agent-bg-elev);
  border-top: 1px solid var(--agent-border);
}

.agent-chat-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.125rem 0.375rem;
  background: var(--agent-bg);
  border: 1px solid var(--agent-border);
  border-radius: 0.375rem;
  font-size: 0.6875rem;
  max-width: 200px;
}

.agent-chat-chip-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

.agent-chat-chip-thumb {
  appearance: none;
  background: none;
  border: none;
  padding: 0;
  cursor: zoom-in;
  width: 22px;
  height: 22px;
  border-radius: 0.25rem;
  overflow: hidden;
  flex-shrink: 0;
}
.agent-chat-chip-thumb img,
.agent-chat-chip-thumb video {
  width: 22px;
  height: 22px;
  object-fit: cover;
  display: block;
}
.agent-chat-chip-audio { max-width: 140px; }
.agent-chat-chip-icon  { font-size: 1rem; }
.agent-chat-chip-remove {
  appearance: none;
  background: none;
  border: none;
  color: var(--agent-text-muted);
  cursor: pointer;
  padding: 0 0.125rem;
}
.agent-chat-chip-remove:hover { color: var(--agent-danger); }

/* ─── Queued-message banner ───────────────────────────────────
 *
 * Sits above the composer when the user typed + hit Send while the
 * agent was still streaming a turn. Park-and-go UX: the message
 * stages here, the composer empties so the user can keep typing, and
 * the turn's finally hook auto-flushes the queue once the agent goes
 * idle. The Stop & send button trips the abort path so the queue
 * dispatches immediately. Mirrors foyer-studio's queued-banner so
 * the same model behaviour ports across surfaces. */
.agent-chat-queued {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  margin: 0 0 0.375rem;
  background: color-mix(in srgb, var(--agent-accent) 12%, var(--agent-bg-elev));
  border: 1px solid color-mix(in srgb, var(--agent-accent) 40%, var(--agent-border));
  border-radius: 0.5rem;
  font-size: 0.75rem;
  color: var(--agent-text);
}
.agent-chat-queued-body {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.agent-chat-queued-body strong {
  flex-shrink: 0;
  font-weight: 600;
  color: var(--agent-accent);
}
.agent-chat-queued-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: 0.85;
}
.agent-chat-queued-actions {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-shrink: 0;
}
.agent-chat-queued-stop,
.agent-chat-queued-edit,
.agent-chat-queued-discard {
  appearance: none;
  padding: 0.25rem 0.5rem;
  border-radius: 0.35rem;
  font: inherit;
  font-size: 0.7rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.agent-chat-queued-stop {
  background: var(--agent-accent);
  color: var(--agent-accent-text);
  border: 1px solid var(--agent-accent);
  font-weight: 500;
}
.agent-chat-queued-stop:hover {
  background: color-mix(in srgb, var(--agent-accent) 85%, white);
}
.agent-chat-queued-edit {
  background: transparent;
  color: var(--agent-text);
  border: 1px solid var(--agent-border);
}
.agent-chat-queued-edit:hover {
  border-color: var(--agent-accent);
  color: var(--agent-accent);
}
.agent-chat-queued-discard {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  background: transparent;
  color: var(--agent-text-muted);
  border: 1px solid transparent;
}
.agent-chat-queued-discard:hover {
  color: var(--agent-danger);
  border-color: color-mix(in srgb, var(--agent-danger) 40%, transparent);
}

/* Secondary send button that appears next to Stop while the agent is
   busy AND the composer has content. Click → park in the queue banner;
   no destructive interruption. Visually paler than the primary send
   so it doesn't look like "send right now". */
.agent-chat-send--queue {
  opacity: 0.75;
}
.agent-chat-send--queue:hover {
  opacity: 1;
}

/* ─── Message attachments ─────────────────────────────────── */

.agent-chat-msg-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.375rem;
}

.agent-chat-message-attachment {
  appearance: none;
  background: none;
  border: 1px solid var(--agent-border);
  border-radius: 0.375rem;
  padding: 0;
  cursor: zoom-in;
  overflow: hidden;
  display: inline-block;
}
.agent-chat-message-attachment img,
.agent-chat-message-attachment video {
  display: block;
  max-width: 140px;
  max-height: 140px;
  width: auto;
  height: auto;
}
.agent-chat-message-attachment--video { position: relative; }
.agent-chat-message-attachment-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  color: rgba(255, 255, 255, 0.8);
  pointer-events: none;
}
.agent-chat-message-audio { max-width: 200px; }
.agent-chat-message-file {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: var(--agent-accent);
  text-decoration: underline;
  font-size: 0.75rem;
}

/* ─── Zoom modal ───────────────────────────────────────────── */

.agent-chat-zoom-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9500;
  cursor: zoom-out;
}

.agent-chat-zoom-image,
.agent-chat-zoom-video {
  max-width: 92vw;
  max-height: 92vh;
  cursor: default;
}

.agent-chat-zoom-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  appearance: none;
  background: rgba(0, 0, 0, 0.6);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 0.375rem;
  width: 32px;
  height: 32px;
  font-size: 1rem;
  cursor: pointer;
}

/* ─── History overlay ─────────────────────────────────────── */

.agent-chat-history {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: var(--agent-bg);
  overflow: hidden;
}

.agent-chat-history-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--agent-border);
  background: var(--agent-bg-elev);
}

.agent-chat-history-list {
  flex: 1;
  overflow-y: auto;
  padding: 0.25rem;
}

.agent-chat-history-empty {
  padding: 1.5rem;
  text-align: center;
  color: var(--agent-text-muted);
  font-size: 0.875rem;
}

.agent-chat-history-row {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.375rem 0.5rem;
  border-radius: 0.375rem;
  cursor: pointer;
  transition: background 0.12s ease;
}

.agent-chat-history-row:hover { background: var(--agent-bg-muted); }
.agent-chat-history-row--active { background: color-mix(in srgb, var(--agent-accent) 20%, transparent); }

.agent-chat-history-row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
}

.agent-chat-history-row-title {
  font-size: 0.8125rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.agent-chat-history-row-meta {
  font-size: 0.6875rem;
  color: var(--agent-text-muted);
}

.agent-chat-history-row-busy {
  color: var(--agent-accent);
  font-weight: 600;
}

.agent-chat-history-row-input {
  background: var(--agent-bg-elev);
  border: 1px solid var(--agent-accent);
  border-radius: 0.25rem;
  color: var(--agent-text);
  font-size: 0.8125rem;
  padding: 0.125rem 0.25rem;
  width: 100%;
}

.agent-chat-history-row-btn {
  width: 22px;
  height: 22px;
}

.agent-chat-history-new {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin: 0.5rem;
  padding: 0.375rem 0.5rem;
  background: var(--agent-bg-elev);
  border: 1px dashed var(--agent-border);
  border-radius: 0.375rem;
  color: var(--agent-text);
  cursor: pointer;
  font-size: 0.8125rem;
}

.agent-chat-history-new:hover {
  background: var(--agent-bg-muted);
  border-color: var(--agent-accent);
}

/* ─── Resize handles (floating mode only) ─────────────────── */

.agent-chat-resize {
  position: absolute;
  background: transparent;
  z-index: 5;
}
.agent-chat-resize--n  { top: -3px;    left: 12px; right: 12px; height: 6px;  cursor: n-resize;  }
.agent-chat-resize--s  { bottom: -3px; left: 12px; right: 12px; height: 6px;  cursor: s-resize;  }
.agent-chat-resize--e  { right: -3px;  top: 12px;  bottom: 12px; width: 6px;  cursor: e-resize;  }
.agent-chat-resize--w  { left: -3px;   top: 12px;  bottom: 12px; width: 6px;  cursor: w-resize;  }
.agent-chat-resize--nw { top: -3px;    left: -3px;    width: 12px; height: 12px; cursor: nw-resize; }
.agent-chat-resize--ne { top: -3px;    right: -3px;   width: 12px; height: 12px; cursor: ne-resize; }
.agent-chat-resize--sw { bottom: -3px; left: -3px;    width: 12px; height: 12px; cursor: sw-resize; }
.agent-chat-resize--se { bottom: -3px; right: -3px;   width: 12px; height: 12px; cursor: se-resize; }

/* ─── Typing indicator + error ─────────────────────────────── */

.agent-chat-typing {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  font-size: 0.75rem;
  color: var(--agent-text-muted);
  padding: 0.25rem 0.5rem;
}

/* Ring, not dots: an ellipsis reads as punctuation, not progress. */
.agent-chat-throb {
  width: 0.8125rem;
  height: 0.8125rem;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(from 0turn,
    color-mix(in srgb, var(--agent-accent) 10%, transparent),
    var(--agent-accent));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  animation: agent-chat-throb 0.85s linear infinite;
}

@keyframes agent-chat-throb { to { transform: rotate(1turn); } }

.agent-chat-throb-secs {
  font-variant-numeric: tabular-nums;
  opacity: 0.65;
}

/* Still turning, just slowly: a frozen ring reads as a hang. */
@media (prefers-reduced-motion: reduce) {
  .agent-chat-throb { animation-duration: 3s; }
}

.agent-chat-error {
  align-self: stretch;
  background: color-mix(in srgb, var(--agent-danger) 15%, transparent);
  color: var(--agent-danger);
  border-radius: 0.375rem;
  padding: 0.375rem 0.5rem;
  font-size: 0.75rem;
}

/* Attachment landed (a log sent from the log viewer). Two pulses is enough to
   catch the eye without reading as an error state. */
@keyframes agent-chat-flash {
  0%, 100% { box-shadow: 0 0 0 0 transparent; border-color: var(--agent-border); }
  25%, 75% {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--agent-accent) 45%, transparent);
    border-color: var(--agent-accent);
  }
}

.agent-chat-panel--flash {
  animation: agent-chat-flash 1s ease-in-out 2;
}

@media (prefers-reduced-motion: reduce) {
  .agent-chat-panel--flash { animation: none; border-color: var(--agent-accent); }
}
