/* Composer — the auto-growing input itself lives in
   components/chat_composer.css (.chat-composer-input /
   .chat-composer-editor). Buttons pin to the bottom edge so they keep
   their natural height while the field grows. */
.chat-composer {
  align-items: flex-end;
}

/* Chat bubble — scoped styles for markdown content in chat messages */

/* Task list checkboxes */
.chat-bubble .task-list-item {
  list-style: none;
  margin-left: -1.5rem;
}

.chat-bubble .task-list-inline {
  display: flex;
  align-items: baseline;
  gap: 0;
  margin: 0;
  cursor: default;
}

.chat-bubble .task-list-checkbox {
  margin-right: 0.4em;
  vertical-align: middle;
  accent-color: var(--traqx-blue-600, #026CFF);
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

/* Markdown tables inside the chat bubble — without explicit styling
   the browser default has no borders, so columns blur into each
   other on tables without padding. */
.chat-bubble .chat-bubble-body table {
  width: 100%;
  margin: 0.5em 0 1em;
  border-collapse: collapse;
  font-size: 0.95em;
}

.chat-bubble .chat-bubble-body th,
.chat-bubble .chat-bubble-body td {
  padding: 0.4em 0.6em;
  border: 1px solid var(--tblr-border-color, #e6e7e9);
  text-align: left;
  vertical-align: top;
}

.chat-bubble .chat-bubble-body th {
  background: var(--tblr-bg-surface-secondary, #f6f8fa);
  font-weight: 600;
}

/* Inline citation badges */
.chat-bubble .citation {
  display: inline;
  padding: 0.1em 0.4em;
  font-size: 0.8em;
  font-weight: 500;
  color: var(--traqx-blue-600, #026CFF);
  background-color: var(--traqx-blue-50, #F0F7FF);
  border: 1px solid var(--traqx-blue-200, #CCE0FF);
  border-radius: 4px;
  cursor: pointer;
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
  transition: background-color 120ms ease, border-color 120ms ease;
}

.chat-bubble .citation[data-chunk-id]:hover,
.chat-bubble .citation[data-document-id]:hover {
  background-color: var(--traqx-blue-100, #DBEBFF);
  border-color: var(--traqx-blue-300, #99C2FF);
}

.chat-bubble .citation::before {
  content: "📄 ";
  font-size: 0.85em;
}

/* Source-list variant: rendered as a full-width row inside the
   "Quellen" details on assistant bubbles. Reuses .citation so the
   Stimulus controller still picks it up for hover-preview and
   click-to-source, but visually presents as a list item rather
   than an inline pill. */
.chat-bubble .citation.citation--source-item {
  display: flex;
  align-items: center;
  gap: 0.2rem;
  width: 100%;
  margin: 0.15rem 0;
  padding: 0.3rem 0.5rem;
  text-align: left;
  font-size: 0.85em;
  font-weight: normal;
  color: var(--tblr-body-color, #1f2d3d);
  background-color: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
}

.chat-bubble .citation.citation--source-item:hover,
.chat-bubble .citation.citation--source-item[data-chunk-id]:hover,
.chat-bubble .citation.citation--source-item[data-document-id]:hover {
  background-color: var(--traqx-blue-50, #F0F7FF);
  border-color: var(--traqx-blue-200, #CCE0FF);
}

.chat-bubble .citation.citation--source-item::before {
  content: none;
}

.citation--source-item-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Citation hover-preview popover. Positioned via JS (citation_controller). */
.citation-popover {
  position: absolute;
  z-index: 1080;
  max-width: 360px;
  min-width: 240px;
  padding: 0.6rem 0.75rem;
  background: var(--tblr-bg-surface, #fff);
  color: var(--tblr-body-color, #1f2d3d);
  border: 1px solid var(--tblr-border-color, #e6e7e9);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
  font-size: 0.85em;
  line-height: 1.45;
  pointer-events: auto;
}

.citation-popover[hidden] {
  display: none;
}

.citation-popover-loading,
.citation-popover-error {
  font-style: italic;
  color: var(--tblr-secondary, #6b7280);
}

.citation-preview-header {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
  margin-bottom: 0.4rem;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--tblr-border-color-translucent, #e6e7e9);
  font-size: 0.85em;
}

.citation-preview-kb {
  color: var(--traqx-blue-600, #026CFF);
  font-weight: 500;
}

.citation-preview-doc {
  font-weight: 500;
}

.citation-preview-heading {
  font-weight: normal;
}

.citation-preview-body {
  word-break: break-word;
  color: var(--tblr-body-color, #1f2d3d);
  max-height: 240px;
  overflow-y: auto;
}

/* Compact markdown styles inside the popover. The chunk text is
   sliced to ~500 chars but may still bring headings, lists, tables
   along — keep them readable but small. */
.citation-preview-body > :first-child { margin-top: 0; }
.citation-preview-body > :last-child  { margin-bottom: 0; }

.citation-preview-body p,
.citation-preview-body ul,
.citation-preview-body ol,
.citation-preview-body blockquote,
.citation-preview-body pre,
.citation-preview-body table {
  margin: 0 0 0.5em;
}

.citation-preview-body h1,
.citation-preview-body h2,
.citation-preview-body h3,
.citation-preview-body h4,
.citation-preview-body h5,
.citation-preview-body h6 {
  margin: 0.4em 0 0.25em;
  font-size: 0.95em;
  font-weight: 600;
  line-height: 1.3;
}

.citation-preview-body ul,
.citation-preview-body ol {
  padding-left: 1.25em;
}

.citation-preview-body li + li { margin-top: 0.15em; }

.citation-preview-body code {
  padding: 0.1em 0.3em;
  background: var(--tblr-bg-surface-secondary, #f6f8fa);
  border-radius: 3px;
  font-size: 0.9em;
}

.citation-preview-body pre {
  padding: 0.4em 0.6em;
  background: var(--tblr-bg-surface-secondary, #f6f8fa);
  border-radius: 4px;
  font-size: 0.85em;
  overflow-x: auto;
}

.citation-preview-body pre code {
  padding: 0;
  background: transparent;
}

.citation-preview-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9em;
}

.citation-preview-body th,
.citation-preview-body td {
  padding: 0.25em 0.5em;
  border: 1px solid var(--tblr-border-color, #e6e7e9);
  text-align: left;
  vertical-align: top;
}

.citation-preview-body blockquote {
  padding-left: 0.75em;
  border-left: 3px solid var(--tblr-border-color, #e6e7e9);
  color: var(--tblr-secondary, #6b7280);
}

/* Side-panel (Offcanvas) — click-to-source.
   Bootstrap drives offcanvas width via the --bs-offcanvas-width custom
   property; setting `width:` directly loses to `.offcanvas.offcanvas-end`
   in some Tabler builds. Override the variable instead. */
.offcanvas.citation-source-panel,
.citation-source-panel {
  --bs-offcanvas-width: min(820px, 92vw);
  width: min(820px, 92vw);
  max-width: 92vw;
}

/* The Turbo Frame wraps both header and body so a single response
   fills the panel. Bootstrap's offcanvas uses `display: flex;
   flex-direction: column` and expects header + body as direct flex
   children — the frame in between would break that and the body
   would never get its `flex-grow: 1; overflow-y: auto` shape. We
   make the frame transparent to layout so its children inherit the
   parent's flex slots. */
.citation-source-panel > turbo-frame {
  display: contents;
}

/* The breadcrumb + open-document button live inside the offcanvas
   header (slotted there by the citation Stimulus controller) so they
   stay visible while the user scrolls the chunks below.

   Layout: a 2-row meta block on the left, the close-X stays
   centered on the right (Bootstrap default). Row 1 has the document
   name + button; row 2 has the KB and section heading as a small
   secondary line. */
.citation-source-panel-header {
  align-items: center;
  gap: 0.75rem;
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}

.citation-source-panel-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.citation-source-meta-primary {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
}

.citation-source-meta-primary .citation-source-doc {
  flex: 1;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.citation-source-meta-primary .citation-source-doc strong {
  overflow: hidden;
  text-overflow: ellipsis;
}

.citation-source-meta-primary .citation-source-actions {
  flex-shrink: 0;
}

.citation-source-meta-secondary {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  font-size: 0.8em;
  line-height: 1.4;
}

.citation-source-meta-secondary .citation-source-kb {
  color: var(--traqx-blue-600, #026CFF);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
}

.citation-source-sep {
  color: var(--tblr-secondary, #6b7280);
}

.citation-source-chunk {
  padding: 0.4rem 0.6rem;
  margin: 0 0 0.85rem;
  border-radius: 0;
  border: 0;
  color: var(--tblr-secondary, #6b7280);
  background: transparent;
  scroll-margin-top: 1rem;
}

.citation-source-chunk:first-child {
  padding-top: 0;
}

.citation-source-chunk:last-child {
  margin-bottom: 0;
}

/* Textmarker-Optik für den Ziel-Chunk. Der gelbe Streifen liegt als
   ::before-Layer unter dem Text (z-index -1) statt als Block-Background,
   damit wir ihn leicht schräg drehen, mit unregelmäßigen Ecken
   versehen und horizontal etwas einrücken können — fühlt sich an wie
   ein echter, von Hand gezogener Marker statt wie eine eckige Karte. */
.citation-source-chunk--target {
  position: relative;
  z-index: 0;
  color: var(--tblr-body-color, #1f2d3d);
  background: transparent;
  box-shadow: none;
}

.citation-source-chunk--target::before {
  content: "";
  position: absolute;
  inset: 0.15rem 0.5rem;
  z-index: -1;
  background-image: linear-gradient(
    100deg,
    rgba(255, 235, 59, 0) 0%,
    rgba(255, 235, 59, 0.5) 3%,
    rgba(255, 235, 59, 0.6) 50%,
    rgba(255, 235, 59, 0.5) 97%,
    rgba(255, 235, 59, 0) 100%
  );
  transform: rotate(-0.3deg);
  /* Leicht unregelmäßige Ecken — wirkt nicht wie ein Rechteck. */
  border-radius: 2px 5px 3px 4px;
  pointer-events: none;
}

.citation-source-chunk-heading {
  margin-bottom: 0.35rem;
  font-weight: 500;
}

.citation-source-chunk-body {
  word-break: break-word;
}

.citation-source-chunk-body > :first-child { margin-top: 0; }
.citation-source-chunk-body > :last-child  { margin-bottom: 0; }

.citation-source-chunk-body p,
.citation-source-chunk-body ul,
.citation-source-chunk-body ol,
.citation-source-chunk-body blockquote,
.citation-source-chunk-body pre,
.citation-source-chunk-body table {
  margin: 0 0 0.6em;
}

.citation-source-chunk-body h1,
.citation-source-chunk-body h2,
.citation-source-chunk-body h3,
.citation-source-chunk-body h4,
.citation-source-chunk-body h5,
.citation-source-chunk-body h6 {
  margin: 0.5em 0 0.3em;
  font-size: 1em;
  font-weight: 600;
}

.citation-source-chunk-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9em;
}

.citation-source-chunk-body th,
.citation-source-chunk-body td {
  padding: 0.3em 0.5em;
  border: 1px solid var(--tblr-border-color, #e6e7e9);
  text-align: left;
  vertical-align: top;
}

.citation-source-empty {
  padding: 1rem 0;
  text-align: center;
}

/* Full-document viewer typography. Scoped to `.citation-document` so
   it doesn't leak into the side-panel partial (which reuses the same
   `.citation-source-chunk-body` markup but in a much smaller box). */
.citation-document {
  font-size: 1rem;
  line-height: 1.7;
  color: var(--tblr-body-color, #1f2d3d);
}

.citation-document .citation-source-chunk {
  padding: 0.25rem 1rem;
  margin: 0 0 1.75rem;
  /* Page header sits above the chunk on full-page navigation;
     leave room so the anchored chunk lands below it after scroll. */
  scroll-margin-top: 5rem;
}

.citation-document .citation-source-chunk:last-child {
  margin-bottom: 0;
}

/* Per-chunk section heading (from the chunker's `heading` metadata).
   Shown as the dominant level in the document view because the
   chunker stripped the `#`/`##` level information at extract time. */
.citation-document-chunk-heading {
  margin: 0 0 0.5rem;
  padding-bottom: 0.3rem;
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--tblr-body-color, #1f2d3d);
  border-bottom: 1px solid var(--tblr-border-color, #e6e7e9);
}

/* Sub-headings inside the chunk content (from markdown `##`, `###`, …)
   get a clear visual hierarchy. Override the compact panel-context
   styles inherited via `.citation-source-chunk-body`. */
.citation-document .citation-source-chunk-body h1,
.citation-document .citation-source-chunk-body h2,
.citation-document .citation-source-chunk-body h3,
.citation-document .citation-source-chunk-body h4,
.citation-document .citation-source-chunk-body h5,
.citation-document .citation-source-chunk-body h6 {
  font-weight: 600;
  line-height: 1.3;
  color: var(--tblr-body-color, #1f2d3d);
}

.citation-document .citation-source-chunk-body h1 {
  font-size: 1.5rem;
  margin: 1.4rem 0 0.7rem;
}

.citation-document .citation-source-chunk-body h2 {
  font-size: 1.25rem;
  margin: 1.2rem 0 0.6rem;
}

.citation-document .citation-source-chunk-body h3 {
  font-size: 1.1rem;
  margin: 1rem 0 0.5rem;
}

.citation-document .citation-source-chunk-body h4 {
  font-size: 1rem;
  margin: 0.85rem 0 0.4rem;
}

.citation-document .citation-source-chunk-body h5 {
  font-size: 0.95rem;
  margin: 0.75rem 0 0.35rem;
  color: var(--tblr-secondary, #6b7280);
}

.citation-document .citation-source-chunk-body h6 {
  font-size: 0.85rem;
  margin: 0.7rem 0 0.3rem;
  color: var(--tblr-secondary, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.citation-document .citation-source-chunk-body p {
  margin: 0 0 0.85em;
}

.citation-document .citation-source-chunk-body ul,
.citation-document .citation-source-chunk-body ol {
  margin: 0 0 0.85em;
  padding-left: 1.6em;
}

.citation-document .citation-source-chunk-body li + li {
  margin-top: 0.25em;
}

.citation-document .citation-source-chunk-body blockquote {
  margin: 0 0 1em;
  padding: 0.5em 0.9em;
  border-left: 3px solid var(--traqx-blue-300, #99C2FF);
  background: var(--traqx-blue-50, #F0F7FF);
  color: var(--tblr-body-color, #1f2d3d);
}

.citation-document .citation-source-chunk-body table {
  width: 100%;
  margin: 0 0 1em;
  border-collapse: collapse;
}

.citation-document .citation-source-chunk-body th,
.citation-document .citation-source-chunk-body td {
  padding: 0.4em 0.6em;
  border: 1px solid var(--tblr-border-color, #e6e7e9);
  text-align: left;
  vertical-align: top;
}

.citation-document .citation-source-chunk-body th {
  background: var(--tblr-bg-surface-secondary, #f6f8fa);
  font-weight: 600;
}

.citation-document .citation-source-chunk-body code {
  padding: 0.1em 0.35em;
  background: var(--tblr-bg-surface-secondary, #f6f8fa);
  border-radius: 3px;
  font-size: 0.92em;
}

.citation-document .citation-source-chunk-body pre {
  padding: 0.75em 1em;
  margin: 0 0 1em;
  background: var(--tblr-bg-surface-secondary, #f6f8fa);
  border-radius: 4px;
  font-size: 0.92em;
  overflow-x: auto;
}

.citation-document .citation-source-chunk-body pre code {
  padding: 0;
  background: transparent;
}

/* The streaming bubble's date slot shows a small activity spinner
   while the turn runs (sized here, not inline — FE-8). */
.chat-bubble .chat-bubble-date .spinner-border {
  width: 0.8rem;
  height: 0.8rem;
}

/* Transient status ticker shown during tool calls before first token arrives */
.chat-bubble .chat-bubble-status {
  font-size: 0.85em;
  font-style: italic;
  color: var(--tblr-secondary, #6b7280);
  opacity: 0.85;
  margin-bottom: 0.25rem;
  display: flex;
  align-items: center;
  gap: 0.4em;
}

/* The base class sets display:flex, which beats the UA's [hidden]
   rule — restore the attribute's meaning (visibility rides `hidden`,
   toggled by chat--status-ticker; FE-4). */
.chat-bubble .chat-bubble-status[hidden] {
  display: none;
}

.chat-bubble .chat-bubble-status::before {
  content: "";
  width: 0.6em;
  height: 0.6em;
  border-radius: 50%;
  background: var(--traqx-blue-400, #4D9AFF);
  animation: chat-status-pulse 1.2s ease-in-out infinite;
  flex-shrink: 0;
}

@keyframes chat-status-pulse {
  0%, 100% { opacity: 0.3; }
  50%      { opacity: 1; }
}

/* Approval bubble — disclosure card attached to its assistant turn.
   Pending state opens by default; decided states collapse to a one-line
   summary, click to expand for audit/details. */
.approval-bubble-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.approval-bubble {
  border: 1px solid var(--tblr-border-color, #e6e7e9);
  border-radius: 0.5rem;
  background: var(--tblr-bg-surface-secondary, #fafbfc);
  overflow: hidden;
  position: relative;
}

/* Bootstrap's `.accordion-item:first-of-type` / `:last-of-type` rules
   set per-corner radii using the Tabler `--bs-accordion-border-radius`
   variable, which on a stand-alone item leaves the corners square.
   Pin them back to our 0.5rem so single-bubble cards have a visible
   round. Doesn't apply inside `.approval-accordion` because the
   accordion wrapper handles the rounding via clip. */
.accordion-item.approval-bubble:first-of-type {
  border-top-left-radius: 0.5rem;
  border-top-right-radius: 0.5rem;
}

.accordion-item.approval-bubble:last-of-type {
  border-bottom-left-radius: 0.5rem;
  border-bottom-right-radius: 0.5rem;
}

.approval-bubble__impact-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1.25rem;
  height: 1.25rem;
}

.approval-bubble[open] {
  background: #fff;
}

/* Tabler accordion wrap when an assistant turn produced 2+ approval
   bubbles. Without this they'd render as separate cards with a
   visible gap between them — the accordion glues them into one
   visual unit with one outer frame + thin separators between items,
   and each item still keeps its pending/decided/etc. colour cue
   via the `.approval-bubble--<status>` modifiers. */
.approval-accordion {
  border: 1px solid var(--tblr-border-color, #e6e7e9);
  border-radius: 0.5rem;
  overflow: hidden;
}

/* Inside the accordion, the per-bubble outer card border falls
   away (the accordion wrapper draws it once, and a thin top-border
   on each non-first item separates them). Border-radius too —
   only the wrapper's corners should round. The status tint still
   shows because it lives on background/box-shadow, not on the
   border. */
.approval-accordion .accordion-item.approval-bubble {
  border-color: transparent;
  border-radius: 0;
}

/* Each bubble is wrapped in its own `<turbo-frame>` (so approve /
   reject can target it individually), which means the
   accordion-item siblings aren't actually direct DOM siblings —
   their `<turbo-frame>` parents are. Hang the separator off the
   frames themselves. `display: block` because `<turbo-frame>` is
   inline by default. */
.approval-accordion > turbo-frame {
  display: block;
}

.approval-accordion > turbo-frame + turbo-frame {
  border-top: 1px solid var(--tblr-border-color, #e6e7e9);
}

/* We render our own chevron in `.accordion-button-toggle` (Tabler's
   icon-variant pattern), so the default Bootstrap `::after`
   chevron has to disappear on every approval-bubble accordion
   button. */
.approval-bubble .accordion-button::after {
  display: none !important;
}

/* Tighten Bootstrap's default 1rem 1.25rem accordion padding —
   approval bubbles are inline chat cards, not a page-level FAQ.
   Also drop the active-state colour swap so the pending halo
   reads cleanly through. */
.approval-bubble .accordion-button {
  padding: 0.375rem 0.625rem;
  background: transparent;
  box-shadow: none;
  font-size: 0.875rem;
  line-height: 1.3;
  color: inherit;
  gap: 0.5rem;
}

.approval-bubble .accordion-button:not(.collapsed) {
  background: transparent;
  box-shadow: none;
  color: inherit;
}

/* The Tabler icon-variant wrappers come with their own margin /
   sizing defaults (designed for full-page FAQ accordions). Pull
   them in for the inline chat-bubble use case. */
.approval-bubble .accordion-button-icon,
.approval-bubble .accordion-button-toggle {
  flex-shrink: 0;
  margin: 0;
  width: 1.125rem;
  height: 1.125rem;
}

.approval-bubble .accordion-button-icon .icon,
.approval-bubble .accordion-button-toggle .icon {
  width: 1.125rem;
  height: 1.125rem;
}

.approval-bubble .accordion-body {
  padding: 0.375rem 0.625rem 0.625rem;
}

/* The status badge is in a flex container — pin it from stretching
   vertically and keep it tabular-nice. */
.approval-bubble .accordion-button .badge {
  flex-shrink: 0;
  align-self: center;
  font-size: 0.7rem;
  padding: 0.2rem 0.5rem;
}

/* Pending header is non-collapsible — no chevron rendered, button
   reads as a static heading. */
.approval-bubble .accordion-button--locked {
  cursor: default;
  pointer-events: none;
}

/* Pending = action required. Subtle yellow tint + soft pulsing halo
   so the user sees at a glance that this card wants attention, without
   being noisy enough to feel like an alert. */
.approval-bubble--pending {
  background: rgba(245, 159, 0, 0.05);
  box-shadow: 0 0 0 1px rgba(245, 159, 0, 0.18), 0 1px 2px rgba(0, 0, 0, 0.04);
  animation: approval-bubble-pulse 2.4s ease-in-out infinite;
}

.approval-bubble--pending[open] {
  background: rgba(245, 159, 0, 0.04);
}

.approval-bubble--pending .approval-bubble__title {
  font-weight: 600;
}

@keyframes approval-bubble-pulse {
  0%, 100% { box-shadow: 0 0 0 1px rgba(245, 159, 0, 0.18), 0 1px 2px rgba(0, 0, 0, 0.04); }
  50%      { box-shadow: 0 0 0 3px rgba(245, 159, 0, 0.28), 0 1px 4px rgba(245, 159, 0, 0.12); }
}

@media (prefers-reduced-motion: reduce) {
  .approval-bubble--pending { animation: none; }
}

.approval-bubble--rejected,
.approval-bubble--expired,
.approval-bubble--cancelled {
  opacity: 0.85;
}

/* Optimistic in-between state: the user just clicked Approve / Reject,
   the POST is in flight, the server hasn't replaced the bubble yet.
   Stops the pending pulse, locks the action buttons (Stimulus
   handles `disabled`), and runs a sweep-bar across the top edge so
   the card visibly registers the click. */
.approval-bubble--deciding {
  animation: none;
  position: relative;
  overflow: hidden;
}

.approval-bubble--deciding .approval-bubble__actions button {
  cursor: wait;
}

.approval-bubble--deciding::before {
  content: "";
  position: absolute;
  top: 0;
  left: -30%;
  width: 30%;
  height: 2px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(2, 108, 255, 0.7) 50%,
    transparent
  );
  animation: approval-bubble-progress 1.4s ease-in-out infinite;
}

@keyframes approval-bubble-progress {
  0%   { left: -30%; }
  100% { left: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .approval-bubble--deciding::before {
    animation: none;
    left: 0;
    width: 100%;
    opacity: 0.5;
  }
}

.approval-bubble__title {
  font-weight: 500;
  flex: 1;
  text-align: left;
  color: var(--tblr-body-color, #232e3c);
}

.approval-bubble__detail {
  margin-bottom: 0.5rem;
  font-size: 0.8125rem;
}

.approval-bubble__meta {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

/* Action buttons sit immediately under the description — no
   separator line; the body itself is one card-section. */
.approval-bubble__actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.approval-bubble__actions .btn {
  display: inline-flex;
  align-items: center;
}

.approval-bubble__actions .btn-primary {
  font-weight: 500;
}

.approval-bubble__actions form {
  margin: 0;
}

.approval-bubble__footer {
  font-size: 0.75rem;
}

/* In normal flow below the card content — it used to float
   absolutely in the body's bottom-right corner, which overlapped the
   Approve/Reject row whenever that was the last content. */
.approval-bubble__id {
  display: block;
  margin-block-start: 0.5rem;
  text-align: end;
  font-size: 9px;
  color: var(--tblr-text-muted, #94a3b8);
  background: transparent;
  border: 0;
  padding: 0;
  font-family: var(--tblr-font-monospace);
  user-select: all;
  opacity: 0.6;
}

.approval-bubble__id:hover {
  opacity: 1;
}
