/* ── Markdown in assistant bubbles ───────────────────────────────────────────
   chat-markdown.js builds the assistant reply as DOM nodes (p, h1-h6, ul/ol/li, strong, em, code,
   br, blockquote), so these rules are the whole visual treatment: the CSP allows no inline styles,
   and the renderer carries no classes of its own, so everything is scoped through .chat-bubble
   descendant selectors and cannot reach a p or code elsewhere in the page.

   Both surfaces that mount the chat pane load this sheet: the Studio shell (studio.css) and the
   classic /sandbox/chat page (site.css). The pane is one partial driven by one module, so the
   markdown it emits gets one set of layout rules rather than a copy per stylesheet that can drift
   into two different readings of the same reply.

   Layout is shared; theme is not, because the two hosts sit on opposite surfaces. The colour
   declarations read named custom properties a host may map to its own palette, and fall back to
   values that stay legible on a light surface when it maps nothing.

   The type scale stays inside the bubble's own voice: headings are section labels within a chat
   message, not page headings, so every level renders small and bold, the top three a fraction above
   the bubble's own text and the deeper three at its size and muted. That fraction is relative for the
   same reason the colours are custom properties: the two hosts set the bubble's text at different
   sizes, so a heading given a fixed size lands under the base size on one of them and stands the
   ladder on its head, rendering an h4 larger than an h1. Every level belongs to one of the two
   treatments, which is what keeps the ladder whole as the sheet gains rules. Inline code sizes
   relatively for the same reason: a fixed size that reads as code on the smaller host reads as
   shrunken on the larger one. Every size in this sheet is relative to the bubble, and a new rule
   giving one a pixel value reintroduces the split. The bubble itself keeps
   pre-wrap for plain-text messages (visitor turns, error notices); the parser emits no newline
   characters inside its nodes (soft breaks are <br>), so pre-wrap adds nothing twice. */
.chat-bubble p, .chat-bubble ul, .chat-bubble ol,
.chat-bubble h1, .chat-bubble h2, .chat-bubble h3,
.chat-bubble h4, .chat-bubble h5, .chat-bubble h6,
.chat-bubble blockquote { margin: 0; font-size: inherit; }
.chat-bubble > :not(:first-child) { margin-top: 7px; }
.chat-bubble h1, .chat-bubble h2, .chat-bubble h3,
.chat-bubble h4, .chat-bubble h5, .chat-bubble h6 { font-weight: 700; line-height: 1.35; }
.chat-bubble h1, .chat-bubble h2, .chat-bubble h3 { font-size: 1.08em; }
.chat-bubble h4, .chat-bubble h5, .chat-bubble h6 { color: var(--chat-md-heading-muted, #6B7280); }
.chat-bubble ul, .chat-bubble ol { padding-left: 18px; }
.chat-bubble li + li { margin-top: 3px; }
.chat-bubble code {
  font-family: var(--mono, "Cascadia Code", "Consolas", ui-monospace, monospace); font-size: 0.9em;
  background: var(--chat-md-code-bg, rgba(0,0,0,0.06)); border-radius: 4px; padding: 1px 4px;
  overflow-wrap: anywhere;
}
.chat-bubble blockquote {
  padding-left: 0.75em; border-left: 0.15em solid var(--chat-md-quote-border, #D1D5DB);
  color: var(--chat-md-quote-text, #6B7280);
}
