diff --git a/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss b/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss index 2cff88556f..c379adeacf 100644 --- a/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss +++ b/src/web-ui/src/app/components/NavPanel/sections/sessions/SessionsSection.scss @@ -138,7 +138,7 @@ &.is-active { color: var(--color-text-primary); - background: var(--element-bg-soft); + background: transparent; } &.is-editing { @@ -187,10 +187,13 @@ } &.is-btw-child { - &:hover, - &.is-active { + &:hover { background: var(--element-bg-soft); } + + &.is-active { + background: transparent; + } } } @@ -890,8 +893,8 @@ } &.is-active { - background: var(--element-bg-medium); - box-shadow: inset 2px 0 0 color-mix(in srgb, var(--color-accent-500) 76%, transparent); + background: transparent; + box-shadow: none; } } diff --git a/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss b/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss index 30eebbd5e3..ec63d296b0 100644 --- a/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss +++ b/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceListSection.scss @@ -178,7 +178,7 @@ overflow: hidden; border-radius: 6px; color: var(--color-text-primary); - background: var(--color-bg-primary); + background: transparent; transition: color $motion-fast $easing-standard, background $motion-fast $easing-standard, box-shadow $motion-fast $easing-standard; @@ -1063,7 +1063,7 @@ max-width: 100%; border-radius: 6px; color: var(--color-text-secondary); - background: var(--color-bg-primary); + background: transparent; overflow: hidden; transition: color $motion-fast $easing-standard, background $motion-fast $easing-standard, @@ -1360,8 +1360,8 @@ &__workspace-item.is-active &__workspace-item-card, &__assistant-item.is-active &__assistant-item-card { - background: var(--element-bg-medium); - box-shadow: inset 2px 0 0 color-mix(in srgb, var(--color-accent-500) 76%, transparent); + background: transparent; + box-shadow: none; } &__workspace-item-card:active, @@ -1438,7 +1438,7 @@ .bitfun-nav-panel__workspace-item.is-active .bitfun-nav-panel__workspace-item-card:hover, .bitfun-nav-panel__assistant-item.is-active .bitfun-nav-panel__assistant-item-card:hover { - background: var(--element-bg-medium); + background: transparent; } } diff --git a/src/web-ui/src/app/scenes/settings/SettingsNav.scss b/src/web-ui/src/app/scenes/settings/SettingsNav.scss index dd3ee4fad4..698cd9b8cf 100644 --- a/src/web-ui/src/app/scenes/settings/SettingsNav.scss +++ b/src/web-ui/src/app/scenes/settings/SettingsNav.scss @@ -119,7 +119,7 @@ &.is-active { color: var(--color-text-primary); - background: var(--element-bg-soft); + background: transparent; font-weight: 500; } @@ -256,9 +256,9 @@ &.is-active { color: var(--color-text-primary); - background: color-mix(in srgb, var(--color-accent-500) 10%, var(--element-bg-soft)); + background: transparent; font-weight: 500; - box-shadow: inset 2px 0 0 var(--color-accent-500); + box-shadow: none; } &:focus-visible { diff --git a/src/web-ui/src/flow_chat/components/ChatInput.scss b/src/web-ui/src/flow_chat/components/ChatInput.scss index 7062e5273c..6fb99ce30a 100644 --- a/src/web-ui/src/flow_chat/components/ChatInput.scss +++ b/src/web-ui/src/flow_chat/components/ChatInput.scss @@ -705,9 +705,7 @@ } &:focus-within { - border-color: color-mix(in srgb, var(--color-accent-500) 46%, var(--border-base)); - box-shadow: - 0 0 0 2px color-mix(in srgb, var(--color-accent-500) 12%, transparent), + box-shadow: 0 12px 30px rgba(var(--color-static-black-rgb), 0.28), inset 0 1px 0 var(--color-overlay-white-12); } diff --git a/src/web-ui/src/flow_chat/components/modern/ExploreRegion.scss b/src/web-ui/src/flow_chat/components/modern/ExploreRegion.scss index 6b956f72e6..fa78d32649 100644 --- a/src/web-ui/src/flow_chat/components/modern/ExploreRegion.scss +++ b/src/web-ui/src/flow_chat/components/modern/ExploreRegion.scss @@ -3,6 +3,11 @@ .explore-region { position: relative; overflow: hidden; + /* Same column box as .model-round-item so the collapse header (`>`) and the + * round's body text share one leading edge. */ + box-sizing: border-box; + width: min(100%, 900px); + margin: 0 auto; padding: 0 var(--flowchat-content-inline-pad); @media (max-width: 768px) { diff --git a/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss b/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss index 645c65e79b..cd92063b1b 100644 --- a/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss +++ b/src/web-ui/src/flow_chat/components/modern/UserMessageItem.scss @@ -6,12 +6,12 @@ .user-message-item { box-sizing: border-box; - width: fit-content; - min-width: min( - 18rem, - calc(100% - var(--flowchat-content-inline-pad) - var(--flowchat-content-inline-pad)) - ); - max-width: min(78%, 52rem); + /* + * Fills the reading column instead of hugging its text: the bubble shares the + * exact leading and trailing edge as the tool-call bars and body text below + * it, so a turn reads as one column rather than a right-floating chat bubble. + */ + width: auto; padding: 0.46rem 0.68rem; background: color-mix(in srgb, var(--element-bg-medium) 90%, var(--color-bg-scene)); border: 1px solid color-mix(in srgb, var(--border-base) 72%, transparent); @@ -20,7 +20,7 @@ 0.06rem var(--flowchat-content-inline-pad) var(--flowchat-turn-gap) - auto; + var(--flowchat-content-inline-pad); box-shadow: 0 1px 0 color-mix(in srgb, var(--color-static-white) 5%, transparent) inset, 0 2px 8px var(--color-overlay-black-08); @@ -61,18 +61,7 @@ // Responsive: reduce margins on smaller screens. @media (max-width: 768px) { - min-width: min( - 14rem, - calc( - 100% - var(--flowchat-content-inline-pad-mobile) - - var(--flowchat-content-inline-pad-mobile) - ) - ); - max-width: calc( - 100% - var(--flowchat-content-inline-pad-mobile) - - var(--flowchat-content-inline-pad-mobile) - ); - margin-left: auto; + margin-left: var(--flowchat-content-inline-pad-mobile); margin-right: var(--flowchat-content-inline-pad-mobile); } } @@ -198,11 +187,6 @@ border: none; box-shadow: none; padding-left: 0.35rem; - width: auto; - min-width: 0; - max-width: none; - margin-left: var(--flowchat-content-inline-pad); - margin-right: var(--flowchat-content-inline-pad); .user-message-item__main { align-items: flex-start; @@ -517,14 +501,15 @@ .user-message-item__images { display: flex; flex-wrap: wrap; - gap: 5px; - margin-top: 4px; + gap: 6px; + margin-top: 6px; } .user-message-item__image-thumb { - width: 120px; - height: 120px; - border-radius: 6px; + /* Attachment-sized, not a hero image: the text stays the primary content. */ + width: 72px; + height: 72px; + border-radius: 5px; overflow: hidden; cursor: pointer; border: 1px solid var(--border-base); diff --git a/src/web-ui/src/flow_chat/components/modern/VirtualItemRenderer.scss b/src/web-ui/src/flow_chat/components/modern/VirtualItemRenderer.scss index 6e951da8db..02e2aaad15 100644 --- a/src/web-ui/src/flow_chat/components/modern/VirtualItemRenderer.scss +++ b/src/web-ui/src/flow_chat/components/modern/VirtualItemRenderer.scss @@ -5,6 +5,11 @@ .virtual-item-wrapper { width: 100%; + /* + * Single reading column shared by every item type (model rounds, explore + * groups, user messages, notices). Matches ChatInput's 900px so headers, + * `>` collapse rows, and bubbles all sit on the same leading edge. + */ max-width: 900px; margin: 0 auto; box-sizing: border-box; diff --git a/src/web-ui/src/infrastructure/config/components/BasicsConfig.scss b/src/web-ui/src/infrastructure/config/components/BasicsConfig.scss index e51c256f4b..5f0ba35467 100644 --- a/src/web-ui/src/infrastructure/config/components/BasicsConfig.scss +++ b/src/web-ui/src/infrastructure/config/components/BasicsConfig.scss @@ -14,10 +14,6 @@ gap: 16px; } - &__select-wrapper { - width: 100%; - } - &__path-row { display: flex; align-items: stretch; @@ -86,10 +82,6 @@ gap: $size-gap-6; } - &__select-wrapper { - width: 100%; - } - &__shell-option, &__shell-value { display: flex; @@ -123,6 +115,7 @@ } &__no-shells { + width: 100%; padding: 12px 16px; border: 1px dashed var(--border-base); border-radius: $size-radius-sm; diff --git a/src/web-ui/src/infrastructure/config/components/BasicsConfig.tsx b/src/web-ui/src/infrastructure/config/components/BasicsConfig.tsx index ee27fef826..ba47a214af 100644 --- a/src/web-ui/src/infrastructure/config/components/BasicsConfig.tsx +++ b/src/web-ui/src/infrastructure/config/components/BasicsConfig.tsx @@ -525,14 +525,12 @@ function BasicsLoggingSection() { description={t('logging.level.description')} align="center" > -
- handleLevelChange(v as string)} + options={levelOptions} + disabled={saving} + /> -
- {availableShells.length > 0 ? ( - handleShellChange(v as string)} + options={shellOptions} + renderOption={renderShellOption} + renderValue={renderShellValue} + placeholder={t('terminal.controls.placeholder')} + disabled={saving} + /> + ) : ( +
{t('terminal.controls.noShells')}
+ )} -
- handleTerminalPanelPositionChange(v as TerminalPanelPosition)} + options={terminalPanelPositionOptions} + placeholder={t('terminal.panelPosition.placeholder')} + disabled={saving} + />
@@ -903,14 +897,12 @@ function BasicsWindowBehaviorSection() { description={t('windowBehavior.closeButtonDescription')} align="center" > -
- { void handleChange(v as string); }} + options={behaviorOptions} + disabled={saving} + />
diff --git a/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss b/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss index 7d33be32bb..b2c46cfe80 100644 --- a/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss +++ b/src/web-ui/src/infrastructure/config/components/ExternalSourcesConfig.scss @@ -37,14 +37,19 @@ position: relative; } - .bitfun-config-page-section__body { - border: 0; - border-radius: 0; - background: transparent; + /* + * Sections keep the shared card surface from ConfigPageLayout, so every + * bespoke block below carries the same horizontal gutter a + * `.bitfun-config-page-row` uses. Custom content then lines up with standard + * rows and its separators run edge to edge like theirs. + */ + .bitfun-config-page-section__body > .bitfun-external-sources-config__notice { + margin: var(--size-gap-3) var(--size-gap-4); } - .bitfun-config-page-row { - padding: 12px 0; + .bitfun-config-page-section__body > .bitfun-external-sources-config__capability-grid { + padding-right: var(--size-gap-4); + padding-left: var(--size-gap-4); } &__ecosystem-heading, @@ -108,7 +113,7 @@ align-items: center; gap: 4px; min-height: 36px; - padding: 2px 0 0; + padding: var(--size-gap-2) var(--size-gap-4) 0; background: transparent; > button { @@ -164,7 +169,7 @@ display: flex; align-items: center; gap: 8px; - padding: 8px 12px; + padding: 8px var(--size-gap-4); border-left: 2px solid var(--color-warning); color: var(--color-text-primary); background: color-mix(in srgb, var(--color-warning) 7%, transparent); @@ -190,7 +195,7 @@ align-items: center; justify-content: space-between; gap: 16px; - padding: 12px 0; + padding: 12px var(--size-gap-4); background: transparent; border-top: 1px solid var(--border-subtle); } @@ -216,7 +221,12 @@ } } - &__policy-actions .select { + /* + * Ecosystem mode and per-capability access are the same control at two + * levels — one width so they read as a single column of dropdowns. + */ + &__policy-actions .select, + &__capability-row .select { min-width: 142px; } @@ -269,10 +279,6 @@ display: grid; gap: 4px; } - - .select { - min-width: 128px; - } } &__notice, @@ -447,7 +453,7 @@ } &__conflict { - padding: 12px 0; + padding: 12px var(--size-gap-4); border-bottom: 1px solid var(--border-subtle); &:last-child { @@ -457,6 +463,10 @@ &__tool-card { padding: 10px 0 10px 14px; + /* Accent bar stays inside the card, so inset the whole block rather than + * padding it — otherwise the bar would sit on the card border. */ + margin-right: var(--size-gap-4); + margin-left: var(--size-gap-4); border-left: 2px solid var(--border-subtle); background: transparent; overflow-wrap: anywhere; @@ -491,7 +501,7 @@ } &__opencode-card { - padding: 12px 0; + padding: 12px var(--size-gap-4); border-top: 1px solid var(--border-subtle); border-radius: 0; margin-bottom: 0; @@ -552,7 +562,7 @@ font-size: 13px; display: grid; gap: 8px; - padding: 12px 0; + padding: 12px var(--size-gap-4); code { font-size: 12px; diff --git a/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss b/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss index 086dd9b7a2..cf8d75839e 100644 --- a/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss +++ b/src/web-ui/src/infrastructure/config/components/McpToolsConfig.scss @@ -1,25 +1,15 @@ @use '../../../component-library/styles/tokens' as *; .bitfun-mcp-tools { - .bitfun-config-page-section__body { - border: 0; - border-radius: 0; - background: transparent; - } - - .bitfun-config-page-row { - padding: $size-gap-3 0; - } + // Server rows, empty states and the JSON editor all sit inside the shared + // section card (see ConfigPageLayout) — no page-level chrome overrides here, + // so this page reads like every other settings page. - .bitfun-collection-empty { - justify-content: flex-start; - padding: $size-gap-2 0; - font-size: var(--font-size-xs); - } // ─── JSON editor (MCP) ───────────────────────────────────────────────────── &__json-editor { - padding: $size-gap-3 0; - border-bottom: 1px solid var(--border-subtle); + // Replaces the server list inside the section card, so it carries the same + // gutter a `.bitfun-config-page-row` would. + padding: $size-gap-4; display: flex; flex-direction: column; gap: $size-gap-3; @@ -205,7 +195,8 @@ justify-content: space-between; gap: 12px; padding: 10px 12px; - margin-bottom: 8px; + /* Inset callout: keeps the import prompt clear of the section card border. */ + margin: $size-gap-3 $size-gap-4; border: 1px solid var(--border-subtle); border-radius: 8px; diff --git a/src/web-ui/src/infrastructure/config/components/common/ConfigPageLayout.scss b/src/web-ui/src/infrastructure/config/components/common/ConfigPageLayout.scss index 3ad09076d1..1e48ef2bc3 100644 --- a/src/web-ui/src/infrastructure/config/components/common/ConfigPageLayout.scss +++ b/src/web-ui/src/infrastructure/config/components/common/ConfigPageLayout.scss @@ -195,6 +195,18 @@ min-width: 0; } + /* + * Safety net for pages that wrap a control in a positioning/state div: an + * unstyled wrapper is a flex item, so it would shrink to content width and + * that row's dropdown would render narrower than every other row's. + */ + > div:has(> .select), + > div:has(> .bitfun-input-wrapper), + > div:has(> .bitfun-number-input) { + width: 100%; + min-width: 0; + } + > .bitfun-number-input .bitfun-number-input__input { text-align: left; }