diff --git a/.claude/rules/emcn-components.md b/.claude/rules/emcn-components.md
index f02ff3946e5..fd57ee5c00c 100644
--- a/.claude/rules/emcn-components.md
+++ b/.claude/rules/emcn-components.md
@@ -56,3 +56,17 @@ Declare keyboard intent on the action-owning primitive; never add document-level
- Use Radix UI primitives for accessibility. Export the component and its `variants` (when using CVA). Document with TSDoc + a usage example.
Color tokens and icon-size conventions are canonical in `.claude/rules/sim-styling.md` — follow it rather than restating.
+
+
+## Ordinary Button action geometry
+
+`Button` retains its existing appearance variants. For square actions use `iconSize`:
+`compact` (24px on the spacing scale), `compact-fixed` (24px), `regular` (28px),
+`roomy` (32px), or `touch` (40px). These values follow the root spacing scale;
+only `compact-fixed` stays fixed when root text is enlarged.
+Use `{ base: 'touch', sm: 'regular' }` for mobile/desktop targets. These props own
+geometry only; colour, radius and SVG stroke continue to come from the selected
+`variant` and `size`. `iconPadding` explicitly overrides the zero-padding geometry.
+Use `shape='round'` for circular actions, or omit it to retain the current radius.
+`size='inline'` is a 20px-high action with caption typography and compact horizontal
+padding. Prefer these supported props to size, padding and radius overrides.
diff --git a/.cursor/rules/emcn-components.mdc b/.cursor/rules/emcn-components.mdc
index 1ac5fc577f8..3f5cd1bf90e 100644
--- a/.cursor/rules/emcn-components.mdc
+++ b/.cursor/rules/emcn-components.mdc
@@ -57,3 +57,17 @@ Declare keyboard intent on the action-owning primitive; never add document-level
- Use Radix UI primitives for accessibility. Export the component and its `variants` (when using CVA). Document with TSDoc + a usage example.
Color tokens and icon-size conventions are canonical in `.claude/rules/sim-styling.md` — follow it rather than restating.
+
+
+## Ordinary Button action geometry
+
+`Button` retains its existing appearance variants. For square actions use `iconSize`:
+`compact` (24px on the spacing scale), `compact-fixed` (24px), `regular` (28px),
+`roomy` (32px), or `touch` (40px). These values follow the root spacing scale;
+only `compact-fixed` stays fixed when root text is enlarged.
+Use `{ base: 'touch', sm: 'regular' }` for mobile/desktop targets. These props own
+geometry only; colour, radius and SVG stroke continue to come from the selected
+`variant` and `size`. `iconPadding` explicitly overrides the zero-padding geometry.
+Use `shape='round'` for circular actions, or omit it to retain the current radius.
+`size='inline'` is a 20px-high action with caption typography and compact horizontal
+padding. Prefer these supported props to size, padding and radius overrides.
diff --git a/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx b/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx
index ceb2b0b709b..6ec4de4377e 100644
--- a/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/components/find-bar/find-bar.tsx
@@ -129,7 +129,8 @@ export const FindBar = memo(function FindBar({
type='button'
variant='ghost'
size='icon'
- className='size-6 shrink-0'
+ iconSize='compact'
+ className='shrink-0'
aria-label={showReplace ? 'Hide replace' : 'Show replace'}
aria-expanded={showReplace}
onClick={() => setShowReplace((visible) => !visible)}
@@ -179,7 +180,8 @@ export const FindBar = memo(function FindBar({
type='button'
variant='ghost'
size='icon'
- className='size-6 shrink-0'
+ iconSize='compact'
+ className='shrink-0'
aria-label='Previous match'
title='Previous match (Shift+Enter)'
disabled={!navEnabled}
@@ -191,7 +193,8 @@ export const FindBar = memo(function FindBar({
type='button'
variant='ghost'
size='icon'
- className='size-6 shrink-0'
+ iconSize='compact'
+ className='shrink-0'
aria-label='Next match'
title='Next match (Enter)'
disabled={!navEnabled}
@@ -203,7 +206,8 @@ export const FindBar = memo(function FindBar({
type='button'
variant='ghost'
size='icon'
- className='size-6 shrink-0'
+ iconSize='compact'
+ className='shrink-0'
aria-label='Close find'
title='Close (Esc)'
onClick={onClose}
diff --git a/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx b/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx
index 0f57c5c0551..e2aa9d94339 100644
--- a/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.test.tsx
@@ -1,7 +1,7 @@
/**
* @vitest-environment jsdom
*/
-import { act, type ReactNode } from 'react'
+import { act, type ComponentProps, type ReactNode } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
@@ -19,6 +19,11 @@ vi.mock('next/navigation', () => ({
}))
vi.mock('@sim/emcn', () => ({
+ Button: ({
+ variant,
+ iconSize,
+ ...props
+ }: ComponentProps<'button'> & { variant?: string; iconSize?: string }) => ,
Check: () => null,
Duplicate: () => null,
Split: () => null,
diff --git a/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.tsx b/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.tsx
index 6207a1e247a..28780a945dd 100644
--- a/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/components/message-actions/message-actions.tsx
@@ -2,6 +2,7 @@
import { memo, useEffect, useRef, useState } from 'react'
import {
+ Button,
Check,
ChipModal,
ChipModalBody,
@@ -27,8 +28,6 @@ import { useForkMothershipChat } from '@/hooks/queries/mothership-chats'
import { useFolderStore } from '@/stores/folders/store'
const ICON_CLASS = 'size-[14px]'
-const BUTTON_CLASS =
- 'flex size-[26px] items-center justify-center rounded-[6px] text-[var(--text-icon)] transition-colors hover-hover:bg-[var(--surface-hover)] focus-visible:outline-hidden'
interface MessageActionsProps {
content: string
@@ -162,14 +161,15 @@ export const MessageActions = memo(function MessageActions({
{canCopyContent && (
-
+
{copied ? 'Copied message' : 'Copy message'}
@@ -180,27 +180,29 @@ export const MessageActions = memo(function MessageActions({
<>
-
+
Good response
-
+
Bad response
@@ -209,15 +211,16 @@ export const MessageActions = memo(function MessageActions({
{canFork && (
-
+
Fork in new chat
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx
index a3f9e23198d..8313c2c549e 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-content/components/browser-session/browser-find-bar.tsx
@@ -106,7 +106,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro
size='sm'
aria-label='Previous match'
disabled={!result?.matches}
- className='size-[24px] shrink-0 p-0'
+ iconSize='compact-fixed'
+ className='shrink-0'
onClick={() => step('back')}
>
@@ -117,7 +118,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro
size='sm'
aria-label='Next match'
disabled={!result?.matches}
- className='size-[24px] shrink-0 p-0'
+ iconSize='compact-fixed'
+ className='shrink-0'
onClick={() => step('forward')}
>
@@ -127,7 +129,8 @@ export function BrowserFindBar({ inputRef, onClose, scopeId }: BrowserFindBarPro
variant='ghost-secondary'
size='sm'
aria-label='Close find bar'
- className='size-[24px] shrink-0 p-0'
+ iconSize='compact-fixed'
+ className='shrink-0'
onClick={dismiss}
>
diff --git a/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/file-download/file-download.tsx b/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/file-download/file-download.tsx
index 8d310f38b29..064baa45326 100644
--- a/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/file-download/file-download.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/logs/components/log-details/components/file-download/file-download.tsx
@@ -106,11 +106,7 @@ function FileCard({ file, isExecutionFile = false, workspaceId }: FileCardProps)
{file.type}
{file.version === undefined ? '' : ` · v${file.version}`}
-