/* Per-element typography for `<MessageMarkdown>` output. Co-located with the
   component so every consumer (ChatPanel assistant/system messages,
   FileViewer markdown preview, MarkdownAttachmentCard, etc.) inherits the
   same rendering. Surface-specific layout (padding, max-width, background,
   role variants) lives in each consumer's own module.

   Selectors take the form `.body :where(<element>)` — specificity (0,1,0).
   That:
   - beats global element resets in `styles/theme.css` (e.g. `h1` at 0,0,1)
     by class specificity, regardless of CSS-bundle ordering;
   - deterministically loses to host-surface overrides such as
     `.previewBody h1` (DiffViewer, 0,1,1) or `.planContent h1`
     (PlanApprovalCard, 0,1,1) — the wrapped descendant pseudo-class drops
     the descendant element's contribution to zero, so consumer rules win
     on specificity rather than relying on import order. */

.body {
  /* Base font-size / line-height / color are deliberately not set here so
   * each consumer surface (ChatPanel `.content`, FileViewer `.markdownBody`,
   * DiffViewer `.previewBody`, PlanApprovalCard `.planContent`, etc.) can
   * pick its own scale. The markdown rules below use `em`-relative sizes
   * so they scale with whatever font-size is inherited from the surface. */
  word-break: break-word;
}

/* Collapse the wrapper's first/last-child margins so consumer rules like
 * `.markdownBody > :first-child { margin-top: 0 }` (FileViewer,
 * MessageAttachment) keep working — without this, the new `.body` div sat
 * between the surface class and the markdown's first/last element, leaving
 * the actual markdown root with its full default top/bottom margin. */
.body > :first-child {
  margin-top: 0;
}

.body > :last-child {
  margin-bottom: 0;
}

/* Headings */
.body :where(h1) {
  font-size: 1.5em;
  font-weight: 700;
  color: var(--text-primary);
  margin: 20px 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(var(--accent-primary-rgb), 0.15);
}

.body :where(h2) {
  font-size: 1.25em;
  font-weight: 700;
  color: var(--text-primary);
  margin: 18px 0 8px;
}

.body :where(h3) {
  font-size: 1.1em;
  font-weight: 600;
  color: var(--accent-primary);
  margin: 14px 0 6px;
}

.body :where(h4, h5, h6) {
  font-size: 1em;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 12px 0 4px;
}

/* Bold text */
.body :where(strong) {
  font-weight: 600;
  color: var(--text-primary);
}

/* Italic */
.body :where(em) {
  color: var(--text-muted);
  font-style: italic;
}

/* Code blocks — Claudette palette + Shiki token coloring (theme.css).
   No `!important` on the background: Shiki's HTML lands inside the `<code>`
   we construct via `dangerouslySetInnerHTML` (token spans, not the outer
   `<pre>`), so nothing inline is fighting this rule. Keeping it as plain
   declaration lets surface-specific overrides like PlanApprovalCard's
   `.planContent pre { background: var(--overlay-bg); }` win on the
   cascade. */
.body :where(pre) {
  position: relative;
  background: var(--chat-input-bg);
  border: 1px solid var(--divider);
  border-top: 2px solid rgba(var(--accent-primary-rgb), 0.2);
  border-radius: 8px;
  padding: 14px 16px;
  overflow: hidden;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  font-size: 13px;
  font-family: var(--font-mono);
  line-height: 1.55;
  margin: 12px 0;
  cursor: text;
  -webkit-user-select: none;
  user-select: none;
}

.body :where(pre code) {
  background: none !important;
  color: inherit;
  padding: 0 !important;
  font-size: inherit;
  -webkit-user-select: text;
  user-select: text;
  display: block;
  width: fit-content;
  max-width: 100%;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

/* Inline code — accent tint */
.body :where(code) {
  background: rgba(var(--accent-primary-rgb), 0.08);
  color: var(--accent-dim);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 0.88em;
  font-family: var(--font-mono);
}

.body :where(p) {
  margin: 6px 0;
}

.body :where(p:first-child) {
  margin-top: 0;
}

.body :where(p:last-child) {
  margin-bottom: 0;
}

/* Lists — colored markers */
.body :where(ul, ol) {
  margin: 8px 0;
  padding-left: 22px;
}

.body :where(ul) {
  list-style: none;
}

.body :where(ul > li) {
  position: relative;
  padding-left: 4px;
}

.body :where(ul > li)::before {
  content: "▸";
  position: absolute;
  left: -16px;
  color: var(--accent-dim);
  font-size: 12px;
}

.body :where(ol) {
  list-style: none;
  counter-reset: ol-counter;
}

.body :where(ol > li) {
  position: relative;
  padding-left: 4px;
  counter-increment: ol-counter;
}

.body :where(ol > li)::before {
  content: counter(ol-counter) ".";
  position: absolute;
  left: -22px;
  width: 18px;
  text-align: right;
  color: var(--accent-dim);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.body :where(li) {
  margin: 3px 0;
}

/* Nested lists — dimmer markers */
.body :where(li ul > li)::before {
  content: "·";
  color: var(--text-faint);
  font-size: 16px;
  font-weight: 700;
}

/* Links */
.body :where(a) {
  color: var(--accent-primary);
  text-decoration: none;
  border-bottom: 1px solid rgba(var(--accent-primary-rgb), 0.25);
  transition: border-color var(--transition-fast);
}

.body :where(a:hover) {
  border-color: var(--accent-primary);
}

.body :where(img) {
  max-width: 100%;
}

.body :where(img:not([height])) {
  height: auto;
}

/* WebKit can report no intrinsic size for SVGs that rely only on a viewBox
   when they are loaded through an <img>. Give those markdown previews a
   visible floor while still letting normal width/height attributes win. */
.body :global(img.cc-markdown-image-svg) {
  min-width: min(480px, 100%);
  min-height: min(240px, 50vh);
  object-fit: contain;
}

/* Horizontal rules */
.body :where(hr) {
  border: none;
  height: 1px;
  background: var(--accent-bg-strong);
  margin: var(--space-4) 0;
}

/* Claude Code callout blocks (★ Insight, ⚠ Warning, etc.) */
.body :where(:global(.cc-callout)) {
  background: var(--chat-system-bg);
  border: 1px solid var(--accent-bg-strong);
  border-left: 3px solid var(--accent-primary);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  padding: var(--space-3) var(--space-4);
  margin: var(--space-4) 0;
  box-shadow: var(--shadow-sm);
}

.body :where(:global(.cc-callout) p) {
  margin: 4px 0;
  color: var(--text-primary);
}

.body :where(:global(.cc-callout) code) {
  background: rgba(var(--accent-primary-rgb), 0.1);
  color: var(--accent-primary);
}

.body :where(:global(.cc-callout-header)) {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--accent-primary);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding-bottom: 8px;
  margin: 0 0 10px;
  border-bottom: 1px solid rgba(var(--accent-primary-rgb), 0.2);
}

.body :where(:global(.cc-callout-icon)) {
  font-size: 15px;
  filter: drop-shadow(0 0 4px rgba(var(--accent-primary-rgb), 0.5));
}

/* Standalone header (no wrapping callout container) */
.body > :where(:global(.cc-callout-header)) {
  color: var(--accent-primary);
  margin: 16px 0 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(var(--accent-primary-rgb), 0.2);
}

.body :where(:global(hr.cc-callout-rule)) {
  border: none;
  border-top: 1px solid rgba(var(--accent-primary-rgb), 0.15);
  margin: 8px 0 16px;
}

/* File-path autolinks injected by `rehypeFilePathLinks`. Subtle, non-loud
   styling — the link should be discoverable on hover but not draw attention
   away from the prose around it. The path text itself is monospace (matching
   how Claude usually writes paths) so the click target reads as
   path-shaped rather than as a generic link. */
.body :where(:global(.cc-file-path-link)) {
  color: var(--text-primary);
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  font-family: var(--font-mono, ui-monospace, monospace);
  line-height: inherit;
  text-decoration: underline;
  text-decoration-color: rgba(var(--accent-primary-rgb), 0.35);
  text-underline-offset: 2px;
  cursor: pointer;
  word-break: break-all;
}

.body :where(:global(.cc-file-path-link:hover)) {
  color: var(--accent-primary);
  text-decoration-color: currentColor;
}

/* Blockquotes — subtle card with left accent */
.body :where(blockquote) {
  border-left: 2px solid var(--text-faint);
  background: var(--hover-bg-subtle);
  border-radius: 0 6px 6px 0;
  margin: 10px 0;
  padding: 8px 14px;
  color: var(--text-muted);
  font-style: italic;
}

.body :where(blockquote p) {
  margin: 2px 0;
}

/* Tables — accent header, alternating rows */
.body :where(table) {
  border-collapse: collapse;
  margin: 12px 0;
  font-size: 13px;
  width: 100%;
  border: 1px solid var(--divider);
  border-radius: 8px;
  overflow: hidden;
}

.body :where(th) {
  background: rgba(var(--accent-primary-rgb), 0.06);
  color: var(--accent-primary);
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 8px 12px;
  text-align: left;
  border-bottom: 1px solid rgba(var(--accent-primary-rgb), 0.12);
}

.body :where(td) {
  padding: 7px 12px;
  text-align: left;
  border-bottom: 1px solid var(--divider);
}

.body :where(tr:nth-child(even) td) {
  background: var(--hover-bg-subtle);
}

.body :where(tr:last-child td) {
  border-bottom: none;
}

/* Inline code inside table cells */
.body :where(td code) {
  font-size: 0.85em;
  padding: 2px 6px;
  white-space: nowrap;
}

/* Wide tables get horizontal scroll. `:global()` because authors reach this
 * via raw HTML `<div class="table-wrapper">…</div>` (rehypeRaw is enabled);
 * a non-global selector here would be CSS-Module-mangled and never match
 * the literal class name in their markup. */
.body :where(:global(.table-wrapper)) {
  overflow-x: auto;
  margin: 12px 0;
}
