fix(landing): refresh sidebars across landing surface (#7102)

* fix(landing): refresh sidebars across landing surface

* fix(landing): remove inline preview scaling
This commit is contained in:
Waleed
2026-08-25 22:42:26 -07:00
committed by GitHub
parent cba0357986
commit 5f62f64e02
15 changed files with 124 additions and 237 deletions
@@ -0,0 +1,48 @@
'use client'
import Image from 'next/image'
import {
PREVIEW_SIDEBAR_CHATS,
PREVIEW_SIDEBAR_WORKFLOWS,
} from '@/app/(landing)/components/shared/sidebar-preview-content'
import {
EnterpriseSidebar,
type EnterpriseSidebarProps,
} from '@/app/(landing)/enterprise/components/enterprise-platform-loop/enterprise-sidebar'
interface CapturedPlatformSurfaceProps {
src: string
sizes: string
activeItem: NonNullable<EnterpriseSidebarProps['activeItem']>
}
/**
* A captured product surface with the current landing sidebar rendered over
* the capture's legacy sidebar pixels. Keeping the sidebar live gives every
* landing callout one source of truth while preserving the detailed product
* content in the capture beside it.
*/
export function CapturedPlatformSurface({ src, sizes, activeItem }: CapturedPlatformSurfaceProps) {
return (
<div className='absolute inset-0 overflow-hidden'>
<Image src={src} alt='' fill sizes={sizes} className='object-cover' />
<svg
aria-hidden='true'
className='pointer-events-none absolute inset-0 size-full overflow-hidden'
viewBox='0 0 1280 735'
preserveAspectRatio='xMinYMin meet'
>
<foreignObject width='1280' height='735'>
<div className='flex h-full w-[249px] border-[var(--border)] border-r bg-[var(--surface-1)]'>
<EnterpriseSidebar
chats={PREVIEW_SIDEBAR_CHATS}
workflows={PREVIEW_SIDEBAR_WORKFLOWS}
activeItem={activeItem}
/>
<div className='min-w-0 flex-1 bg-[var(--surface-1)]' />
</div>
</foreignObject>
</svg>
</div>
)
}
@@ -1,14 +1,10 @@
import Image from 'next/image'
import { CalloutFrame } from '@/app/(landing)/components/features/components/callout-frame'
import { CapturedPlatformSurface } from '@/app/(landing)/components/features/components/captured-platform-surface'
/**
* The Integrate beat's callout - the REAL platform Integrations page as one
* floating window: a full capture of the workspace UI (sidebar + Integrations
* tab with the showcase mosaic, search, and Featured sections) taken by
* `exports/readme-banner/capture-integrations-ui.mjs` at the hero shot's card
* geometry (1280x735 @2x), framed by the shared {@link CalloutFrame} so it
* wears the hero platform window's exact chrome (10px radius + layered
* shadow).
* The Integrate beat's callout - the platform Integrations page as one
* floating window. The detailed page capture is paired with the shared live
* landing sidebar so its navigation and footer stay aligned with the product.
*
* The window is oversized (125% of the media stage, ~82% of the capture's
* native scale) and anchored with visually EQUAL top and left insets
@@ -37,12 +33,10 @@ export function IntegrationsCallout() {
className='absolute top-[14.4%] left-[9.6%] w-[125%]'
bodyClassName='aspect-[1280/735]'
>
<Image
<CapturedPlatformSurface
src='/landing/feature-integrate-ui.png'
alt=''
fill
sizes='(max-width: 1023px) 114vw, (max-width: 1460px) 109vw, 1053px'
className='object-cover'
activeItem='Integrations'
/>
</CalloutFrame>
</div>
@@ -1,14 +1,10 @@
import Image from 'next/image'
import { CalloutFrame } from '@/app/(landing)/components/features/components/callout-frame'
import { CapturedPlatformSurface } from '@/app/(landing)/components/features/components/captured-platform-surface'
/**
* The Context beat's callout - the REAL platform Knowledge base page as one
* floating window: a full capture of the workspace UI (sidebar with Knowledge
* base selected + the knowledge list) taken by
* `exports/readme-banner/capture-knowledge-ui.mjs` at the hero shot's card
* geometry (1280x735 @2x), framed by the shared {@link CalloutFrame} so it
* wears the hero platform window's exact chrome (10px radius + layered
* shadow).
* The Context beat's callout - the platform Knowledge bases page as one
* floating window. The detailed page capture is paired with the shared live
* landing sidebar so its navigation and footer stay aligned with the product.
*
* Same oversized treatment as the Integrate card: 125% of the media stage
* with EQUAL top and left insets (96px), so the top-left corner floats free
@@ -22,12 +18,10 @@ export function KnowledgeCallout() {
className='absolute top-[14.4%] left-[9.6%] w-[125%]'
bodyClassName='aspect-[1280/735]'
>
<Image
<CapturedPlatformSurface
src='/landing/feature-context-ui.png'
alt=''
fill
sizes='1050px'
className='object-cover'
activeItem='Knowledge bases'
/>
</CalloutFrame>
</div>
@@ -1,14 +1,10 @@
import Image from 'next/image'
import { CalloutFrame } from '@/app/(landing)/components/features/components/callout-frame'
import { CapturedPlatformSurface } from '@/app/(landing)/components/features/components/captured-platform-surface'
/**
* The Monitor beat's callout - the REAL platform Logs page as one floating
* window: a full capture of the workspace UI (sidebar with Logs selected +
* the seeded run table) taken by
* `exports/readme-banner/capture-logs-ui.mjs` at the hero shot's card
* geometry (1280x735 @2x), framed by the shared {@link CalloutFrame} so it
* wears the hero platform window's exact chrome (10px radius + layered
* shadow).
* The Monitor beat's callout - the platform Logs page as one floating window.
* The detailed page capture is paired with the shared live landing sidebar so
* its navigation and footer stay aligned with the product.
*
* Same oversized treatment as the Context card: 125% of the media stage with
* EQUAL top and left insets (96px), so the top-left corner floats free over
@@ -22,12 +18,10 @@ export function LogsCallout() {
className='absolute top-[14.4%] left-[9.6%] w-[125%]'
bodyClassName='aspect-[1280/735]'
>
<Image
<CapturedPlatformSurface
src='/landing/feature-monitor-ui.png'
alt=''
fill
sizes='1050px'
className='object-cover'
activeItem='Logs'
/>
</CalloutFrame>
</div>
@@ -1,14 +1,18 @@
'use client'
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
import { useEffect, useState } from 'react'
import { cn } from '@sim/emcn'
import {
HeroChatLoop,
type HeroChatPhase,
} from '@/app/(landing)/components/hero/components/hero-chat-loop'
import { HeroWorkflowStage } from '@/app/(landing)/components/hero/components/hero-platform-loop/hero-workflow-stage'
import { SidebarHotspots } from '@/app/(landing)/components/hero/components/hero-platform-loop/sidebar-hotspots'
import { STAGE_BLOCKS } from '@/app/(landing)/components/hero/components/hero-platform-loop/stage-data'
import { HeroLoopShell } from '@/app/(landing)/components/shared/hero-loop-shell'
import {
PREVIEW_SIDEBAR_CHATS,
PREVIEW_SIDEBAR_WORKFLOWS,
} from '@/app/(landing)/components/shared/sidebar-preview-content'
/**
* One pass of the synced loop, matching the REAL platform behavior: the chat
@@ -29,35 +33,14 @@ const TOTAL_MS = 12_500
const RESET_FADE_MS = 260
/**
* The workspace container's interior in the capture's design space (the shot
* is 2560x1470 at 2x, i.e. a 1280x735 CSS layout - oversized vs the 1080x620
* window so the whole UI displays at 84.4%, landing the app's native type at
* cursor.com's ~12.7px demo scale): x 249-1272, y 7-727. The live layer lays
* out at this FIXED size and scales down with the window (`transform: scale`),
* so its text and controls shrink in lockstep with the baked sidebar pixels -
* the "mini app" reading - instead of rendering at 1:1 CSS sizes and looking
* oversized next to the scaled screenshot.
*/
const CHROME_INTERIOR = { width: 1024, height: 721 } as const
/**
* The hero window's live layer - one flex region replaying the REAL Home
* two-pane over the static screenshot. The region covers the workspace
* container's interior (inset a hair inside the shot's baked chrome: the
* horizontal rules 6px from the card top/bottom (the chrome's `p-[8px]` gap is
* tightened to 6px at capture time), the container's left border at ~19.4%,
* and its right border at ~99.4%; the container renders at `6px` radius
* (overridden at capture time from the chrome's 8px so it DISPLAYS at the
* concentric ~4.9px after the 84.4% shot-to-window factor), so the region
* clips itself `rounded-[4px]` to hug the baked corner curves without
* covering them) so every visible outline is the real UI's pixels.
*
* Inside, the layout mirrors `Home`: the {@link HeroChatLoop} is a flex-1
* The homepage's live platform preview, rendered through the same shared shell
* as every product and solutions hero so the sidebar never drifts between
* landing surfaces. Inside, the layout mirrors `Home`: the
* {@link HeroChatLoop} is a flex-1
* `--bg` column; the {@link HeroWorkflowStage} pane animates `w-0 ↔ w-1/2`
* with the real `MothershipView` width transition (200ms,
* `cubic-bezier(0.25,0.1,0.25,1)`, `border-l` only while open) - the baked
* chat|stage divider is covered by this region, so the divider users see is
* the live `border-l`, appearing exactly as it does in the product.
* `cubic-bezier(0.25,0.1,0.25,1)`, `border-l` only while open), matching the
* divider users see in the product.
*
* Both panes stay `pointer-events-none` (decorative, matching the hero's
* `aria-hidden` frame) - blocks are static. Remounting the stage per cycle
@@ -67,28 +50,11 @@ const CHROME_INTERIOR = { width: 1024, height: 721 } as const
* open stage, and fully-built workflow render statically.
*/
export function HeroPlatformLoop() {
const regionRef = useRef<HTMLDivElement>(null)
const [phase, setPhase] = useState<HeroChatPhase>('idle')
const [stageOpen, setStageOpen] = useState(false)
const [builtCount, setBuiltCount] = useState(0)
const [fading, setFading] = useState(false)
const [cycleId, setCycleId] = useState(0)
const [scale, setScale] = useState(1)
// Track the rendered region width and scale the design-space layer to fill
// it, keeping the live layer's proportions locked to the screenshot's.
useLayoutEffect(() => {
const el = regionRef.current
if (!el) return
const measure = () => {
const w = el.getBoundingClientRect().width
if (w > 40) setScale(w / CHROME_INTERIOR.width)
}
measure()
const ro = new ResizeObserver(measure)
ro.observe(el)
return () => ro.disconnect()
}, [])
useEffect(() => {
const media = window.matchMedia('(prefers-reduced-motion: reduce)')
@@ -144,33 +110,27 @@ export function HeroPlatformLoop() {
}, [])
return (
<>
<SidebarHotspots />
<div
ref={regionRef}
className='absolute top-[0.95%] right-[0.55%] bottom-[0.95%] left-[19.45%] overflow-hidden rounded-[4px]'
>
<HeroLoopShell chats={PREVIEW_SIDEBAR_CHATS} workflows={PREVIEW_SIDEBAR_WORKFLOWS}>
<div className='flex h-full w-full overflow-hidden rounded-[6px] border border-[var(--border)] bg-[var(--bg)]'>
<div className='relative h-full min-w-0 flex-1'>
<HeroChatLoop phase={phase} fading={fading} />
</div>
<div
className='flex origin-top-left'
style={{
width: CHROME_INTERIOR.width,
height: CHROME_INTERIOR.height,
transform: `scale(${scale})`,
}}
className={cn(
'h-full shrink-0 overflow-hidden border-[var(--border)] bg-[var(--bg)] transition-[width,min-width,border-width] duration-200 [transition-timing-function:cubic-bezier(0.25,0.1,0.25,1)]',
stageOpen ? 'w-1/2 border-l' : 'w-0 min-w-0 border-l-0'
)}
>
<div className='pointer-events-none relative h-full min-w-0 flex-1'>
<HeroChatLoop phase={phase} fading={fading} />
</div>
<div
className={cn(
'h-full shrink-0 overflow-hidden border-[var(--border)] bg-[var(--bg)] transition-[width,min-width,border-width] duration-200 [transition-timing-function:cubic-bezier(0.25,0.1,0.25,1)]',
stageOpen ? 'w-1/2 border-l' : 'w-0 min-w-0 border-l-0'
'h-full w-full transition-opacity duration-300 ease-out',
fading ? 'opacity-0' : 'opacity-100'
)}
>
<HeroWorkflowStage key={cycleId} builtCount={builtCount} />
</div>
</div>
</div>
</>
</HeroLoopShell>
)
}
@@ -1,89 +1,2 @@
'use client'
import { Tooltip } from '@sim/emcn'
/**
* Cursor-to-bubble gap for tooltips over the mini platform UI - tighter than
* the product-standard 16px so the bubble hugs the cursor proportionately to
* the scaled-down preview.
*/
/** Tight tooltip spacing for the scaled-down platform preview. */
export const HERO_TOOLTIP_OFFSET = 8
/** Percent-of-image bounds shared by both hotspot kinds. */
interface HotspotBounds {
left: string
top: string
width: string
height: string
}
/** An icon control that shows a tooltip on hover, like the real product. */
interface TooltipHotspot extends HotspotBounds {
label: string
}
/** A sidebar nav row that shows the real row-hover highlight on hover. */
interface RowHotspot extends HotspotBounds {
name: string
}
/**
* Icon controls measured from the capture (2560x1470): the collapse-sidebar
* toggle (x428-468, y36-72) and the Workflows section's "More actions"
* ellipsis (x376-412) and "Create workflow" plus (x424-460) at y920-952.
* Copy matches the real product's tooltips.
*/
const TOOLTIP_HOTSPOTS: TooltipHotspot[] = [
{ label: 'Collapse sidebar', left: '16.72%', top: '2.45%', width: '1.56%', height: '2.45%' },
{ label: 'More actions', left: '14.69%', top: '62.59%', width: '1.4%', height: '2.18%' },
{ label: 'Create workflow', left: '16.56%', top: '62.59%', width: '1.4%', height: '2.18%' },
]
/**
* Workspace nav rows (Tables / Files / Knowledge base), boxed like the real
* sidebar row (`h-[30px] rounded-lg`, text rows measured at y598-616, 662-680,
* 726-750): a 60px-tall (at 2x) highlight box centered on each row's text,
* starting left of the row ICON (icons measured at x37-39, the box carries the
* real row's 8px icon gutter) so the icon sits inside the highlight.
*/
const ROW_HOTSPOTS: RowHotspot[] = [
{ name: 'Tables', left: '0.82%', top: '39.25%', width: '17.15%', height: '4.08%' },
{ name: 'Files', left: '0.82%', top: '43.61%', width: '17.15%', height: '4.08%' },
{ name: 'Knowledge base', left: '0.82%', top: '48.16%', width: '17.15%', height: '4.08%' },
]
/**
* Hover layers over the BAKED sidebar pixels. Icon controls (collapse toggle,
* Workflows more/create) get transparent targets wired to the emcn
* {@link Tooltip} with the product's real copy ({@link HERO_TOOLTIP_OFFSET}
* keeps the bubble close over the mini UI). The Workspace nav rows instead
* reproduce the REAL sidebar row-hover state - `--surface-active` on the
* row's rounded box - via `mix-blend-multiply`, which paints over the baked
* white/text pixels to exactly the result of a background behind the text.
*/
export function SidebarHotspots() {
return (
<div aria-hidden='true' className='pointer-events-none absolute inset-0'>
{TOOLTIP_HOTSPOTS.map((spot) => (
<Tooltip.Root key={spot.label}>
<Tooltip.Trigger asChild>
<span
aria-label={spot.label}
className='pointer-events-auto absolute block'
style={{ left: spot.left, top: spot.top, width: spot.width, height: spot.height }}
/>
</Tooltip.Trigger>
<Tooltip.Content offset={HERO_TOOLTIP_OFFSET}>{spot.label}</Tooltip.Content>
</Tooltip.Root>
))}
{ROW_HOTSPOTS.map((row) => (
<span
key={row.name}
aria-label={row.name}
className='pointer-events-auto absolute block cursor-pointer rounded-[6px] mix-blend-multiply transition-colors duration-100 hover:bg-[var(--surface-active)]'
style={{ left: row.left, top: row.top, width: row.width, height: row.height }}
/>
))}
</div>
)
}
@@ -31,23 +31,11 @@ import { TrustedBy } from '@/app/(landing)/components/trusted-by'
* LCP element) behind a white window (a soft three-part shadow stack:
* `0 0 0 1px rgba(0,0,0,0.08)` ring in place of a CSS border, plus
* `0 2px 6px rgba(0,0,0,0.05)` contact and `0 4px 42px rgba(0,0,0,0.06)`
* ambient shadows; no browser toolbar) filled edge to edge by the REAL
* platform UI - a 2x
* screenshot (`hero-platform-ui.png`, 2560x1470: a 1280x735 layout shown in
* the 1080x620 window, so the UI reads at 84.4% - the "mini app" type scale
* cursor.com's demo window uses) of the chat-everywhere two-pane (seeded
* Mothership chat left, staged workflow right) captured from the
* `readme-tour-capture` route via
* `exports/readme-banner/capture-hero-platform.mjs`. The window is
* `rounded-[10px]` - matching cursor.com's demo window - and the shot's
* workspace container renders at the concentric inner radius `4px` (outer
* 10px - 6px gap; overridden at capture time from the chrome's 8px). Only the
* SIDEBAR
* remains visible from the shot: the {@link HeroPlatformLoop} island overlays
* the container interior (full-width chat that stages the workflow pane in,
* replaying the conversation with the goo ThinkingLoader), inset a hair INSIDE
* the shot's own baked outlines so the visible chrome is the real UI's pixels
* - never re-drawn.
* ambient shadows; no browser toolbar) filled edge to edge by the live
* {@link HeroPlatformLoop}. The shared landing sidebar and animated Home
* workspace render together in a fixed 1280x735 design space, so the homepage
* stays aligned with every product and solutions hero without a baked UI
* capture drifting behind it.
* The frame is `1300/720` and the window `1080/620` at `83.08%` width, centered
* - matching cursor.com's hero media proportions, with backdrop showing on all
* four sides. Decorative, `aria-hidden`; the `--surface-3` fill remains as the
@@ -109,14 +97,6 @@ export function Hero() {
/>
<div className='-translate-x-1/2 -translate-y-1/2 absolute top-1/2 left-1/2 flex aspect-[1080/620] w-[83.08%] flex-col overflow-hidden rounded-[10px] bg-[var(--surface-1)] shadow-[0_0_0_1px_rgba(0,0,0,0.08),0_2px_6px_0_rgba(0,0,0,0.05),0_4px_42px_0_rgba(0,0,0,0.06)]'>
<div className='relative flex-1'>
<Image
src='/landing/hero-platform-ui.png'
alt=''
fill
priority
sizes='(max-width: 1460px) 83vw, 1080px'
className='object-cover object-left-top'
/>
<HeroPlatformLoop />
</div>
</div>
@@ -32,8 +32,8 @@ export interface EditorLoopContent {
canvas: { width: number; height: number }
/** The block the "editing" beat selects once the flow is assembled. */
selectedBlockId: string
/** Workspace-nav row to highlight in the sidebar; unset keeps New chat active. */
activeNav?: EnterpriseSidebarProps['activeNav']
/** Sidebar row to highlight; unset keeps New chat active. */
activeItem?: EnterpriseSidebarProps['activeItem']
}
interface EditorLoopProps {
@@ -96,7 +96,7 @@ export function EditorLoop({ content }: EditorLoopProps) {
<HeroLoopShell
chats={content.sidebarChats}
workflows={content.sidebarWorkflows}
activeNav={content.activeNav}
activeItem={content.activeItem}
>
<div className='h-full w-full overflow-hidden rounded-[6px] border border-[var(--border)] bg-[var(--bg)]'>
<div
@@ -16,8 +16,8 @@ interface HeroLoopShellProps {
chats: readonly string[]
/** Deployed-workflow entries in the sidebar - five fill the design height. */
workflows: readonly string[]
/** Workspace-nav row to highlight; unset keeps New chat active. */
activeNav?: EnterpriseSidebarProps['activeNav']
/** Sidebar row to highlight; unset keeps New chat active. */
activeItem?: EnterpriseSidebarProps['activeItem']
/** The workspace pane's contents, rendered inside the inset pane gutter. */
children: ReactNode
}
@@ -35,7 +35,7 @@ export function HeroLoopShell({
profileName = 'Morgan',
chats,
workflows,
activeNav,
activeItem,
children,
}: HeroLoopShellProps) {
const { regionRef, scale } = useDesignScale()
@@ -55,7 +55,7 @@ export function HeroLoopShell({
profileName={profileName}
chats={chats}
workflows={workflows}
activeNav={activeNav}
activeItem={activeItem}
/>
<div className='h-full min-w-0 flex-1 py-[7px] pr-[8px]'>{children}</div>
</div>
@@ -0,0 +1,7 @@
export const PREVIEW_SIDEBAR_CHATS = ['Enrich new signups', 'Post deal alerts to #sales'] as const
export const PREVIEW_SIDEBAR_WORKFLOWS = [
'Lead enrichment',
'Inbound lead routing',
'Weekly pipeline report',
] as const
@@ -32,6 +32,8 @@ const WORKSPACE_NAV = [
{ label: 'Logs', icon: Library },
] as const
export type SidebarItem = 'New chat' | 'Integrations' | (typeof WORKSPACE_NAV)[number]['label']
interface IconRowProps {
icon: React.ComponentType<{ className?: string }>
label: string
@@ -81,18 +83,13 @@ export interface EnterpriseSidebarProps {
chats?: readonly string[]
/** Deployed-workflow entries - five fill the design height. Defaults enterprise. */
workflows?: readonly string[]
/**
* Workspace-nav row to render active (e.g. `'Tables'`) - the platform pages
* highlight their own module instead of New chat. Unset keeps the enterprise
* default (New chat active).
*/
activeNav?: (typeof WORKSPACE_NAV)[number]['label']
/** Sidebar row to render active. Defaults to New chat. */
activeItem?: SidebarItem
}
/**
* The Brightwave workspace sidebar, rendered live (the homepage loop keeps its
* baked-screenshot sidebar; the enterprise loop draws its own so the content
* can read like a large tenured deployment): the workspace header, New chat /
* The Brightwave workspace sidebar, rendered live across landing previews so
* every surface stays aligned with the product: the workspace header, New chat /
* Integrations, a filled-out Chats history, the Workspace nav, a full
* Workflows section, and the profile / Help footer. Purely decorative -
* hover/click behavior is owned by the parent's `pointer-events-none` frame.
@@ -107,7 +104,7 @@ export const EnterpriseSidebar = memo(function EnterpriseSidebar({
profileName = 'Morgan',
chats = SIDEBAR_CHATS,
workflows = SIDEBAR_WORKFLOWS,
activeNav,
activeItem = 'New chat',
}: EnterpriseSidebarProps = {}) {
return (
<div className='flex h-full w-[238px] flex-shrink-0 flex-col bg-[var(--surface-1)] pt-3'>
@@ -137,8 +134,8 @@ export const EnterpriseSidebar = memo(function EnterpriseSidebar({
</div>
<div className='mt-4 flex flex-shrink-0 flex-col gap-[1px] px-2'>
<IconRow icon={Home} label='New chat' active={!activeNav} />
<IconRow icon={Integration} label='Integrations' />
<IconRow icon={Home} label='New chat' active={activeItem === 'New chat'} />
<IconRow icon={Integration} label='Integrations' active={activeItem === 'Integrations'} />
</div>
<div className='mt-4 flex flex-shrink-0 flex-col'>
@@ -158,7 +155,7 @@ export const EnterpriseSidebar = memo(function EnterpriseSidebar({
key={item.label}
icon={item.icon}
label={item.label}
active={item.label === activeNav}
active={item.label === activeItem}
/>
))}
</div>
@@ -235,7 +235,7 @@ export function FilesHeroLoop() {
})
return (
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeNav='Files'>
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeItem='Files'>
<div className='h-full w-full overflow-hidden rounded-[6px] border border-[var(--border)] bg-[var(--bg)]'>
<div
className={cn(
@@ -162,7 +162,7 @@ export function KnowledgeHeroLoop() {
})
return (
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeNav='Knowledge bases'>
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeItem='Knowledge bases'>
<div className='h-full w-full overflow-hidden rounded-[6px] border border-[var(--border)] bg-[var(--bg)]'>
<div
className={cn(
@@ -274,7 +274,7 @@ export function LogsHeroLoop() {
const liveCompleted = liveState === 'completed'
return (
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeNav='Logs'>
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeItem='Logs'>
<div className='h-full w-full overflow-hidden rounded-[6px] border border-[var(--border)] bg-[var(--bg)]'>
<div
key={cycleId}
@@ -390,7 +390,7 @@ export function TablesHeroLoop() {
})
return (
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeNav='Tables'>
<HeroLoopShell chats={SIDEBAR_CHATS} workflows={SIDEBAR_WORKFLOWS} activeItem='Tables'>
<div className='h-full w-full overflow-hidden rounded-[6px] border border-[var(--border)] bg-[var(--bg)]'>
<div
className={cn(