From cfdea9123e3f32f801f5d6b9dad6d3cefe8f96a5 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 5 Aug 2026 13:36:08 -0700 Subject: [PATCH] improvement(docs): restructure sidebar, align chrome, rename Mothership to Chat Sidebar: 11 separator groups become 5, with each module a collapsible folder that auto-opens on the active page. 61 always-visible rows drop to 16. Groups mirror the app's own nav (Chats/Workspace/Workflows) rather than inventing a taxonomy; Enterprise and Self-Hosting are hoisted out of Platform. Chrome: register the `hover-hover` variant, without which every @sim/emcn hover state silently compiled to nothing; restore the sidebar's Geist font stack; add 11 emcn tokens that were falling back to currentColor; adopt the named type scale; align row geometry, hover tokens and group labels with the app. Rename: mothership/ -> chat/ with redirects for the old URLs. Asset paths, the @mothership.sim.ai domain and the `mothership` log-trigger enum value are deliberately left alone -- they are CDN objects, a real domain, and a live product value. Also removes the page-type badge, drops the "Next" heading from the ToC, and lets FAQ rows open independently so expanding one no longer shifts the page. --- apps/docs/app/[lang]/[[...slug]]/page.tsx | 21 ++- apps/docs/app/global.css | 122 +++++++++++------- .../components/docs-layout/page-footer.tsx | 101 +++++---------- .../docs-layout/sidebar-components.tsx | 56 ++++---- apps/docs/components/footer/footer.tsx | 2 +- apps/docs/components/navbar/navbar.tsx | 2 +- apps/docs/components/page-type-badge.tsx | 53 -------- apps/docs/components/ui/faq.tsx | 24 +++- apps/docs/components/ui/sim-logo.tsx | 107 --------------- apps/docs/components/ui/video.tsx | 7 +- .../content/docs/en/academy/chat/building.mdx | 14 +- .../content/docs/en/academy/chat/intro.mdx | 30 ++--- apps/docs/content/docs/en/agents/choosing.mdx | 1 - .../content/docs/en/agents/custom-tools.mdx | 1 - apps/docs/content/docs/en/agents/index.mdx | 1 - apps/docs/content/docs/en/agents/mcp.mdx | 1 - apps/docs/content/docs/en/agents/meta.json | 4 + apps/docs/content/docs/en/agents/skills.mdx | 1 - .../docs/en/{mothership => chat}/files.mdx | 36 +++--- apps/docs/content/docs/en/chat/index.mdx | 73 +++++++++++ .../en/{mothership => chat}/knowledge.mdx | 24 ++-- .../docs/en/{mothership => chat}/mailer.mdx | 2 +- .../docs/en/{mothership => chat}/meta.json | 4 +- .../docs/en/{mothership => chat}/research.mdx | 12 +- .../docs/en/{mothership => chat}/tables.mdx | 16 +-- .../docs/en/{mothership => chat}/tasks.mdx | 34 ++--- .../en/{mothership => chat}/workflows.mdx | 36 +++--- apps/docs/content/docs/en/files/editor.mdx | 1 - .../docs/content/docs/en/files/generating.mdx | 1 - apps/docs/content/docs/en/files/index.mdx | 1 - apps/docs/content/docs/en/files/meta.json | 4 + .../content/docs/en/files/passing-files.mdx | 1 - .../docs/en/files/using-in-workflows.mdx | 1 - .../content/docs/en/getting-started/index.mdx | 3 +- apps/docs/content/docs/en/index.mdx | 2 +- .../docs/en/integrations/hubspot-setup.mdx | 1 - .../content/docs/en/integrations/index.mdx | 1 - .../content/docs/en/introduction/index.mdx | 20 +-- .../en/knowledgebase/chunking-strategies.mdx | 1 - .../docs/en/knowledgebase/connectors.mdx | 1 - .../en/knowledgebase/debugging-retrieval.mdx | 1 - .../content/docs/en/knowledgebase/index.mdx | 1 - .../en/knowledgebase/using-in-workflows.mdx | 1 - .../content/docs/en/logs-debugging/alerts.mdx | 1 - .../content/docs/en/logs-debugging/index.mdx | 3 +- .../docs/en/logs-debugging/logging.mdx | 1 - .../content/docs/en/logs-debugging/meta.json | 4 + apps/docs/content/docs/en/meta.json | 70 ++-------- .../docs/content/docs/en/mothership/index.mdx | 73 ----------- apps/docs/content/docs/en/platform/costs.mdx | 4 +- .../en/platform/enterprise/access-control.mdx | 16 +-- .../en/platform/enterprise/data-drains.mdx | 10 +- .../docs/en/platform/enterprise/index.mdx | 4 +- apps/docs/content/docs/en/platform/meta.json | 4 + .../content/docs/en/platform/organization.mdx | 1 - .../content/docs/en/platform/permissions.mdx | 1 - .../content/docs/en/platform/workspaces.mdx | 1 - apps/docs/content/docs/en/tables/index.mdx | 1 - apps/docs/content/docs/en/tables/meta.json | 4 + .../docs/en/tables/using-in-workflows.mdx | 1 - .../docs/en/tables/workflow-columns.mdx | 1 - .../docs/en/workflows/blocks/agent.mdx | 1 - .../content/docs/en/workflows/blocks/api.mdx | 1 - .../docs/en/workflows/blocks/condition.mdx | 1 - .../docs/en/workflows/blocks/credential.mdx | 1 - .../docs/en/workflows/blocks/evaluator.mdx | 1 - .../docs/en/workflows/blocks/function.mdx | 1 - .../docs/en/workflows/blocks/guardrails.mdx | 1 - .../en/workflows/blocks/human-in-the-loop.mdx | 1 - .../content/docs/en/workflows/blocks/loop.mdx | 1 - .../docs/en/workflows/blocks/parallel.mdx | 1 - .../content/docs/en/workflows/blocks/pi.mdx | 1 - .../docs/en/workflows/blocks/response.mdx | 1 - .../docs/en/workflows/blocks/router.mdx | 1 - .../docs/en/workflows/blocks/variables.mdx | 1 - .../content/docs/en/workflows/blocks/wait.mdx | 1 - .../docs/en/workflows/blocks/webhook.mdx | 1 - .../docs/en/workflows/blocks/workflow.mdx | 1 - .../content/docs/en/workflows/connections.mdx | 1 - .../content/docs/en/workflows/data-flow.mdx | 1 - .../docs/en/workflows/deployment/index.mdx | 1 - .../content/docs/en/workflows/how-it-runs.mdx | 1 - apps/docs/content/docs/en/workflows/index.mdx | 5 +- apps/docs/content/docs/en/workflows/meta.json | 13 ++ .../docs/en/workflows/triggers/rss.mdx | 1 - .../docs/en/workflows/triggers/schedule.mdx | 1 - .../docs/en/workflows/triggers/start.mdx | 1 - .../docs/en/workflows/triggers/table.mdx | 1 - .../docs/en/workflows/triggers/webhook.mdx | 1 - .../content/docs/en/workflows/variables.mdx | 1 - apps/docs/lib/source.ts | 4 - apps/docs/next.config.ts | 9 +- apps/docs/source.config.ts | 11 +- 93 files changed, 436 insertions(+), 659 deletions(-) delete mode 100644 apps/docs/components/page-type-badge.tsx create mode 100644 apps/docs/content/docs/en/agents/meta.json rename apps/docs/content/docs/en/{mothership => chat}/files.mdx (60%) create mode 100644 apps/docs/content/docs/en/chat/index.mdx rename apps/docs/content/docs/en/{mothership => chat}/knowledge.mdx (72%) rename apps/docs/content/docs/en/{mothership => chat}/mailer.mdx (96%) rename apps/docs/content/docs/en/{mothership => chat}/meta.json (56%) rename apps/docs/content/docs/en/{mothership => chat}/research.mdx (68%) rename apps/docs/content/docs/en/{mothership => chat}/tables.mdx (66%) rename apps/docs/content/docs/en/{mothership => chat}/tasks.mdx (70%) rename apps/docs/content/docs/en/{mothership => chat}/workflows.mdx (62%) create mode 100644 apps/docs/content/docs/en/files/meta.json create mode 100644 apps/docs/content/docs/en/logs-debugging/meta.json delete mode 100644 apps/docs/content/docs/en/mothership/index.mdx create mode 100644 apps/docs/content/docs/en/platform/meta.json create mode 100644 apps/docs/content/docs/en/tables/meta.json create mode 100644 apps/docs/content/docs/en/workflows/meta.json diff --git a/apps/docs/app/[lang]/[[...slug]]/page.tsx b/apps/docs/app/[lang]/[[...slug]]/page.tsx index 438968103cf..a5702cc93c9 100644 --- a/apps/docs/app/[lang]/[[...slug]]/page.tsx +++ b/apps/docs/app/[lang]/[[...slug]]/page.tsx @@ -10,7 +10,6 @@ import { notFound } from 'next/navigation' import { PageFooter } from '@/components/docs-layout/page-footer' import { PageNavigationArrows } from '@/components/docs-layout/page-navigation-arrows' import { LLMCopyButton } from '@/components/page-actions' -import { PageTypeBadge } from '@/components/page-type-badge' import { StructuredData } from '@/components/structured-data' import { CodeBlock } from '@/components/ui/code-block' import { Heading } from '@/components/ui/heading' @@ -23,6 +22,21 @@ import { DOCS_BASE_URL } from '@/lib/urls' const SUPPORTED_LANGUAGES: Set = new Set(i18n.languages) const BASE_URL = DOCS_BASE_URL +/** + * Most pages close with a `## Next` / `## Next steps` grid of onward links. + * That heading is navigation, not content, so it is kept out of the table of + * contents — the ToC should say what the page covers, not where to go after it. + * The heading itself still renders above the cards. + * + * Matched on the slug rather than the rendered title because a ToC title is a + * `ReactNode`; the trailing group tolerates the slugger's dedupe suffix. + */ +const ONWARD_NAV_SLUG = /^#next(-steps)?(-\d+)?$/i + +function isContentHeading(item: { url: string }): boolean { + return !ONWARD_NAV_SLUG.test(item.url) +} + const OG_LOCALE_MAP: Record = { en: 'en_US', es: 'es_ES', @@ -171,7 +185,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l breadcrumb={breadcrumbs} /> - {data.pageType && } {data.title} diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index 1047524cc3d..39f705b6510 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -5,6 +5,19 @@ @source "../../../packages/emcn/src"; @source "../../../packages/workflow-renderer/src"; +/* Every @sim/emcn component expresses hover through `hover-hover:` so touch + devices never latch a sticky hover state. The app registers it as a plugin + variant in apps/sim/tailwind.config.ts; docs is CSS-first Tailwind v4 with no + config, so without this declaration the variant compiles to nothing and every + emcn hover state silently no-ops here. */ +@custom-variant hover-hover { + @media (hover: hover) and (pointer: fine) { + &:hover { + @slot; + } + } +} + /* Prevent overscroll bounce effect on the page */ html, body { @@ -114,11 +127,24 @@ body { --badge-error-text: #dc2626; --badge-gray-bg: #e7e5e4; --badge-gray-text: #57534e; + --code-bg: #f5f5f5; + --code-foreground: #1a1a1a; + --code-line-number: #737373; + --selection-bg: #add6ff; + --selection-dark: #264f78; + --highlight-search-active: #f6ad55; --scrollbar-thumb-color: #c0c0c0; --scrollbar-thumb-hover-color: #a8a8a8; --shadow-subtle: 0 2px 4px 0 rgba(0, 0, 0, 0.08); --shadow-medium: 0 4px 12px rgba(0, 0, 0, 0.1); + --shadow-overlay: 0 10px 30px rgba(0, 0, 0, 0.11); --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.04); + /* z-index scale — poppers sit above the modal so menus stay clickable over + the modal overlay. Mirrors apps/sim/app/_styles/globals.css. */ + --z-toast: 150; + --z-modal: 200; + --z-popover: 300; + --z-tooltip: 400; } .dark { @@ -185,8 +211,13 @@ body { --badge-error-text: #fca5a5; --badge-gray-bg: #3a3a3a; --badge-gray-text: #a8a8a8; + --code-bg: #1f1f1f; + --code-foreground: #eeeeee; + --code-line-number: #a8a8a8; + --selection-bg: #264f78; --scrollbar-thumb-color: #5a5a5a; --scrollbar-thumb-hover-color: #6a6a6a; + --shadow-overlay: 0 10px 30px rgba(0, 0, 0, 0.3); } /* Scrollbars — platform thumb tokens, transparent track */ @@ -358,10 +389,10 @@ aside#nd-sidebar [data-radix-scroll-area-viewport] { } } -/* Sidebar spacing — left padding aligns item text with navbar content (item has 14px internal padding) */ +/* Sidebar spacing — left padding aligns item text with navbar content (item has 8px internal padding) */ [data-sidebar-viewport], #nd-sidebar > div { - padding: 0 14px 0 calc(var(--nav-inset) - 14px) !important; + padding: 0 14px 0 calc(var(--nav-inset) - 8px) !important; background: transparent !important; } @@ -386,15 +417,20 @@ html #nd-sidebar [data-radix-scroll-area-viewport] > div { /* Target Link and button elements in sidebar - override Fumadocs itemVariants */ /* Exclude the small chevron-only toggle buttons */ /* Using html prefix for higher specificity over Tailwind v4 utilities */ +/* NEVER set `display` here. This selector scores (1,2,2) and carries + `!important`, so it out-specifies every rule below that hides the language + selector, theme toggle, and search button — a `display` declaration here + forces all of them back into the sidebar. The 30px chip height therefore + comes from line-height + padding (20 + 5 + 5), not from flex centering. */ html #nd-sidebar a:not(:has(span.font-mono)), html #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) { font-size: 0.875rem !important; /* 14px to match navbar items */ - line-height: 1.4 !important; - padding: 0.375rem 0.875rem !important; - font-weight: 450 !important; + line-height: 20px !important; + padding: 5px 0.5rem !important; /* 30px tall overall — the app's chip pill, at its px-2 */ + font-weight: 400 !important; border-radius: 0.5rem !important; /* platform rounded-lg */ - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, - sans-serif !important; + font-family: var(--font-geist-sans), ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important; } /* Sidebar text — platform --text-body */ @@ -428,28 +464,24 @@ html #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) margin-bottom: 0 !important; } -/* Section separator headers — styling handled by component, override fumadocs defaults */ +/* Section separator headers — match the app sidebar's group label: 12px, + sentence case, normal weight. Only the fumadocs defaults are overridden here; + size and color stay on the component. */ [data-sidebar-viewport] [data-separator] p, #nd-sidebar [data-separator] p { - font-size: 0.625rem !important; /* 10px */ - font-weight: 600 !important; - text-transform: uppercase !important; - letter-spacing: 0.06em !important; + font-weight: 400 !important; + text-transform: none !important; + letter-spacing: normal !important; margin: 0 !important; padding: 0 !important; } -/* First separator has no top margin or divider; subsequent ones show the divider on desktop */ +/* The first group sits flush against the top padding — it has nothing to be + separated from. */ [data-separator]:not([data-separator] ~ [data-separator]) { margin-top: 0; } -@media (min-width: 1024px) { - [data-separator] ~ [data-separator] > .separator-divider { - display: block; - } -} - /* Active state — aligned with platform --surface-active */ #nd-sidebar a[data-active="true"]:not(:has(span.font-mono)), #nd-sidebar button[data-active="true"] { @@ -709,7 +741,7 @@ main article h4, [data-content] h4, #nd-page h3, #nd-page h4 { - font-size: 1rem !important; + font-size: var(--text-md) !important; font-weight: 470 !important; letter-spacing: -0.01em; color: var(--text-body); @@ -751,18 +783,26 @@ main article li, border-left: none !important; } +/* The clerk TOC draws its active range twice: a track segment, plus a dot that + animates along the track to the current heading. The dot is redundant with the + segment and reads as a stray artifact, so hide it and keep the segment. It is + the only node fumadocs gives an inline offset-path, which is what anchors it. */ +#nd-toc [style*="offset-path"] { + display: none !important; +} + /* TOC heading — align weight with landing */ #nd-toc h3, #nd-toc [class*="title"] { font-weight: 480 !important; - font-size: 0.8125rem !important; + font-size: var(--text-small) !important; color: var(--text-muted); } /* TOC links — softer colors aligned with landing muted text */ #nd-toc a { font-weight: 430 !important; - font-size: 0.8125rem !important; + font-size: var(--text-small) !important; color: var(--text-muted); transition: color 0.2s; } @@ -905,7 +945,7 @@ html #nd-sidebar a:has(span.font-mono.font-medium) { align-items: center; justify-content: center; width: 2.625rem; - font-size: 0.625rem !important; + font-size: var(--text-micro) !important; line-height: 1 !important; padding: 0.15625rem 0.25rem; border-radius: 0.375rem; @@ -917,7 +957,7 @@ html #nd-sidebar a:has(span.font-mono.font-medium) { display: inline-flex; align-items: center; justify-content: center; - font-size: 0.625rem !important; + font-size: var(--text-micro) !important; line-height: 1 !important; padding: 0.15625rem 0.375rem; border-radius: 0.375rem; @@ -984,7 +1024,7 @@ div.flex.flex-row.items-start.bg-fd-secondary.border.rounded-lg.text-xs { span.font-mono.font-medium { font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif !important; font-weight: 600 !important; - font-size: 0.6875rem !important; + font-size: var(--text-xs) !important; letter-spacing: 0.025em; text-transform: uppercase; padding: 0.125rem 0.5rem !important; @@ -1033,7 +1073,7 @@ div.flex.flex-row.items-start.bg-fd-secondary.border.rounded-lg.text-xs { background: none !important; border: none !important; padding: 0 !important; - font-size: 0.8125rem !important; + font-size: var(--text-small) !important; } /* Inline code in API pages — neutral color aligned with sim design. Exclude code inside the method+path bar (handled above). */ @@ -1213,7 +1253,7 @@ div.flex.flex-row.items-start.bg-fd-secondary.border.rounded-lg.text-xs { color: var(--text-secondary); padding: 0.1875rem 0.5rem; border-radius: 0.375rem; - font-size: 0.6875rem; + font-size: var(--text-xs); line-height: 1.125rem; font-weight: 500; font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; @@ -1223,7 +1263,6 @@ html.dark .flex.flex-wrap.items-center.gap-3.not-prose > span.text-sm.font-mono.text-fd-muted-foreground { background-color: var(--surface-4); - color: var(--text-secondary); } /* Hide the "*" inside the name span — we'll add "required" as a ::after on the flex row */ @@ -1242,7 +1281,7 @@ html.dark color: var(--badge-error-text); padding: 0.1875rem 0.5rem; border-radius: 0.375rem; - font-size: 0.6875rem; + font-size: var(--text-xs); line-height: 1.125rem; font-weight: 500; font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; @@ -1284,7 +1323,7 @@ html.dark > .flex.flex-wrap.items-center.gap-3.not-prose > span.text-sm.font-mono.text-fd-muted-foreground::after { content: "string"; - font-size: 0.6875rem; + font-size: var(--text-xs); line-height: 1.125rem; font-weight: 500; font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; @@ -1301,7 +1340,6 @@ html.dark > .flex.flex-wrap.items-center.gap-3.not-prose > span.text-sm.font-mono.text-fd-muted-foreground::after { background-color: var(--surface-4); - color: var(--text-secondary); } /* "header" badge via ::before on the auth flex row */ @@ -1314,7 +1352,7 @@ html.dark color: var(--text-secondary); padding: 0.1875rem 0.5rem; border-radius: 0.375rem; - font-size: 0.6875rem; + font-size: var(--text-xs); line-height: 1.125rem; font-weight: 500; font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; @@ -1324,7 +1362,6 @@ html.dark div.my-4 > .flex.flex-wrap.items-center.gap-3.not-prose::before { background-color: var(--surface-4); - color: var(--text-secondary); } /* "required" badge via ::after on the auth flex row — red pill */ @@ -1337,7 +1374,7 @@ html.dark color: var(--badge-error-text); padding: 0.1875rem 0.5rem; border-radius: 0.375rem; - font-size: 0.6875rem; + font-size: var(--text-xs); line-height: 1.125rem; font-weight: 500; font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; @@ -1389,7 +1426,7 @@ html.dark color: var(--text-secondary); padding: 0.1875rem 0.5rem; border-radius: 0.375rem; - font-size: 0.6875rem; + font-size: var(--text-xs); line-height: 1.125rem; font-weight: 500; font-family: var(--font-geist-sans), ui-sans-serif, system-ui, sans-serif; @@ -1400,7 +1437,6 @@ html.dark .flex.flex-wrap.items-center.gap-3.not-prose > span:has(> button) { background-color: var(--surface-4); - color: var(--text-secondary); } /* Section headings (Authorization, Path Parameters, etc.) — consistent top spacing */ @@ -1562,10 +1598,6 @@ div > figure.shiki { box-shadow: none !important; } -html.dark div > figure.shiki { - background-color: transparent !important; -} - /* Tabbed code block container (cURL/JS/Go tabs) */ div:has(> [role="tablist"]):has(> div > figure.shiki) { border-radius: 0.5rem !important; @@ -1610,19 +1642,11 @@ figure.shiki pre { background-color: transparent !important; } -html.dark figure.shiki pre { - background-color: transparent !important; -} - /* Code viewport scroll area — transparent bg */ figure.shiki > div[role="region"] { background-color: transparent !important; } -html.dark figure.shiki > div[role="region"] { - background-color: transparent !important; -} - /* Copy button — minimal ghost style */ figure.shiki button[aria-label="Copy Text"], figure.shiki button[aria-label="Copied Text"] { @@ -1690,7 +1714,7 @@ figure.shiki > div:has(> button[aria-label]) { .grid > a[data-card] p, .grid > a[data-card] div { color: var(--text-muted) !important; - font-size: 0.8125rem !important; + font-size: var(--text-small) !important; } /* Steps — lighter styling aligned with platform */ diff --git a/apps/docs/components/docs-layout/page-footer.tsx b/apps/docs/components/docs-layout/page-footer.tsx index 7031211fe84..2b4f289e811 100644 --- a/apps/docs/components/docs-layout/page-footer.tsx +++ b/apps/docs/components/docs-layout/page-footer.tsx @@ -12,81 +12,40 @@ interface PageFooterProps { next?: PageNeighbour } -const SOCIAL_LINKS = [ - { - href: 'https://x.com/simdotai', - label: 'X (Twitter)', - icon: 'M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z', - }, - { - href: 'https://github.com/simstudioai/sim', - label: 'GitHub', - icon: 'M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z', - }, - { - href: 'https://join.slack.com/t/sim-ott9864/shared_invite/zt-43lp8tc5v-0qrrqHGBKUsvQlpoouH~TA', - label: 'Slack', - icon: 'M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z', - }, -] as const - +/** + * Sequential page navigation. The destination name carries the meaning, so each + * card shows it alone with a direction chevron — the chevron already says which + * way you are going, and a "Previous"/"Next" label above the name only repeated + * that. Social links live in the site footer directly below this. + */ export function PageFooter({ previous, next }: PageFooterProps) { - return ( -
-
- - {(previous || next) && ( -
- {previous ? ( - - Previous - - - {previous.name} - - - ) : ( -
- )} + if (!previous && !next) return null - {next ? ( - - Next - - {next.name} - - - - ) : ( -
- )} -
+ return ( +
+ {previous ? ( + + + {previous.name} + + ) : ( +
)} -
- {SOCIAL_LINKS.map((link) => ( - - - - - - ))} -
+ {next ? ( + + {next.name} + + + ) : ( +
+ )}
) } diff --git a/apps/docs/components/docs-layout/sidebar-components.tsx b/apps/docs/components/docs-layout/sidebar-components.tsx index e646b071895..6a603fc856e 100644 --- a/apps/docs/components/docs-layout/sidebar-components.tsx +++ b/apps/docs/components/docs-layout/sidebar-components.tsx @@ -40,18 +40,29 @@ function isActive(url: string, pathname: string, nested = true): boolean { ) } +/** + * Rows mirror the app sidebar's chip pill: 30px tall, `rounded-lg`, `px-2`, 14px + * at normal weight, `--text-body` at rest AND when active — only the background + * moves, to `--surface-active`, then `--surface-6` when an active row is hovered. + * + * Height, horizontal padding, weight and color are additionally pinned in + * `global.css` (`html #nd-sidebar a…`), which needs `!important` to beat + * fumadocs' own sidebar rules and therefore also beats these utilities. Keep the + * two in step: the classes here describe the intent and drive the mobile layout, + * the stylesheet is what actually lands on desktop. + */ const ITEM_BASE = - 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-[var(--text-muted)] text-sm transition-colors hover:bg-[var(--surface-active)] hover:text-[var(--text-body)]' -const ITEM_ACTIVE_MOBILE = 'bg-[var(--surface-active)] font-medium text-[var(--text-primary)]' + 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-[var(--text-body)] text-sm transition-colors hover:bg-[var(--surface-active)]' +const ITEM_ACTIVE_MOBILE = 'bg-[var(--surface-active)]' const ITEM_DESKTOP = - 'lg:mb-[0.0625rem] lg:block lg:rounded-lg lg:px-2 lg:py-1.5 lg:font-normal lg:text-sm lg:leading-tight' + 'lg:mb-[0.0625rem] lg:block lg:rounded-lg lg:px-2 lg:font-normal lg:text-sm lg:leading-tight' const ITEM_TEXT = 'lg:text-[var(--text-body)]' const ITEM_HOVER = 'lg:hover:bg-[var(--surface-active)]' const ITEM_ACTIVE = 'lg:bg-[var(--surface-active)] lg:font-normal lg:text-[var(--text-body)] lg:hover:bg-[var(--surface-6)]' -const FOLDER_TEXT = 'lg:text-[var(--text-body)] lg:font-medium' +const FOLDER_TEXT = 'lg:text-[var(--text-body)] lg:font-normal' const FOLDER_HOVER = 'lg:hover:bg-[var(--surface-active)]' const FOLDER_ACTIVE = 'lg:bg-[var(--surface-active)] lg:text-[var(--text-body)] lg:hover:bg-[var(--surface-6)]' @@ -133,9 +144,9 @@ export function SidebarFolder({ item, children }: { item: Folder; children: Reac data-active={active} className={cn( 'flex flex-1 items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors', - 'text-[var(--text-muted)] hover:bg-[var(--surface-active)] hover:text-[var(--text-body)]', + 'text-[var(--text-body)] hover:bg-[var(--surface-active)]', active && ITEM_ACTIVE_MOBILE, - 'lg:block lg:flex-1 lg:rounded-lg lg:px-2 lg:py-1.5 lg:text-sm lg:leading-tight', + 'lg:block lg:flex-1 lg:rounded-lg lg:px-2 lg:text-sm lg:leading-tight', FOLDER_TEXT, !active && FOLDER_HOVER, active && FOLDER_ACTIVE @@ -161,8 +172,8 @@ export function SidebarFolder({ item, children }: { item: Folder; children: Reac onClick={toggleOpen} className={cn( 'flex flex-1 items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors', - 'text-[var(--text-muted)] hover:bg-[var(--surface-active)]', - 'lg:flex lg:w-full lg:cursor-pointer lg:items-center lg:justify-between lg:rounded-lg lg:px-2 lg:py-1.5 lg:text-left lg:text-sm lg:leading-tight', + 'text-[var(--text-body)] hover:bg-[var(--surface-active)]', + 'lg:flex lg:w-full lg:cursor-pointer lg:items-center lg:justify-between lg:rounded-lg lg:px-2 lg:text-left lg:text-sm lg:leading-tight', FOLDER_TEXT, FOLDER_HOVER )} @@ -181,9 +192,7 @@ export function SidebarFolder({ item, children }: { item: Folder; children: Reac >
{children}
-
    - {children} -
+
    {children}
)} @@ -191,25 +200,16 @@ export function SidebarFolder({ item, children }: { item: Folder; children: Reac ) } +/** + * Group label. Mirrors the app sidebar's section header: a 12px `--text-muted` + * row at normal weight in sentence case, with the group's 16px top gap carried + * by the label itself (the app's `SIDEBAR_SECTION_GAP_CLASS`). Groups are told + * apart by that gap alone — the app draws no rule between them. + */ export function SidebarSeparator({ item }: { item: Separator }) { return ( -
-
-
-
-
-
-

- {item.name} -

+
+

{item.name}

) } diff --git a/apps/docs/components/footer/footer.tsx b/apps/docs/components/footer/footer.tsx index 1c20bb53d1b..698aa012475 100644 --- a/apps/docs/components/footer/footer.tsx +++ b/apps/docs/components/footer/footer.tsx @@ -21,7 +21,7 @@ interface FooterItem { const PRODUCT_LINKS: FooterItem[] = [ { label: 'Enterprise', href: `${SIM_SITE_URL}/enterprise`, external: true }, - { label: 'Mothership', href: '/mothership' }, + { label: 'Chat', href: '/chat' }, { label: 'Workflows', href: '/introduction' }, { label: 'Knowledge Base', href: '/knowledgebase' }, { label: 'Tables', href: '/tables' }, diff --git a/apps/docs/components/navbar/navbar.tsx b/apps/docs/components/navbar/navbar.tsx index 8b2ee8fcc2a..d6d23260800 100644 --- a/apps/docs/components/navbar/navbar.tsx +++ b/apps/docs/components/navbar/navbar.tsx @@ -75,7 +75,7 @@ export function Navbar() { aria-current={isActive ? 'page' : undefined} {...(tab.external ? { target: '_blank', rel: 'noopener noreferrer' } : {})} className={cn( - '-mb-px relative flex items-center border-b text-[14px] tracking-[-0.01em] transition-colors', + '-mb-px relative flex items-center border-b text-sm tracking-[-0.01em] transition-colors', isActive ? 'border-[var(--text-muted)] font-medium text-[var(--text-primary)]' : 'border-transparent font-normal text-[var(--text-muted)] hover:border-[var(--border-1)] hover:text-[var(--text-secondary)]' diff --git a/apps/docs/components/page-type-badge.tsx b/apps/docs/components/page-type-badge.tsx deleted file mode 100644 index df46fd1d962..00000000000 --- a/apps/docs/components/page-type-badge.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import type { DocsPageType } from '@/lib/source' -import { cn } from '@/lib/utils' - -/** - * Status-color mapping mirrored from the emcn `Badge` variants - * (`apps/sim/components/emcn/components/badge/badge.tsx`) — `green`, `blue`, - * `purple`, and `amber` over the shared `--badge-*` tokens. - */ -const CONFIG = { - tutorial: { - label: 'Tutorial', - className: 'bg-[var(--badge-success-bg)] text-[var(--badge-success-text)]', - }, - guide: { - label: 'Guide', - className: 'bg-[var(--badge-blue-bg)] text-[var(--badge-blue-text)]', - }, - reference: { - label: 'Reference', - className: 'bg-[var(--badge-purple-bg)] text-[var(--badge-purple-text)]', - }, - concept: { - label: 'Concept', - className: 'bg-[var(--badge-amber-bg)] text-[var(--badge-amber-text)]', - }, -} as const satisfies Record - -interface PageTypeBadgeProps { - type: DocsPageType - className?: string -} - -/** - * Small label that tells the reader which Diátaxis mode a page is — learning, - * task, lookup, or understanding. Rendered only when a page declares `type`. - * Chrome matches the emcn `Badge` status variants (md size). - */ -export function PageTypeBadge({ type, className }: PageTypeBadgeProps) { - const config = CONFIG[type] - if (!config) return null - - return ( - - {config.label} - - ) -} diff --git a/apps/docs/components/ui/faq.tsx b/apps/docs/components/ui/faq.tsx index 7a7c0eec62f..d9a9b6134b1 100644 --- a/apps/docs/components/ui/faq.tsx +++ b/apps/docs/components/ui/faq.tsx @@ -30,7 +30,7 @@ function FAQItemRow({ type='button' onClick={onToggle} aria-expanded={isOpen} - className='flex w-full cursor-pointer items-center gap-3 px-4 py-2.5 text-left font-medium text-[0.875rem] text-[var(--text-body)] transition-colors hover:bg-[var(--surface-3)]' + className='flex w-full cursor-pointer items-center gap-3 px-4 py-2.5 text-left font-medium text-[var(--text-body)] text-sm transition-colors hover:bg-[var(--surface-active)]' >
-
+
{item.answer}
@@ -58,7 +58,21 @@ function FAQItemRow({ } export function FAQ({ items, title = 'Common Questions' }: FAQProps) { - const [openIndex, setOpenIndex] = useState(null) + /** + * Rows open independently rather than as a single-open accordion. Auto-closing + * a sibling collapses content *above* the row being opened, which yanks that + * row out from under the pointer — and since the FAQ is the last block on the + * page, the shrinking document also clamps the scroll position and lurches the + * whole viewport. Opening a row now only ever pushes content below it down. + */ + const [openIndices, setOpenIndices] = useState>(() => new Set()) + + const toggle = (index: number) => + setOpenIndices((previous) => { + const next = new Set(previous) + if (!next.delete(index)) next.add(index) + return next + }) const faqSchema = { '@context': 'https://schema.org', @@ -88,8 +102,8 @@ export function FAQ({ items, title = 'Common Questions' }: FAQProps) { > setOpenIndex(openIndex === index ? null : index)} + isOpen={openIndices.has(index)} + onToggle={() => toggle(index)} />
))} diff --git a/apps/docs/components/ui/sim-logo.tsx b/apps/docs/components/ui/sim-logo.tsx index f505e778c91..84f77d81d95 100644 --- a/apps/docs/components/ui/sim-logo.tsx +++ b/apps/docs/components/ui/sim-logo.tsx @@ -1,6 +1,3 @@ -'use client' - -import { useId } from 'react' import { cn } from '@/lib/utils' interface SimLogoProps { @@ -32,107 +29,3 @@ export function SimWordmark({ className }: SimLogoProps) { ) } - -/** - * Icon-only Sim mark, no wordmark text. Same brandbook icon geometry as - * {@link SimLogoFull}'s icon, at its native square viewBox. - */ -export function SimLogoIcon({ className }: SimLogoProps) { - const gradientId = `sim-logo-icon-gradient-${useId()}` - - return ( - - - - - - - - - - - - ) -} - -/** - * Full Sim logo with icon and "Sim" text. - * Uses the same SVG source as the landing page navbar for exact visual alignment. - * The icon stays green (#33C482), text adapts to light/dark mode. - */ -export function SimLogoFull({ className }: SimLogoProps) { - const gradientId = `sim-logo-full-gradient-${useId()}` - - return ( - - - - - - - - {/* Green icon — scaled to match landing logo proportions */} - - - - - - {/* "Sim" text — adapts to light/dark mode */} - - - - - - - ) -} diff --git a/apps/docs/components/ui/video.tsx b/apps/docs/components/ui/video.tsx index 888d5244a06..f3b1f4f9e0b 100644 --- a/apps/docs/components/ui/video.tsx +++ b/apps/docs/components/ui/video.tsx @@ -18,7 +18,7 @@ interface VideoProps { export function Video({ src, - className = 'w-full rounded-xl border border-[var(--border)] overflow-hidden outline-none focus:outline-none', + className = 'w-full', autoPlay = true, loop = true, muted = true, @@ -70,8 +70,9 @@ export function Video({ width={width} height={height} className={cn( - className, - enableLightbox && 'cursor-pointer transition-opacity group-hover:opacity-[0.97]' + 'overflow-hidden rounded-xl border border-[var(--border)] outline-none focus:outline-none', + enableLightbox && 'cursor-pointer transition-opacity group-hover:opacity-[0.97]', + className )} src={isInView ? getAssetUrl(src) : undefined} /> diff --git a/apps/docs/content/docs/en/academy/chat/building.mdx b/apps/docs/content/docs/en/academy/chat/building.mdx index ca2fd54dbdd..355ae305628 100644 --- a/apps/docs/content/docs/en/academy/chat/building.mdx +++ b/apps/docs/content/docs/en/academy/chat/building.mdx @@ -33,7 +33,7 @@ You can build a whole workflow without dragging a single block. Describe the sys }, { title: 'Deploy from the conversation', - body: "One more message and the workflow is live behind an endpoint, from blank canvas to working system without leaving the chat.", + body: "One more message and the workflow is live behind an endpoint, from blank canvas to working system without leaving Chat.", }, ]} /> @@ -58,9 +58,9 @@ You can build a whole workflow without dragging a single block. Describe the sys ## From description to blocks -The chat turns your description into real structure: a parallel container drafting candidate posts, generation blocks for the image, the deck, and the voiceover, an evaluator scoring the results, and a table keeping every score. Nothing about the result is special, it's a normal workflow you could have built by hand, which means you can open it, read it, and change it. +Sim turns your description into real structure: a parallel container drafting candidate posts, generation blocks for the image, the deck, and the voiceover, an evaluator scoring the results, and a table keeping every score. Nothing about the result is special, it's a normal workflow you could have built by hand, which means you can open it, read it, and change it. -Here is the shape of the workflow the chat builds in the video, candidates drafted in parallel, an evaluator scoring them, and the scores kept in a table: +Here is the shape of the workflow Sim builds in the video, candidates drafted in parallel, an evaluator scoring them, and the scores kept in a table: @@ -77,13 +77,13 @@ The run record shows every step with its timing and output: the draft, the image Deploying is one more message in the conversation. The workflow deploys behind a live endpoint, ready for whatever you send it, and it remains a workflow in your workspace: inspectable, schedulable, and callable from everything else you build. ## Related documentation -- [Building workflows from chat](/mothership/workflows) +- [Building workflows from Chat](/chat/workflows) - [Deployment](/workflows/deployment) diff --git a/apps/docs/content/docs/en/academy/chat/intro.mdx b/apps/docs/content/docs/en/academy/chat/intro.mdx index c39951319f7..f4b66107e0d 100644 --- a/apps/docs/content/docs/en/academy/chat/intro.mdx +++ b/apps/docs/content/docs/en/academy/chat/intro.mdx @@ -1,6 +1,6 @@ --- title: Chat -description: "The chat in Sim is your workspace control plane: one conversation that queries your tables, searches your docs, runs and schedules workflows, researches the outside world, and composes it all into new systems." +description: "Chat is your AI command center: one conversation that queries your tables, searches your docs, runs and schedules workflows, researches the outside world, and composes it all into new systems." --- import { VideoPlaceholder } from '@/components/ui/video-placeholder' @@ -15,7 +15,7 @@ import { AV_SUPPORT_DESK_WORKFLOW } from '@/components/workflow-preview/academy-
-The chat lives inside your workspace, and everything in it, your workflows, tables, knowledge bases, and files, is within its reach. You ask from one place, and Sim works across all of it: answering from your data, operating your workflows, and shaping new systems around the task. +Chat lives inside your workspace, and everything in it, your workflows, tables, knowledge bases, and files, is within its reach. You ask from one place, and Sim works across all of it: answering from your data, operating your workflows, and shaping new systems around the task. ## Asking it to act -Telling the chat to *do* something is the same motion as asking it something. Run the backlog through the support desk, ship the weekly digest, put it on a schedule for Friday mornings: each lands as a real operation, confirmed with a toast, with the run's log available the moment it finishes. +Telling Sim to *do* something is the same motion as asking it something. Run the backlog through the support desk, ship the weekly digest, put it on a schedule for Friday mornings: each lands as a real operation, confirmed with a toast, with the run's log available the moment it finishes. ## Research beyond the workspace -The chat can research beyond your workspace: search X and Reddit for this week's conversations, pull the rising themes, and file them as a new document. What it learns becomes a resource like any other, ready for the next ask. +Sim can research beyond your workspace: search X and Reddit for this week's conversations, pull the rising themes, and file them as a new document. What it learns becomes a resource like any other, ready for the next ask. ## Composing a new workflow -One sentence can compose what the chat just touched into a new workflow. A watcher that reads the trends file on a schedule, matches them against your tickets, and calls your support-desk workflow when something hits. You described it, and the chat assembled it from the resources you already have. +One sentence can compose what Sim just touched into a new workflow. A watcher that reads the trends file on a schedule, matches them against your tickets, and calls your support-desk workflow when something hits. You described it, and Sim assembled it from the resources you already have. ## Related documentation -- [Chat overview](/mothership) -- [Operating workflows from chat](/mothership/workflows) -- [Research from chat](/mothership/research) +- [Chat overview](/chat) +- [Operating workflows from Chat](/chat/workflows) +- [Research from Chat](/chat/research) diff --git a/apps/docs/content/docs/en/agents/choosing.mdx b/apps/docs/content/docs/en/agents/choosing.mdx index 84c6e3adfe1..f888b836ee7 100644 --- a/apps/docs/content/docs/en/agents/choosing.mdx +++ b/apps/docs/content/docs/en/agents/choosing.mdx @@ -1,7 +1,6 @@ --- title: Choosing what to use description: Pick between a deterministic block, an agent tool, a custom tool, an MCP server, a workflow-as-tool, and a skill. -pageType: concept --- import { Callout } from 'fumadocs-ui/components/callout' diff --git a/apps/docs/content/docs/en/agents/custom-tools.mdx b/apps/docs/content/docs/en/agents/custom-tools.mdx index 9648b00910e..0a2eb82d517 100644 --- a/apps/docs/content/docs/en/agents/custom-tools.mdx +++ b/apps/docs/content/docs/en/agents/custom-tools.mdx @@ -1,7 +1,6 @@ --- title: Custom Tools description: Create your own tools with JavaScript code and use them in Agent blocks -pageType: guide --- import { Callout } from 'fumadocs-ui/components/callout' diff --git a/apps/docs/content/docs/en/agents/index.mdx b/apps/docs/content/docs/en/agents/index.mdx index 73069186092..1ffa134d3cd 100644 --- a/apps/docs/content/docs/en/agents/index.mdx +++ b/apps/docs/content/docs/en/agents/index.mdx @@ -1,7 +1,6 @@ --- title: Overview description: An agent is a workflow that reasons and acts, built around Agent blocks and the features you give them. -pageType: concept --- import { Callout } from 'fumadocs-ui/components/callout' diff --git a/apps/docs/content/docs/en/agents/mcp.mdx b/apps/docs/content/docs/en/agents/mcp.mdx index 90155b3ca73..9391b4d2171 100644 --- a/apps/docs/content/docs/en/agents/mcp.mdx +++ b/apps/docs/content/docs/en/agents/mcp.mdx @@ -1,7 +1,6 @@ --- title: Using MCP tools description: Connect external tools and services using the Model Context Protocol -pageType: guide --- import { Image } from '@/components/ui/image' diff --git a/apps/docs/content/docs/en/agents/meta.json b/apps/docs/content/docs/en/agents/meta.json new file mode 100644 index 00000000000..b4bd6af6a7d --- /dev/null +++ b/apps/docs/content/docs/en/agents/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Agents", + "pages": ["index", "choosing", "custom-tools", "mcp", "skills"] +} diff --git a/apps/docs/content/docs/en/agents/skills.mdx b/apps/docs/content/docs/en/agents/skills.mdx index bd608982d3e..65f55068313 100644 --- a/apps/docs/content/docs/en/agents/skills.mdx +++ b/apps/docs/content/docs/en/agents/skills.mdx @@ -1,7 +1,6 @@ --- title: Agent skills description: Reusable instruction packages your agents load on demand, managed from the Skills tab. -pageType: guide --- import { Callout } from 'fumadocs-ui/components/callout' diff --git a/apps/docs/content/docs/en/mothership/files.mdx b/apps/docs/content/docs/en/chat/files.mdx similarity index 60% rename from apps/docs/content/docs/en/mothership/files.mdx rename to apps/docs/content/docs/en/chat/files.mdx index 64eb36960e1..88071469c12 100644 --- a/apps/docs/content/docs/en/mothership/files.mdx +++ b/apps/docs/content/docs/en/chat/files.mdx @@ -9,23 +9,23 @@ import { FAQ } from '@/components/ui/faq'