diff --git a/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/trace-view/trace-view.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/trace-view/trace-view.tsx
index b1e2313af8b..b9ae284b385 100644
--- a/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/trace-view/trace-view.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/trace-view/trace-view.tsx
@@ -495,7 +495,8 @@ function DetailCodeSection({
{activeConfigTab === 'cursor' && (
@@ -533,7 +533,7 @@ console.log(limits);`
code={getStreamCommand()}
language={LANGUAGE_SYNTAX[language]}
wrapText
- className='min-h-0! rounded-sm border border-[var(--border-1)]'
+ className='min-h-0!'
/>
@@ -579,7 +579,7 @@ console.log(limits);`
code={getAsyncCommand()}
language={LANGUAGE_SYNTAX[language]}
wrapText
- className='min-h-0! rounded-sm border border-[var(--border-1)]'
+ className='min-h-0!'
/>
)}
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/output-panel.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/output-panel.tsx
index 7eb787be542..daa24590d8e 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/output-panel.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/output-panel/output-panel.tsx
@@ -66,7 +66,8 @@ const OutputCodeContent = React.memo(function OutputCodeContent({
code={code}
showGutter
language={language}
- className='m-0 min-h-full rounded-none border-0 bg-[var(--bg)] dark:bg-[var(--bg)]'
+ appearance='flat'
+ className='m-0 min-h-full'
paddingLeft={8}
gutterStyle={{ backgroundColor: 'transparent' }}
wrapText={wrapText}
diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx
index 8b027c4c74a..715532c9643 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/preview/components/preview-editor/preview-editor.tsx
@@ -1226,7 +1226,8 @@ function PreviewEditorContent({
{
;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true
+ vi.stubGlobal(
+ 'ResizeObserver',
+ class {
+ observe() {}
+ unobserve() {}
+ disconnect() {}
+ }
+ )
host = document.createElement('div')
document.body.appendChild(host)
root = createRoot(host)
@@ -20,6 +28,7 @@ beforeEach(() => {
afterEach(() => {
if (root) act(() => root?.unmount())
host?.remove()
+ vi.unstubAllGlobals()
root = null
host = null
})
@@ -60,3 +69,79 @@ describe('Code.Viewer workflow references', () => {
expect(host?.querySelector('[data-search-match]')?.textContent).toBe('result')
})
})
+
+describe('Code.Viewer appearances', () => {
+ for (const virtualized of [false, true]) {
+ it(`applies the inspection surface to ${virtualized ? 'virtualized' : 'standard'} output`, async () => {
+ await act(async () => {
+ root?.render(
+
+ )
+ await sleep(1)
+ })
+
+ const viewer = host?.firstElementChild
+ expect(viewer?.classList.contains('rounded-md')).toBe(true)
+ expect(viewer?.classList.contains('border-0')).toBe(true)
+ expect(viewer?.classList.contains('bg-[var(--surface-4)]!')).toBe(true)
+ expect(viewer?.classList.contains('dark:bg-[var(--surface-3)]!')).toBe(true)
+ expect(viewer?.classList.contains('max-h-[300px]')).toBe(true)
+ })
+ }
+
+ it('keeps the flat viewer separate from the default code container', async () => {
+ await act(async () => {
+ root?.render(
+ <>
+
+
+ >
+ )
+ await sleep(1)
+ })
+
+ const [defaultViewer, flatViewer] = Array.from(host?.children ?? [])
+ expect(defaultViewer.classList.contains('rounded-sm')).toBe(true)
+ expect(flatViewer.classList.contains('rounded-none')).toBe(true)
+ expect(flatViewer.classList.contains('bg-[var(--bg)]')).toBe(true)
+ expect(flatViewer.classList.contains('dark:bg-[var(--bg)]')).toBe(true)
+ expect(flatViewer.textContent).toContain('flat')
+ })
+
+ it('applies flat chrome on the virtualized gutter path used by the terminal', async () => {
+ const contentRef = createRef()
+ await act(async () => {
+ root?.render(
+
+ )
+ await sleep(1)
+ })
+
+ const viewer = host?.firstElementChild
+ expect(contentRef.current).toBe(viewer)
+ expect(viewer?.classList.contains('rounded-none')).toBe(true)
+ expect(viewer?.classList.contains('border-0')).toBe(true)
+ expect(viewer?.classList.contains('bg-[var(--bg)]')).toBe(true)
+ expect(viewer?.classList.contains('dark:bg-[var(--bg)]')).toBe(true)
+ expect(viewer?.classList.contains('overflow-x-hidden')).toBe(true)
+ expect(viewer?.classList.contains('min-h-full')).toBe(true)
+ expect(viewer?.classList.contains('rounded-sm')).toBe(false)
+ })
+})
diff --git a/packages/emcn/src/components/code/code.tsx b/packages/emcn/src/components/code/code.tsx
index 2e540301caa..2f0a42a5781 100644
--- a/packages/emcn/src/components/code/code.tsx
+++ b/packages/emcn/src/components/code/code.tsx
@@ -13,6 +13,7 @@ import {
import { escapeRegExp } from '@sim/utils/string'
import { findWorkflowReferenceTokens } from '@sim/utils/workflow-references'
import { useVirtualizer } from '@tanstack/react-virtual'
+import { cva, type VariantProps } from 'class-variance-authority'
import { ChevronRight } from '../../icons'
import { cn } from '../../lib/cn'
import './code.css'
@@ -856,6 +857,18 @@ function applySearchHighlightingToLine(
*/
type CodeViewerDensity = 'default' | 'compact'
+/** Container appearances shared by the standard and virtualized viewers. */
+export const codeViewerAppearanceVariants = cva('', {
+ variants: {
+ appearance: {
+ default: '',
+ inspection: 'rounded-md border-0 bg-[var(--surface-4)]! dark:bg-[var(--surface-3)]!',
+ flat: 'rounded-none border-0 bg-[var(--bg)] dark:bg-[var(--bg)]',
+ },
+ },
+ defaultVariants: { appearance: 'default' },
+})
+
interface CodeViewerProps {
/** Code content to display */
code: string
@@ -865,6 +878,8 @@ interface CodeViewerProps {
language?: 'javascript' | 'json' | 'python' | 'bash' | 'toml'
/** Additional CSS classes for the container */
className?: string
+ /** Container appearance for code inspected in logs/previews or on flat surfaces. */
+ appearance?: NonNullable['appearance']>
/** Visual density for read-only code. */
density?: CodeViewerDensity
/** Highlight Sim `{{ENV}}` and `` references with the platform accent. */
@@ -948,6 +963,7 @@ type ViewerInnerProps = {
language: 'javascript' | 'json' | 'python' | 'bash' | 'toml'
/** Additional CSS classes for the container */
className?: string
+ appearance: NonNullable
/** Visual density for read-only code. */
density: CodeViewerDensity
highlightWorkflowReferences: boolean
@@ -978,6 +994,7 @@ const VirtualizedViewerInner = memo(function VirtualizedViewerInner({
showGutter,
language,
className,
+ appearance,
density,
highlightWorkflowReferences,
paddingLeft,
@@ -1147,6 +1164,7 @@ const VirtualizedViewerInner = memo(function VirtualizedViewerInner({
wrapText ? 'overflow-x-hidden' : 'overflow-x-auto',
'overflow-y-auto',
'dark:bg-[var(--code-bg)]',
+ codeViewerAppearanceVariants({ appearance }),
className
)}
style={{ height: containerHeight }}
@@ -1196,6 +1214,7 @@ const ViewerInner = memo(function ViewerInner({
showGutter,
language,
className,
+ appearance,
density,
highlightWorkflowReferences,
paddingLeft,
@@ -1309,7 +1328,7 @@ const ViewerInner = memo(function ViewerInner({
// Grid-based rendering for gutter alignment (works with wrap)
if (showGutter) {
return (
-
+