/* canvas.css — the code canvas (Files tab of the chat workspace panel) plus the
   one token palette that dresses BOTH highlight.js output and canvas.js's own
   fallback highlighter. Loaded by index.html before styles.css (same reason
   live-activity.css is: these are shared with the embed page, and the console's
   later rules keep their precedence) and by embed.html.

   Tokens come from the host page (--line, --code-bg, --muted, …), so the canvas
   follows the app's theme without knowing which app it is in. */

/* ------------------------------------------------------- syntax palette --
   One set of colors for hljs class names, tuned against --code-bg. Light
   values first; the dark overrides follow the host's own theme switches. */
:root {
  --syn-comment: #7c8697;
  --syn-keyword: #a626a4;
  --syn-string: #1a7f37;
  --syn-number: #b45309;
  --syn-title: #1f6feb;
  --syn-type: #b7791f;
  --syn-builtin: #0e7490;
  --syn-attr: #b45309;
  --syn-meta: #6b7280;
  --syn-tag: #cf222e;
  --diff-add: rgba(46, 160, 67, 0.16);
  --diff-del: rgba(207, 34, 46, 0.16);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --syn-comment: #6b7688;
    --syn-keyword: #c678dd;
    --syn-string: #98c379;
    --syn-number: #d19a66;
    --syn-title: #61afef;
    --syn-type: #e5c07b;
    --syn-builtin: #56b6c2;
    --syn-attr: #d19a66;
    --syn-meta: #7f848e;
    --syn-tag: #e06c75;
    --diff-add: rgba(63, 185, 80, 0.18);
    --diff-del: rgba(248, 81, 73, 0.18);
  }
}

:root[data-theme="dark"] {
  --syn-comment: #6b7688;
  --syn-keyword: #c678dd;
  --syn-string: #98c379;
  --syn-number: #d19a66;
  --syn-title: #61afef;
  --syn-type: #e5c07b;
  --syn-builtin: #56b6c2;
  --syn-attr: #d19a66;
  --syn-meta: #7f848e;
  --syn-tag: #e06c75;
  --diff-add: rgba(63, 185, 80, 0.18);
  --diff-del: rgba(248, 81, 73, 0.18);
}

.hljs-comment, .hljs-quote { color: var(--syn-comment); font-style: italic; }
.hljs-keyword, .hljs-selector-tag, .hljs-doctag, .hljs-formula { color: var(--syn-keyword); }
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-symbol, .hljs-bullet { color: var(--syn-string); }
.hljs-number, .hljs-literal { color: var(--syn-number); }
.hljs-title, .hljs-section, .hljs-name, .hljs-selector-id, .hljs-selector-class { color: var(--syn-title); }
.hljs-type, .hljs-class .hljs-title, .hljs-params { color: var(--syn-type); }
.hljs-built_in, .hljs-builtin-name { color: var(--syn-builtin); }
.hljs-attr, .hljs-attribute, .hljs-variable, .hljs-template-variable { color: var(--syn-attr); }
.hljs-meta, .hljs-meta .hljs-keyword { color: var(--syn-meta); }
.hljs-tag { color: var(--syn-tag); }
.hljs-deletion { color: var(--syn-tag); }
.hljs-emphasis { font-style: italic; }
.hljs-strong { font-weight: 600; }

/* --------------------------------------------------- chat code block head --
   markdown.js wraps every fence in .code-block; the head carries the language
   and the two actions that matter on a snippet: take it, or open it properly. */
.code-block {
  margin: 10px 0;
  border: 1px solid var(--line-strong, var(--line));
  border-radius: var(--radius-sm, 6px);
  overflow: hidden;
  background: var(--code-bg);
}

.code-block:last-child { margin-bottom: 0; }

/* The header sits ON the code surface, so every color in it is keyed to
   --code-ink rather than the page's --ink: the embed paints code dark even in
   its light theme, and page-ink hover states would vanish there. */
.code-block-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px 4px 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--code-ink, #888) 14%, transparent);
  background: color-mix(in srgb, var(--code-ink, #888) 7%, transparent);
  color: var(--code-ink);
  font-size: 11px;
}

.code-block-lang {
  color: color-mix(in srgb, var(--code-ink, #888) 60%, transparent);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-right: auto;
  font-weight: 600;
}

.code-block-actions { display: inline-flex; gap: 2px; }

.code-block-actions button {
  border: 0;
  background: transparent;
  color: color-mix(in srgb, var(--code-ink, #888) 72%, transparent);
  font: inherit;
  font-size: 11px;
  padding: 3px 8px;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
  min-height: 0;
}

.code-block-actions button:hover { background: color-mix(in srgb, var(--code-ink, #888) 14%, transparent); color: var(--code-ink); }

.code-block > pre.chat-code {
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* Inline path:line citation chips — the "one click from the code" mechanic.
   These sit in prose, so they tint the PAGE's ink, not the code surface. */
.code-ref {
  display: inline;
  border: 1px solid var(--line-strong, var(--line));
  background: color-mix(in srgb, var(--ink, #888) 7%, transparent);
  color: var(--primary, var(--accent, #0b6f79));
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 0.88em;
  line-height: 1.3;
  padding: 0.05em 0.4em;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
}

.code-ref:hover { border-color: var(--primary, var(--accent, #0b6f79)); }

/* --------------------------------------------------------- workspace tabs -- */
.canvas-tabs {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill, 999px);
  background: var(--surface, transparent);
}

.canvas-tabs button {
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-sm, 12px);
  padding: 3px 11px;
  border-radius: var(--radius-pill, 999px);
  cursor: pointer;
  min-height: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

/* Chrome surfaces tint the host's ink rather than borrowing --code-bg: the
   embed paints code on a dark slab even in its light theme, and an active tab
   in that color reads as a hole in the panel. */
.canvas-tabs button.active { background: color-mix(in srgb, var(--ink) 10%, transparent); color: var(--ink); }
.canvas-tabs .canvas-tab-count {
  font-size: 10px;
  min-width: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent, #0b6f79) 22%, transparent);
  color: var(--ink);
}

/* ------------------------------------------------------------ files pane -- */
.canvas-files {
  display: grid;
  /* The panel is often only ~400 px wide inside the chat workspace, so the
     file list takes a share of it, not a fixed 190 px that would leave the
     editor with nothing. */
  grid-template-columns: minmax(104px, 30%) minmax(0, 1fr);
  min-height: 0;
  height: 100%;
  overflow: hidden;
}

.cf-list {
  border-right: 1px solid var(--line);
  overflow: auto;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.cf-file {
  display: grid;
  /* The file name owns its whole row; the directory, the +/- counts and the
     problem badge share the second. A name is what you scan for, so it never
     competes with a badge for width. */
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas: "name name name" "dir delta badge";
  align-items: center;
  gap: 0 6px;
  text-align: left;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: var(--text-sm, 12px);
  padding: 5px 8px;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
  min-height: 0;
  width: 100%;
}

.cf-file:hover { background: color-mix(in srgb, var(--ink, #888) 8%, transparent); }
.cf-file.active { background: color-mix(in srgb, var(--ink, #888) 12%, transparent); }
.cf-file-name { grid-area: name; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono, monospace); }
.cf-file-dir { grid-area: dir; color: var(--faint, var(--muted)); font-size: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; }
.cf-file-dir:empty { display: none; }
.cf-delta { grid-area: delta; font-size: 10px; font-style: normal; display: inline-flex; gap: 4px; }
.cf-delta .add { color: var(--syn-string); font-style: normal; }
.cf-delta .del { color: var(--syn-tag); font-style: normal; }
.cf-badge { grid-area: badge; font-size: 10px; border-radius: 999px; padding: 0 5px; }
.cf-badge.error { background: color-mix(in srgb, #cf222e 30%, transparent); }
.cf-badge.warn { background: color-mix(in srgb, #b45309 30%, transparent); }

.cf-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.cf-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.cf-bar:empty { display: none; }

.cf-tabs { display: inline-flex; gap: 1px; }
.cf-tabs button {
  border: 0; background: transparent; color: var(--muted); font: inherit; font-size: var(--text-sm, 12px);
  padding: 3px 9px; border-radius: var(--radius-sm, 6px); cursor: pointer; min-height: 0;
}
.cf-tabs button.active { background: color-mix(in srgb, var(--ink, #888) 12%, transparent); color: var(--ink); }
.cf-tabs button[disabled] { opacity: 0.4; cursor: default; }

.cf-lang { color: var(--faint, var(--muted)); font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; margin-right: auto; }

.cf-bar-actions { display: inline-flex; gap: 2px; align-items: center; }
.cf-bar-actions button {
  border: 0; background: transparent; color: var(--muted); font: inherit; font-size: 11px;
  padding: 3px 8px; border-radius: var(--radius-sm, 6px); cursor: pointer; min-height: 0;
  display: inline-flex; align-items: center; gap: 4px;
}
.cf-bar-actions button:hover { background: color-mix(in srgb, var(--ink, #888) 10%, transparent); color: var(--ink); }

.cf-versions {
  position: absolute;
  top: 100%;
  right: 8px;
  z-index: 5;
  min-width: 220px;
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--line-strong, var(--line));
  border-radius: var(--radius, 10px);
  background: var(--surface);
  box-shadow: var(--shadow, 0 6px 20px rgba(0, 0, 0, 0.25));
  padding: 4px;
}

.cf-version { display: flex; align-items: center; gap: 8px; padding: 4px 6px; font-size: var(--text-sm, 12px); }
.cf-version-n { font-family: var(--mono, monospace); }
.cf-version-by { color: var(--muted); margin-right: auto; }
.cf-versions-empty { padding: 8px 10px; color: var(--muted); font-size: var(--text-sm, 12px); }

.cf-stage { position: relative; flex: 1 1 auto; min-height: 0; display: flex; }
.cf-stage > * { flex: 1 1 auto; min-height: 0; min-width: 0; }

/* Both stages set --code-ink explicitly: the editor paints itself onto the
   code surface, and unstyled tokens (punctuation, operators) inherit this
   color — inheriting the page's --ink instead puts black text on the embed's
   dark code slab in its light theme. */
.cf-editor { overflow: hidden; display: flex; background: var(--code-bg); color: var(--code-ink); }
.cf-editor .cm-editor { width: 100%; height: 100%; }
.cf-editor .cm-editor.cm-focused { outline: none; }
.cf-editor .cm-scroller { overflow: auto; }
/* The file is read-only most of the time; a full-width active-line band on an
   unfocused editor reads as a selection that is not there. */
.cf-editor .cm-activeLine { background-color: color-mix(in srgb, var(--code-ink) 6%, transparent); }
.cf-editor .cm-editor:not(.cm-focused) .cm-activeLine { background-color: transparent; }
.cf-editor .cm-selectionBackground,
.cf-editor .cm-content ::selection { background: color-mix(in srgb, var(--accent, #0b6f79) 34%, transparent); }

/* Fallback listing: no CodeMirror on this build, but the same colors. */
.cf-plain {
  display: flex;
  gap: 12px;
  margin: 0;
  padding: 10px 12px;
  overflow: auto;
  width: 100%;
  background: var(--code-bg);
  color: var(--code-ink);
  font: 12px/1.55 var(--mono, ui-monospace, monospace);
}
.cf-plain .cf-nums { color: var(--faint, var(--muted)); text-align: right; user-select: none; white-space: pre; }
.cf-plain code { white-space: pre; }

.cf-diff { overflow: hidden; display: flex; background: var(--code-bg); color: var(--code-ink); }
.cf-diff .cm-editor { width: 100%; height: 100%; }
.cf-diff .cm-activeLine { background-color: transparent; }
.cf-diff-scroll { overflow: auto; width: 100%; }

/* @codemirror/merge ships its own subtle chunk styling; ours makes red and
   green unmistakable at a glance, which is the whole job of a diff. */
.cf-diff .cm-changedLine, .cf-diff .cm-insertedLine { background: var(--diff-add); }
.cf-diff .cm-deletedChunk { background: var(--diff-del); }
.cf-diff .cm-changedText, .cf-diff .cm-insertedText { background: color-mix(in srgb, var(--syn-string) 26%, transparent); }
.cf-diff .cm-deletedChunk .cm-deletedText { background: color-mix(in srgb, var(--syn-tag) 30%, transparent); }
.cf-diff .cm-changedLineGutter { background: var(--diff-add); }

.cf-difftable {
  border-collapse: collapse;
  width: 100%;
  font: 12px/1.5 var(--mono, ui-monospace, monospace);
  color: var(--code-ink);
}
.cf-difftable td { padding: 0 6px; vertical-align: top; white-space: pre; }
.cf-difftable td.n { width: 1%; color: var(--faint, var(--muted)); text-align: right; user-select: none; }
.cf-difftable td.s { width: 1%; color: var(--muted); user-select: none; }
.cf-difftable td.t { width: 100%; }
.cf-difftable tr.add { background: var(--diff-add); }
.cf-difftable tr.del { background: var(--diff-del); }
.cf-difftable tr.cf-hunk td { color: var(--muted); background: color-mix(in srgb, var(--ink, #888) 8%, transparent); padding: 3px 8px; }

/* The preview iframe is sandbox="allow-scripts" WITHOUT allow-same-origin:
   generated pages execute but can never touch this origin. */
.cf-preview { background: #fff; display: flex; }
.cf-frame { width: 100%; height: 100%; border: 0; background: #fff; }

.cf-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 24px;
  text-align: center;
  color: var(--muted);
  font-size: var(--text-sm, 12px);
}

/* A file whose text is not here: on its way, or why it cannot be shown.
   It stands where the editor would, so it is never mistaken for an empty file. */
.cf-status { display: grid; place-items: center; padding: 24px; overflow: auto; }
.cf-loading { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: var(--text-sm, 12px); }
.cf-spinner {
  width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--ink, #888) 18%, transparent);
  border-top-color: var(--muted);
  animation: cf-spin 0.8s linear infinite;
}
@keyframes cf-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cf-spinner { animation: none; } }
.cf-problem { max-width: 380px; text-align: center; font-size: var(--text-sm, 12px); color: var(--muted); }
.cf-problem strong { display: block; color: var(--ink); font-size: var(--text-md, 13px); margin-bottom: 6px; overflow-wrap: anywhere; }
.cf-problem p { margin: 0; line-height: 1.5; overflow-wrap: anywhere; }
.cf-problem-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: 12px; }
.cf-problem-actions button {
  border: 1px solid var(--line-strong, var(--line)); background: transparent; color: var(--ink);
  font: inherit; font-size: 11px; padding: 4px 11px; border-radius: var(--radius-pill, 999px); cursor: pointer; min-height: 0;
}
.cf-problem-actions button:hover { background: color-mix(in srgb, var(--ink, #888) 10%, transparent); }

/* The footer scrolls vertically only: a long test command or failure name must
   ellipsize, never push the whole strip sideways. */
.cf-foot { border-top: 1px solid var(--line); max-height: 42%; overflow-y: auto; overflow-x: hidden; flex: none; }
.cf-foot:empty { display: none; }

.cf-selection {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px;
  border-bottom: 1px solid var(--line); font-size: var(--text-sm, 12px); color: var(--muted);
}
.cf-selection button { margin-left: auto; border: 1px solid var(--line-strong, var(--line)); background: transparent; color: var(--ink); font: inherit; font-size: 11px; padding: 3px 9px; border-radius: var(--radius-pill, 999px); cursor: pointer; min-height: 0; }

.cf-tests { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--line); font-size: var(--text-sm, 12px); }
.cf-tests-head { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.cf-tests.pass .cf-tests-head { color: var(--syn-string); }
.cf-tests.fail .cf-tests-head { color: var(--syn-tag); }
.cf-tests-cmd { color: var(--muted); font-family: var(--mono, monospace); font-size: 11px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-tests-list { display: flex; flex-wrap: wrap; gap: 4px; width: 100%; min-width: 0; }
/* The ellipsis lives on an inner span: Chrome centers (and clips both ends of)
   overflowing text inside a <button>'s anonymous box and ignores
   text-overflow there. */
.cf-test-name {
  border: 1px solid var(--line-strong, var(--line)); background: transparent; color: var(--ink);
  font-family: var(--mono, monospace); font-size: 11px; padding: 2px 7px; border-radius: var(--radius-sm, 6px);
  cursor: pointer; min-height: 0; min-width: 0; flex: 0 1 auto; max-width: 100%;
  overflow: hidden; text-align: left;
}
.cf-test-name span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cf-diags-head { padding: 6px 10px 2px; color: var(--muted); font-size: 11px; }
.cf-diag {
  display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left;
  border: 0; background: transparent; color: var(--ink); font: inherit; font-size: var(--text-sm, 12px);
  padding: 3px 10px; cursor: pointer; min-height: 0;
}
.cf-diag:hover { background: color-mix(in srgb, var(--ink, #888) 8%, transparent); }
.cf-diag-where { font-family: var(--mono, monospace); color: var(--faint, var(--muted)); flex: none; }
.cf-diag-msg { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-diag-src { color: var(--faint, var(--muted)); font-size: 10px; flex: none; }
.cf-diag.error .cf-diag-where { color: var(--syn-tag); }
.cf-diag.warning .cf-diag-where { color: var(--syn-number); }

/* -------------------------------------------------- live terminal strip --
   tool.output chunks under the running tool call. Capped in live-activity.js;
   this only makes it look like a terminal. */
.ls-terminal {
  margin: 6px 0 0;
  padding: 6px 9px;
  max-height: 132px;
  overflow: auto;
  border-radius: var(--radius-sm, 6px);
  background: var(--code-bg);
  color: var(--code-ink);
  font: 11px/1.5 var(--mono, ui-monospace, monospace);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.ls-terminal .stderr { color: var(--syn-tag); }

/* ----------------------------------------------------------- model chip -- */
.router-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--line-strong, var(--line));
  border-radius: var(--radius-pill, 999px);
  padding: 1px 8px;
  font-size: 11px;
  color: var(--muted);
  background: var(--surface, transparent);
  cursor: help;
}

.router-chip strong { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------- narrow / mobile ------- */
@media (max-width: 700px) {
  .canvas-files { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  /* Narrow: the list becomes a horizontal tab strip. One row per file, so the
     name and its counts sit side by side rather than stacked. */
  .cf-list { border-right: 0; border-bottom: 1px solid var(--line); flex-direction: row; overflow-x: auto; overflow-y: hidden; }
  .cf-file { width: auto; flex: none; grid-template-columns: auto auto auto; grid-template-areas: "name delta badge"; }
  .cf-file-name { overflow: visible; }
  .cf-file-dir { display: none; }
}

/* ---- Rich blocks: diagrams and charts drawn in place (rich-blocks.js) ---- */
.rich-block > pre.rich-source { display: none; }
.rich-block.rich-show-source > pre.rich-source,
.rich-block.rich-failed > pre.rich-source,
.rich-block.rich-streaming > pre.rich-source { display: block; }
.rich-block.rich-streaming > .rich-stage,
.rich-block.rich-failed:not(.rich-show-source) > .rich-stage:empty { display: none; }

.rich-stage {
  position: relative;
  padding: 12px 14px 14px;
  background: var(--surface-soft, var(--code-bg));
  border-radius: 0 0 var(--radius, 10px) var(--radius, 10px);
}

.rich-tools {
  position: absolute;
  top: 8px;
  right: 10px;
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 120ms ease-out;
  z-index: 2;
}

.rich-block:hover .rich-tools,
.rich-block:focus-within .rich-tools { opacity: 1; }

.rich-tools button {
  font: 500 11px/1 var(--mono, ui-monospace, monospace);
  padding: 4px 7px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--surface, #fff);
  color: var(--muted);
  cursor: pointer;
}

.rich-tools button:hover { color: var(--ink); border-color: var(--line-strong, var(--line)); }

.rich-diagram {
  overflow: auto;
  max-height: 420px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.rich-diagram.rich-pannable { cursor: grab; }
.rich-diagram.rich-panning { cursor: grabbing; user-select: none; }

.rich-diagram .rich-scaled {
  flex: 0 0 auto;
  width: 100%;
}

.rich-diagram svg,
.rich-diagram img.rich-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* A diagram is drawn as a picture (rich-blocks.js): dragging pans it rather
   than lifting the image out of the page. */
.rich-diagram img.rich-svg {
  -webkit-user-drag: none;
  user-select: none;
}

.rich-stage.rich-zoomed .rich-diagram { justify-content: flex-start; }

.rich-chart {
  position: relative;
  height: 320px;
  width: 100%;
}

.rich-chart canvas { width: 100% !important; height: 100% !important; }

.rich-chart-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.rich-pending {
  padding: 24px 0;
  text-align: center;
  color: var(--muted);
  font-size: 12px;
}

.rich-error {
  color: var(--danger, #e5484d);
  font: 12px/1.5 var(--mono, ui-monospace, monospace);
  white-space: pre-wrap;
}

.rich-block.rich-failed > .rich-stage { padding-top: 10px; }

.rich-standalone > .rich-stage { background: transparent; padding: 0; height: 100%; display: flex; flex-direction: column; }
.rich-standalone .rich-chart { height: min(70vh, 640px); }
.rich-standalone .rich-diagram { max-height: none; flex: 1 1 auto; min-height: 240px; }
.rich-standalone .rich-tools { opacity: 1; }
.cf-doc > .rich-standalone { height: 100%; }

/* The canvas's document preview: a message's renderer, in a scrolling page. */
.cf-doc {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  height: 100%;
  overflow: auto;
  padding: 16px 20px 32px;
  line-height: 1.55;
}

.cf-doc-markdown > :first-child { margin-top: 0; }
.cf-doc [data-code-canvas] { display: none; }

/* ---- Artifact views (artifact-view.js): a file shown as what it is ---- */
.av { display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.av-frame { width: 100%; height: 70vh; border: 0; border-radius: 8px; background: #fff; }
.av-image img { display: block; max-width: 100%; max-height: 70vh; margin: 0 auto; }
.av-video { width: 100%; max-height: 70vh; }
.av-audio { width: 100%; }
.av-text { max-height: 70vh; overflow: auto; }
.av-text pre.av-code { margin: 0; }
.av-markdown { line-height: 1.55; }
.av-table-wrap { overflow: auto; max-height: 60vh; border: 1px solid var(--line); border-radius: 8px; }
.av-table { border-collapse: collapse; font-size: 12.5px; min-width: 100%; }
.av-table th, .av-table td { padding: 6px 10px; border-bottom: 1px solid var(--line); text-align: left; white-space: nowrap; max-width: 360px; overflow: hidden; text-overflow: ellipsis; }
.av-table th { position: sticky; top: 0; background: var(--surface-soft, var(--surface)); font-weight: 600; z-index: 1; }
.av-table tr:last-child td { border-bottom: 0; }
.av-note { color: var(--muted); font-size: 12px; margin: 6px 0 0; }
.av-error { color: var(--danger, #e5484d); }
.av-actions { font-size: 12.5px; margin: 0; }
.av-size { color: var(--muted); margin-left: 6px; }
.cf-doc-table .av-table-wrap { max-height: none; border: 0; border-radius: 0; }

/* One scratch file: the list would be a single row; give the stage the width. */
.canvas-files.cf-solo .cf-list { display: none; }
.canvas-files.cf-solo { grid-template-columns: minmax(0, 1fr); }
