diff --git a/frontend/src/App.tool-center.test.ts b/frontend/src/App.tool-center.test.ts
index 219f6e05..88748d89 100644
--- a/frontend/src/App.tool-center.test.ts
+++ b/frontend/src/App.tool-center.test.ts
@@ -10,6 +10,10 @@ const appCss = readFileSync(
fileURLToPath(new globalThis.URL('./App.css', import.meta.url)),
'utf8',
);
+const v2ThemeCss = readFileSync(
+ fileURLToPath(new globalThis.URL('./v2-theme.css', import.meta.url)),
+ 'utf8',
+);
const linuxCJKFontBannerSource = readFileSync(
fileURLToPath(new globalThis.URL('./components/LinuxCJKFontBanner.tsx', import.meta.url)),
'utf8',
@@ -321,7 +325,7 @@ describe('tool center menu entries', () => {
['newConnection', 'handleCreateConnection();'],
['toggleAIPanel', 'toggleAIPanel();'],
['toggleLogPanel', 'handleToggleLogPanel();'],
- ['toggleTheme', 'setTheme('],
+ ['toggleTheme', 'setThemePreference('],
['openShortcutManager', 'setIsShortcutModalOpen(true);'],
['toggleMacFullscreen', 'handleTitleBarWindowToggle({ allowMacNativeFullscreen: true });'],
['resetWindowZoom', 'handleManualResetWindowZoom();'],
@@ -410,12 +414,20 @@ describe('global appearance tokens', () => {
expect(appSource).toContain("setProperty('--gn-font-size-mono'");
expect(appSource).toContain("setProperty('--gn-data-table-font-size'");
expect(appSource).toContain("setProperty('--gn-sidebar-tree-font-size'");
+ expect(appSource).toContain("setProperty('--gn-sidebar-rail-scale'");
expect(appSource).toContain("setProperty('--gn-control-height'");
expect(appSource).toContain("setProperty('--gn-control-height-sm'");
expect(appSource).toContain('fontFamily: resolvedUiFontFamily');
expect(appSource).toContain('fontFamilyCode: resolvedMonoFontFamily');
+ expect(appSource).toContain('const effectiveSidebarRailScale = sanitizeV2SidebarRailScale(appearance.v2SidebarRailScale);');
+ expect(appSource).toContain("t('app.theme.appearance.sidebar_rail_scale_title')");
+ expect(appSource).toContain("t('app.theme.appearance.sidebar_rail_scale_hint')");
+ expect(appSource).toContain('v2SidebarRailScale: sanitizeV2SidebarRailScale(value)');
expect(appSource).toContain("t('app.theme.data_table.font_size')");
expect(appSource).toContain("t('app.theme.data_table.sidebar_tree_font_size')");
+ expect(v2ThemeCss).toContain('--gn-sidebar-rail-scale');
+ expect(v2ThemeCss).toContain('font-size: calc(var(--gn-font-size-sm, 12px) * var(--gn-sidebar-rail-scale, 1));');
+ expect(v2ThemeCss).toContain('width: calc(38px * var(--gn-v2-rail-scale));');
expect(appSource).toContain("const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';");
expect(appSource).toContain("t('app.theme.data_table.table_double_click_action')");
expect(appSource).toContain("t('app.theme.data_table.table_double_click_action.open_data')");
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 7912d1bb..073f7851 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -21,7 +21,13 @@ import SecurityUpdateIntroModal from './components/SecurityUpdateIntroModal';
import SecurityUpdateProgressModal from './components/SecurityUpdateProgressModal';
import SecurityUpdateSettingsModal from './components/SecurityUpdateSettingsModal';
import LanguageSettingsPanel from './components/LanguageSettingsPanel';
-import { DEFAULT_APPEARANCE, useStore } from './store';
+import {
+ DEFAULT_APPEARANCE,
+ MAX_V2_SIDEBAR_RAIL_SCALE,
+ MIN_V2_SIDEBAR_RAIL_SCALE,
+ sanitizeV2SidebarRailScale,
+ useStore,
+} from './store';
import { SavedConnection, SecurityUpdateIssue, SecurityUpdateStatus } from './types';
import { blurToFilter, normalizeBlurForPlatform, normalizeOpacityForPlatform, isWindowsPlatform, resolveAppearanceValues } from './utils/appearance';
import { buildFontFamilyOptions, DEFAULT_MONO_FONT_FAMILY, DEFAULT_UI_FONT_FAMILY, getLinuxCJKFontInstallHint, matchFontFamilyOption, resolveMonoFontFamily, resolveUIFontFamily, sanitizeFontFamilyInput, type FontFamilyOption, type InstalledFontFamily } from './utils/fontFamilies';
@@ -271,6 +277,7 @@ function App() {
const effectiveSidebarTreeFontSize = sidebarTreeFontSizeFollowsGlobal
? effectiveFontSize
: (sanitizeSidebarTreeFontSize(appearance.sidebarTreeFontSize) ?? effectiveFontSize);
+ const effectiveSidebarRailScale = sanitizeV2SidebarRailScale(appearance.v2SidebarRailScale);
const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';
const tabDisplaySettings = useMemo(
() => sanitizeTabDisplaySettings(appearance.tabDisplay),
@@ -2727,6 +2734,7 @@ function App() {
document.documentElement.style.setProperty('--gn-font-size-mono', `${Math.max(10, Math.round(effectiveDataTableFontSize * 0.92))}px`);
document.documentElement.style.setProperty('--gn-data-table-font-size', `${effectiveDataTableFontSize}px`);
document.documentElement.style.setProperty('--gn-sidebar-tree-font-size', `${effectiveSidebarTreeFontSize}px`);
+ document.documentElement.style.setProperty('--gn-sidebar-rail-scale', `${effectiveSidebarRailScale}`);
document.documentElement.style.setProperty('--gn-control-height', `${tokenControlHeight}px`);
document.documentElement.style.setProperty('--gn-control-height-sm', `${tokenControlHeightSM}px`);
}, [
@@ -2737,6 +2745,7 @@ function App() {
resolvedMonoFontFamily,
resolvedUiFontFamily,
runtimePlatform,
+ effectiveSidebarRailScale,
effectiveSidebarTreeFontSize,
effectiveUiScale,
tokenControlHeight,
@@ -4693,6 +4702,27 @@ function App() {
{effectiveFontSize}px
+ {appearance.uiVersion === 'v2' && (
+
{t('app.theme.font_family.title')}
diff --git a/frontend/src/store.test.ts b/frontend/src/store.test.ts
index ca2ac8c8..c36e1c94 100644
--- a/frontend/src/store.test.ts
+++ b/frontend/src/store.test.ts
@@ -73,6 +73,7 @@ describe('store appearance persistence', () => {
expect(appearance.v2SidebarSearchMode).toBe('command');
expect(appearance.v2CommandSearchPersistentFilterEnabled).toBe(false);
expect(appearance.v2SidebarPersistedFilter).toBe('');
+ expect(appearance.v2SidebarRailScale).toBe(1);
expect(appearance.showDataTableVerticalBorders).toBe(false);
expect(appearance.dataTableDensity).toBe('comfortable');
expect(appearance.dataTableFontSize).toBeNull();
@@ -95,12 +96,14 @@ describe('store appearance persistence', () => {
showDataTableVerticalBorders: true,
dataTableDensity: 'compact',
tableDoubleClickAction: 'open-design',
+ v2SidebarRailScale: 1.55,
});
const persisted = JSON.parse(storage.getItem('lite-db-storage') || '{}');
expect(persisted.state.appearance.showDataTableVerticalBorders).toBe(true);
expect(persisted.state.appearance.dataTableDensity).toBe('compact');
expect(persisted.state.appearance.tableDoubleClickAction).toBe('open-design');
+ expect(persisted.state.appearance.v2SidebarRailScale).toBe(1.55);
vi.resetModules();
const reloaded = await importStore();
@@ -109,6 +112,7 @@ describe('store appearance persistence', () => {
expect(appearance.showDataTableVerticalBorders).toBe(true);
expect(appearance.dataTableDensity).toBe('compact');
expect(appearance.tableDoubleClickAction).toBe('open-design');
+ expect(appearance.v2SidebarRailScale).toBe(1.55);
});
it('restores query tabs from crash-recovery snapshots even when persisted tabs are missing', async () => {
@@ -158,6 +162,20 @@ describe('store appearance persistence', () => {
expect(useStore.getState().appearance.tableDoubleClickAction).toBe('open-data');
});
+ it('sanitizes persisted v2 sidebar rail scale settings into the supported range', async () => {
+ storage.setItem('lite-db-storage', JSON.stringify({
+ state: {
+ appearance: {
+ v2SidebarRailScale: 99,
+ },
+ },
+ version: 13,
+ }));
+
+ const { useStore } = await importStore();
+ expect(useStore.getState().appearance.v2SidebarRailScale).toBe(1);
+ });
+
it('persists language preference and sanitizes unsupported persisted values', async () => {
const { useStore } = await importStore();
diff --git a/frontend/src/store.ts b/frontend/src/store.ts
index 59aa4f46..1f2244d6 100644
--- a/frontend/src/store.ts
+++ b/frontend/src/store.ts
@@ -102,12 +102,17 @@ export interface AppearanceSettings extends DataGridDisplaySettings {
v2SidebarSearchMode: "command" | "filter";
v2CommandSearchPersistentFilterEnabled: boolean;
v2SidebarPersistedFilter: string;
+ v2SidebarRailScale: number;
customUIFontFamily: string | null;
customMonoFontFamily: string | null;
tabDisplay: TabDisplaySettings;
redisDbAliases: RedisDbAliasMap;
}
+export const DEFAULT_V2_SIDEBAR_RAIL_SCALE = 1.0;
+export const MIN_V2_SIDEBAR_RAIL_SCALE = 1.0;
+export const MAX_V2_SIDEBAR_RAIL_SCALE = 1.8;
+
export const DEFAULT_APPEARANCE: AppearanceSettings = {
uiVersion: "legacy",
enabled: true,
@@ -118,6 +123,7 @@ export const DEFAULT_APPEARANCE: AppearanceSettings = {
v2SidebarSearchMode: "command",
v2CommandSearchPersistentFilterEnabled: false,
v2SidebarPersistedFilter: "",
+ v2SidebarRailScale: DEFAULT_V2_SIDEBAR_RAIL_SCALE,
customUIFontFamily: null,
customMonoFontFamily: null,
tabDisplay: DEFAULT_TAB_DISPLAY_SETTINGS,
@@ -153,6 +159,16 @@ const sanitizeV2SidebarPersistedFilter = (value: unknown): string => {
}
return value.trim().slice(0, MAX_SIDEBAR_PERSISTED_FILTER_LENGTH);
};
+
+export const sanitizeV2SidebarRailScale = (value: unknown): number => {
+ return normalizeFloatInRange(
+ value,
+ DEFAULT_V2_SIDEBAR_RAIL_SCALE,
+ MIN_V2_SIDEBAR_RAIL_SCALE,
+ MAX_V2_SIDEBAR_RAIL_SCALE,
+ );
+};
+
const MAX_URI_LENGTH = 4096;
const MAX_HOST_ENTRY_LENGTH = 512;
const MAX_HOST_ENTRIES = 64;
@@ -2193,6 +2209,9 @@ const sanitizeAppearance = (
v2SidebarPersistedFilter: sanitizeV2SidebarPersistedFilter(
appearance.v2SidebarPersistedFilter,
),
+ v2SidebarRailScale: sanitizeV2SidebarRailScale(
+ appearance.v2SidebarRailScale,
+ ),
customUIFontFamily: sanitizeFontFamilyInput(appearance.customUIFontFamily),
customMonoFontFamily: sanitizeFontFamilyInput(appearance.customMonoFontFamily),
tabDisplay: sanitizeTabDisplaySettings(appearance.tabDisplay),
diff --git a/frontend/src/v2-theme.css b/frontend/src/v2-theme.css
index c2f2705d..3775d9df 100644
--- a/frontend/src/v2-theme.css
+++ b/frontend/src/v2-theme.css
@@ -1762,6 +1762,7 @@ body[data-ui-version="v2"] .gn-v2-app-sider {
}
body[data-ui-version="v2"] .gn-v2-sidebar-redesign {
+ --gn-v2-rail-scale: calc(var(--gn-ui-scale, 1) * var(--gn-sidebar-rail-scale, 1));
width: 100%;
background: var(--gn-bg-panel-2);
border-right: 0.5px solid var(--gn-br-1);
@@ -1769,14 +1770,14 @@ body[data-ui-version="v2"] .gn-v2-sidebar-redesign {
}
body[data-ui-version="v2"] .gn-v2-connection-rail {
- width: calc(38px * var(--gn-ui-scale, 1));
- flex: 0 0 calc(38px * var(--gn-ui-scale, 1));
+ width: calc(38px * var(--gn-v2-rail-scale));
+ flex: 0 0 calc(38px * var(--gn-v2-rail-scale));
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
- gap: calc(4px * var(--gn-ui-scale, 1));
- padding: calc(8px * var(--gn-ui-scale, 1)) 0;
+ gap: calc(4px * var(--gn-v2-rail-scale));
+ padding: calc(8px * var(--gn-v2-rail-scale)) 0;
border-right: 0.5px solid var(--gn-br-1);
background: transparent;
}
@@ -1787,10 +1788,10 @@ body[data-ui-version="v2"] .gn-v2-rail-items {
display: flex;
flex-direction: column;
align-items: center;
- gap: calc(4px * var(--gn-ui-scale, 1));
+ gap: calc(4px * var(--gn-v2-rail-scale));
width: 100%;
box-sizing: border-box;
- padding-top: calc(4px * var(--gn-ui-scale, 1));
+ padding-top: calc(4px * var(--gn-v2-rail-scale));
overflow-x: hidden;
overflow-y: auto;
scrollbar-width: thin;
@@ -1811,26 +1812,26 @@ body[data-ui-version="v2"] .gn-v2-rail-group {
display: flex;
flex-direction: column;
align-items: center;
- gap: calc(3px * var(--gn-ui-scale, 1));
+ gap: calc(3px * var(--gn-v2-rail-scale));
}
body[data-ui-version="v2"] .gn-v2-rail-group + .gn-v2-rail-group {
- padding-top: calc(5px * var(--gn-ui-scale, 1));
+ padding-top: calc(5px * var(--gn-v2-rail-scale));
border-top: 0.5px solid var(--gn-br-1);
}
body[data-ui-version="v2"] .gn-v2-rail-group-header {
position: relative;
width: 100%;
- min-height: calc(24px * var(--gn-ui-scale, 1));
+ min-height: calc(24px * var(--gn-v2-rail-scale));
overflow: visible;
border: none;
border-radius: 0;
display: flex;
align-items: center;
justify-content: flex-start;
- gap: 4px;
- padding: 0 4px 0 6px;
+ gap: calc(4px * var(--gn-v2-rail-scale));
+ padding: 0 calc(4px * var(--gn-v2-rail-scale)) 0 calc(6px * var(--gn-v2-rail-scale));
background: transparent;
color: var(--gn-fg-5);
box-shadow: none;
@@ -1845,7 +1846,7 @@ body[data-ui-version="v2"] .gn-v2-rail-group-chevron {
position: static;
display: inline-flex;
color: var(--gn-fg-5);
- font-size: 9px;
+ font-size: calc(9px * var(--gn-v2-rail-scale));
line-height: 1;
transform: rotate(0deg);
transition: transform 120ms ease;
@@ -1870,18 +1871,18 @@ body[data-ui-version="v2"] .gn-v2-rail-group-count {
position: absolute;
top: -1px;
right: -1px;
- min-width: 16px;
- height: 16px;
+ min-width: calc(16px * var(--gn-v2-rail-scale));
+ height: calc(16px * var(--gn-v2-rail-scale));
border-radius: 999px;
display: inline-flex;
align-items: center;
justify-content: center;
- padding: 0 4px;
+ padding: 0 calc(4px * var(--gn-v2-rail-scale));
border: 2px solid var(--gn-bg-panel-2);
background: var(--gn-accent);
color: #fff;
font-family: var(--gn-font-mono);
- font-size: 9px;
+ font-size: calc(9px * var(--gn-v2-rail-scale));
font-weight: 800;
line-height: 1;
}
@@ -1891,7 +1892,7 @@ body[data-ui-version="v2"] .gn-v2-rail-group-items {
display: flex;
flex-direction: column;
align-items: center;
- gap: calc(4px * var(--gn-ui-scale, 1));
+ gap: calc(4px * var(--gn-v2-rail-scale));
}
body[data-ui-version="v2"] .gn-v2-rail-primary-actions,
@@ -1900,16 +1901,16 @@ body[data-ui-version="v2"] .gn-v2-rail-secondary-actions {
display: flex;
flex-direction: column;
align-items: center;
- gap: calc(6px * var(--gn-ui-scale, 1));
+ gap: calc(6px * var(--gn-v2-rail-scale));
}
body[data-ui-version="v2"] .gn-v2-rail-primary-actions {
- padding-top: calc(4px * var(--gn-ui-scale, 1));
+ padding-top: calc(4px * var(--gn-v2-rail-scale));
}
body[data-ui-version="v2"] .gn-v2-rail-secondary-actions {
margin-top: auto;
- padding-bottom: calc(4px * var(--gn-ui-scale, 1));
+ padding-bottom: calc(4px * var(--gn-v2-rail-scale));
}
body[data-ui-version="v2"] .gn-v2-rail-action-group,
@@ -1917,11 +1918,11 @@ body[data-ui-version="v2"] .gn-v2-rail-system-actions {
display: flex;
flex-direction: column;
align-items: center;
- gap: calc(4px * var(--gn-ui-scale, 1));
+ gap: calc(4px * var(--gn-v2-rail-scale));
}
body[data-ui-version="v2"] .gn-v2-rail-action-group {
- padding-bottom: calc(6px * var(--gn-ui-scale, 1));
+ padding-bottom: calc(6px * var(--gn-v2-rail-scale));
border-bottom: 0.5px solid var(--gn-br-1);
}
@@ -1942,13 +1943,13 @@ body[data-ui-version="v2"] .gn-v2-rail-action:disabled {
body[data-ui-version="v2"] .gn-v2-rail-item,
body[data-ui-version="v2"] .gn-v2-rail-tool {
position: relative;
- width: calc(36px * var(--gn-ui-scale, 1));
- height: calc(38px * var(--gn-ui-scale, 1));
- border-radius: calc(9px * var(--gn-ui-scale, 1));
+ width: calc(36px * var(--gn-v2-rail-scale));
+ height: calc(38px * var(--gn-v2-rail-scale));
+ border-radius: calc(9px * var(--gn-v2-rail-scale));
border: none;
background: transparent;
color: var(--gn-fg-4);
- font-size: var(--gn-font-size-sm, 12px);
+ font-size: calc(var(--gn-font-size-sm, 12px) * var(--gn-sidebar-rail-scale, 1));
display: flex;
align-items: center;
justify-content: center;
@@ -1957,9 +1958,9 @@ body[data-ui-version="v2"] .gn-v2-rail-tool {
}
body[data-ui-version="v2"] .gn-v2-rail-tool {
- width: calc(24px * var(--gn-ui-scale, 1));
- height: calc(32px * var(--gn-ui-scale, 1));
- border-radius: calc(8px * var(--gn-ui-scale, 1));
+ width: calc(24px * var(--gn-v2-rail-scale));
+ height: calc(32px * var(--gn-v2-rail-scale));
+ border-radius: calc(8px * var(--gn-v2-rail-scale));
justify-content: center;
padding: 0;
}
@@ -1977,11 +1978,11 @@ body[data-ui-version="v2"] .gn-v2-rail-item.is-active {
body[data-ui-version="v2"] .gn-v2-rail-active-bar {
display: none;
position: absolute;
- left: -8px;
- top: 7px;
- bottom: 7px;
- width: 3px;
- border-radius: 3px;
+ left: calc(-8px * var(--gn-v2-rail-scale));
+ top: calc(7px * var(--gn-v2-rail-scale));
+ bottom: calc(7px * var(--gn-v2-rail-scale));
+ width: calc(3px * var(--gn-v2-rail-scale));
+ border-radius: calc(3px * var(--gn-v2-rail-scale));
background: var(--gn-accent);
}
@@ -1991,22 +1992,22 @@ body[data-ui-version="v2"] .gn-v2-rail-item.is-active .gn-v2-rail-active-bar {
body[data-ui-version="v2"] .gn-v2-rail-icon {
display: flex;
- width: 24px;
- height: 24px;
+ width: calc(24px * var(--gn-v2-rail-scale));
+ height: calc(24px * var(--gn-v2-rail-scale));
align-items: center;
justify-content: center;
}
body[data-ui-version="v2"] .gn-v2-rail-badge {
- width: 22px;
- height: 22px;
- border-radius: 6px;
+ width: calc(22px * var(--gn-v2-rail-scale));
+ height: calc(22px * var(--gn-v2-rail-scale));
+ border-radius: calc(6px * var(--gn-v2-rail-scale));
display: inline-flex;
align-items: center;
justify-content: center;
color: #fff;
font-family: var(--gn-font-mono);
- font-size: 9.5px;
+ font-size: calc(9.5px * var(--gn-sidebar-rail-scale, 1));
font-weight: 800;
line-height: 1;
box-shadow: inset 0 0.5px 0 rgba(255,255,255,0.3), 0 0.5px 1px rgba(0,0,0,0.2);
@@ -2015,9 +2016,9 @@ body[data-ui-version="v2"] .gn-v2-rail-badge {
body[data-ui-version="v2"] .gn-v2-rail-badge-wrap {
position: relative;
- width: 22px;
- height: 22px;
- flex: 0 0 22px;
+ width: calc(22px * var(--gn-v2-rail-scale));
+ height: calc(22px * var(--gn-v2-rail-scale));
+ flex: 0 0 calc(22px * var(--gn-v2-rail-scale));
}
body[data-ui-version="v2"] .gn-v2-rail-fallback {
@@ -2026,12 +2027,12 @@ body[data-ui-version="v2"] .gn-v2-rail-fallback {
body[data-ui-version="v2"] .gn-v2-rail-status {
position: absolute;
- right: -2px;
- bottom: -2px;
- width: 8px;
- height: 8px;
+ right: calc(-2px * var(--gn-v2-rail-scale));
+ bottom: calc(-2px * var(--gn-v2-rail-scale));
+ width: calc(8px * var(--gn-v2-rail-scale));
+ height: calc(8px * var(--gn-v2-rail-scale));
border-radius: 50%;
- border: 1.5px solid var(--gn-bg-panel);
+ border: calc(1.5px * var(--gn-sidebar-rail-scale, 1)) solid var(--gn-bg-panel);
background: var(--gn-fg-5);
}
@@ -2044,16 +2045,16 @@ body[data-ui-version="v2"] .gn-v2-rail-status.is-error {
}
body[data-ui-version="v2"] .gn-v2-rail-create-button {
- margin-top: 4px;
- width: calc(40px * var(--gn-ui-scale, 1));
- height: calc(40px * var(--gn-ui-scale, 1));
+ margin-top: calc(4px * var(--gn-v2-rail-scale));
+ width: calc(40px * var(--gn-v2-rail-scale));
+ height: calc(40px * var(--gn-v2-rail-scale));
border: 1px dashed var(--gn-br-2);
- border-radius: calc(14px * var(--gn-ui-scale, 1));
+ border-radius: calc(14px * var(--gn-v2-rail-scale));
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
- gap: 6px;
+ gap: calc(6px * var(--gn-v2-rail-scale));
padding: 0;
color: var(--gn-fg-5);
background: transparent;
@@ -2064,9 +2065,9 @@ body[data-ui-version="v2"] .gn-v2-rail-create-button:hover {
}
body[data-ui-version="v2"] .gn-v2-rail-create-icon {
- width: 24px;
- height: 24px;
- border-radius: 8px;
+ width: calc(24px * var(--gn-v2-rail-scale));
+ height: calc(24px * var(--gn-v2-rail-scale));
+ border-radius: calc(8px * var(--gn-v2-rail-scale));
display: inline-flex;
align-items: center;
justify-content: center;
@@ -2077,13 +2078,13 @@ body[data-ui-version="v2"] .gn-v2-rail-create-icon {
body[data-ui-version="v2"] .gn-v2-rail-create-label {
color: var(--gn-fg-5);
- font-size: 10px;
+ font-size: calc(10px * var(--gn-sidebar-rail-scale, 1));
line-height: 1;
}
body[data-ui-version="v2"] .gn-v2-object-explorer {
min-width: 0;
- flex: 1 1 calc(100% - 38px);
+ flex: 1 1 calc(100% - calc(38px * var(--gn-v2-rail-scale)));
background: var(--gn-bg-panel-2);
overflow: hidden;
}
diff --git a/shared/i18n/de-DE.json b/shared/i18n/de-DE.json
index eca35794..c8ee3515 100644
--- a/shared/i18n/de-DE.json
+++ b/shared/i18n/de-DE.json
@@ -2678,6 +2678,8 @@
"app.theme.appearance.transparency_blur_title": "Transparenz- und Weichzeichnungseffekte",
"app.theme.appearance.ui_scale_hint": "* Für kleine Bildschirme werden 85%-95% empfohlen",
"app.theme.appearance.ui_scale_title": "UI-Skalierung (UI Scale)",
+ "app.theme.appearance.sidebar_rail_scale_hint": "Wirkt sich nur auf die linke V2-Navigationsleiste aus und vergrößert dort Buttons und Verbindungsicons für große Displays.",
+ "app.theme.appearance.sidebar_rail_scale_title": "Größe der linken Navigationsbuttons",
"app.theme.appearance.windows_acrylic_hint": "Windows verwendet den systemeigenen Acrylic-Effekt. Die Unschärfestärke wird vom System gesteuert.",
"app.theme.data_table.column_width_hint": "Der Standardmodus nutzt 200px, der kompakte Modus 140px als Standardspaltenbreite. Manuell angepasste Spaltenbreiten bleiben vorrangig erhalten.",
"app.theme.data_table.column_width_mode": "Spaltenbreitenmodus der Datentabelle",
diff --git a/shared/i18n/en-US.json b/shared/i18n/en-US.json
index 78559f9f..3e074063 100644
--- a/shared/i18n/en-US.json
+++ b/shared/i18n/en-US.json
@@ -2678,6 +2678,8 @@
"app.theme.appearance.transparency_blur_title": "Transparency and Blur Effects",
"app.theme.appearance.ui_scale_hint": "* Recommended for small screens: 85%-95%",
"app.theme.appearance.ui_scale_title": "UI Scale (UI Scale)",
+ "app.theme.appearance.sidebar_rail_scale_hint": "Only affects the V2 left navigation rail. Use it to enlarge buttons and connection icons on large displays.",
+ "app.theme.appearance.sidebar_rail_scale_title": "Left Navigation Button Size",
"app.theme.appearance.windows_acrylic_hint": "Windows uses the system Acrylic effect. Blur intensity is controlled by the system.",
"app.theme.data_table.column_width_hint": "Standard mode defaults to 200px; compact mode defaults to 140px. Manually adjusted column widths are preserved first.",
"app.theme.data_table.column_width_mode": "Data Table Column Width Mode",
diff --git a/shared/i18n/ja-JP.json b/shared/i18n/ja-JP.json
index 4defc880..11f0d328 100644
--- a/shared/i18n/ja-JP.json
+++ b/shared/i18n/ja-JP.json
@@ -2678,6 +2678,8 @@
"app.theme.appearance.transparency_blur_title": "透明度とぼかし効果",
"app.theme.appearance.ui_scale_hint": "* 小さい画面では 85%-95% を推奨します",
"app.theme.appearance.ui_scale_title": "UI スケール (UI Scale)",
+ "app.theme.appearance.sidebar_rail_scale_hint": "V2 左側ナビゲーションレールにのみ適用されます。大画面でボタンや接続アイコンを見やすく拡大できます。",
+ "app.theme.appearance.sidebar_rail_scale_title": "左側ナビゲーションボタンのサイズ",
"app.theme.appearance.windows_acrylic_hint": "Windows ではシステムの Acrylic 効果を使用します。ぼかしの強さはシステムにより制御されます。",
"app.theme.data_table.column_width_hint": "標準モードの既定列幅は 200px、コンパクトモードの既定列幅は 140px です。手動で調整した列幅は優先して保持されます。",
"app.theme.data_table.column_width_mode": "データテーブル列幅モード",
diff --git a/shared/i18n/ru-RU.json b/shared/i18n/ru-RU.json
index 366713e0..9ed07a1b 100644
--- a/shared/i18n/ru-RU.json
+++ b/shared/i18n/ru-RU.json
@@ -2678,6 +2678,8 @@
"app.theme.appearance.transparency_blur_title": "Эффекты прозрачности и размытия",
"app.theme.appearance.ui_scale_hint": "* Для небольших экранов рекомендуется 85%-95%",
"app.theme.appearance.ui_scale_title": "Масштаб UI (UI Scale)",
+ "app.theme.appearance.sidebar_rail_scale_hint": "Влияет только на левую навигационную панель V2 и помогает увеличить кнопки и значки подключений на больших экранах.",
+ "app.theme.appearance.sidebar_rail_scale_title": "Размер кнопок левой навигации",
"app.theme.appearance.windows_acrylic_hint": "Windows использует системный эффект Acrylic. Сила размытия управляется системой.",
"app.theme.data_table.column_width_hint": "В стандартном режиме ширина столбца по умолчанию 200px; в компактном режиме 140px. Вручную измененные ширины столбцов сохраняются в приоритете.",
"app.theme.data_table.column_width_mode": "Режим ширины столбцов таблицы данных",
diff --git a/shared/i18n/zh-CN.json b/shared/i18n/zh-CN.json
index 12bfed3c..6c933980 100644
--- a/shared/i18n/zh-CN.json
+++ b/shared/i18n/zh-CN.json
@@ -2678,6 +2678,8 @@
"app.theme.appearance.transparency_blur_title": "透明与模糊效果",
"app.theme.appearance.ui_scale_hint": "* 建议小屏设备设置为 85%-95%",
"app.theme.appearance.ui_scale_title": "界面缩放 (UI Scale)",
+ "app.theme.appearance.sidebar_rail_scale_hint": "仅影响 V2 左侧导航轨道,适合在大屏上放大按钮和连接图标。",
+ "app.theme.appearance.sidebar_rail_scale_title": "左侧导航按钮大小",
"app.theme.appearance.windows_acrylic_hint": "Windows 使用系统 Acrylic 效果,模糊程度由系统控制",
"app.theme.data_table.column_width_hint": "标准模式默认列宽 200px;紧凑模式默认列宽 140px。已手动拖拽调整的列宽优先保留。",
"app.theme.data_table.column_width_mode": "数据表列宽模式",
diff --git a/shared/i18n/zh-TW.json b/shared/i18n/zh-TW.json
index 95691d19..1c418184 100644
--- a/shared/i18n/zh-TW.json
+++ b/shared/i18n/zh-TW.json
@@ -2678,6 +2678,8 @@
"app.theme.appearance.transparency_blur_title": "透明与模糊效果",
"app.theme.appearance.ui_scale_hint": "* 建议小屏设备設定为 85%-95%",
"app.theme.appearance.ui_scale_title": "界面缩放 (UI Scale)",
+ "app.theme.appearance.sidebar_rail_scale_hint": "僅影響 V2 左側導覽軌,適合在大螢幕上放大按鈕與連線圖示。",
+ "app.theme.appearance.sidebar_rail_scale_title": "左側導覽按鈕大小",
"app.theme.appearance.windows_acrylic_hint": "Windows 使用系统 Acrylic 效果,模糊程度由系统控制",
"app.theme.data_table.column_width_hint": "标准模式預設列宽 200px;紧凑模式預設列宽 140px。已手动拖拽调整的列宽优先保留。",
"app.theme.data_table.column_width_mode": "資料表列宽模式",