Studio: remove the edge fades appearance setting (#7143)

The edge fades toggle in Settings > Appearance let users swap the panel
edge gradients for thin divider lines. It added little on top of the
default look, so this removes the setting and all of its wiring while
leaving the default edge fades in place.

- drop the edgeFades field, default, and no-edge-fades class from the
  appearance customization store
- remove the settings row, switch, and search entry
- drop the html.no-edge-fades rules from index.css and hub.css
- remove the edgeFades label and description from all locales
- drop the edgeFades field from the personalization backend model and
  its test references
This commit is contained in:
Michael Han 2026-07-15 06:39:23 -07:00 committed by GitHub
commit 162cf38586
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 0 additions and 100 deletions

View file

@ -708,7 +708,6 @@ class PersonalizationCustomization(BaseModel):
pointerCursors: bool = False
reduceMotion: Literal["system", "on", "off"] = "system"
fontSmoothing: bool = True
edgeFades: bool = True
sidebarMenu: list[PersonalizationSidebarMenuItem] = Field(
default_factory = _default_sidebar_menu,
max_length = MAX_SIDEBAR_MENU_INPUT_ITEMS,

View file

@ -56,7 +56,6 @@ def test_customization_defaults():
assert c.contrast == 50
assert c.reduceMotion == "system"
assert c.fontSmoothing is True
assert c.edgeFades is True
assert c.pointerCursors is False
assert c.colors.light.accent is None
assert c.headingFont is None
@ -370,7 +369,6 @@ def test_personalization_route_roundtrip_real_shape(monkeypatch):
"pointerCursors": True,
"reduceMotion": "off",
"fontSmoothing": True,
"edgeFades": False,
"sidebarMenu": [
{"id": "darkMode", "visible": True},
{"id": "api", "visible": False},

View file

@ -1527,16 +1527,3 @@ html.dark .hub-page [data-hub-scroll="true"]::-webkit-scrollbar-thumb {
body[data-scroll-locked] .hub-modal-pe-guard {
pointer-events: none !important;
}
@layer components {
/* Edge fades off (Appearance setting): hub scroll dissolves become thin
divider lines. */
html.no-edge-fades .hub-page .hub-detail-bar::after {
height: 1px;
background: var(--border);
}
html.no-edge-fades .hub-page .hub-scroll-fade {
background: none;
border-top: 1px solid var(--border);
}
}

View file

@ -846,17 +846,6 @@ export function CodeFontSizeRow() {
);
}
export function EdgeFadesSwitch() {
const edgeFades = useAppearanceCustomStore((s) => s.customization.edgeFades);
const patch = useAppearanceCustomStore((s) => s.patch);
return (
<Switch
checked={edgeFades}
onCheckedChange={(checked) => patch({ edgeFades: checked })}
/>
);
}
export function FontSmoothingSwitch() {
const fontSmoothing = useAppearanceCustomStore(
(s) => s.customization.fontSmoothing,

View file

@ -58,7 +58,6 @@ export const SETTINGS_SEARCH_INDEX: Record<SettingsTab, TranslationKey[]> = {
"settings.appearance.custom.uiFontSize.label",
"settings.appearance.custom.codeFontSize.label",
"settings.appearance.custom.fontSmoothing.label",
"settings.appearance.custom.edgeFades.label",
"settings.appearance.layout.compactSidebar",
"settings.appearance.sidebarMenu.title",
"settings.appearance.sidebarMenu.darkModeToggle",

View file

@ -111,8 +111,6 @@ export type AppearanceCustomization = {
reduceMotion: ReduceMotionSetting;
/** true = the app default (antialiased). */
fontSmoothing: boolean;
/** true = content dissolves at panel edges; false = thin divider lines. */
edgeFades: boolean;
/** Order and visibility of the optional sidebar profile menu items. */
sidebarMenu: SidebarMenuItemPref[];
};
@ -136,7 +134,6 @@ export const DEFAULT_CUSTOMIZATION: AppearanceCustomization = {
pointerCursors: false,
reduceMotion: "system",
fontSmoothing: true,
edgeFades: true,
sidebarMenu: SIDEBAR_MENU_ITEM_IDS.map((id) => ({
id,
visible: SIDEBAR_MENU_DEFAULT_VISIBLE[id],
@ -275,7 +272,6 @@ export function sanitizeCustomization(value: unknown): AppearanceCustomization {
? source.reduceMotion
: "system",
fontSmoothing: source.fontSmoothing !== false,
edgeFades: source.edgeFades !== false,
sidebarMenu: sanitizeSidebarMenu(source.sidebarMenu),
};
}
@ -548,9 +544,6 @@ export function applyCustomizationToDocument(
// the media rules in index.css skip html.force-motion.
el.classList.toggle("force-motion", c.reduceMotion === "off");
el.classList.toggle("no-font-smoothing", !c.fontSmoothing);
// Off swaps the scroll-edge dissolves for thin divider lines (index.css
// and hub.css key their fade rules off this class).
el.classList.toggle("no-edge-fades", !c.edgeFades);
}
/**

View file

@ -10,7 +10,6 @@ import {
CodeFontRow,
CodeFontSizeRow,
ContrastSliderRow,
EdgeFadesSwitch,
FontSmoothingSwitch,
HeadingFontRow,
PointerCursorsSwitch,
@ -142,12 +141,6 @@ export function AppearanceTab() {
>
<FontSmoothingSwitch />
</SettingsRow>
<SettingsRow
label={t("settings.appearance.custom.edgeFades.label")}
description={t("settings.appearance.custom.edgeFades.description")}
>
<EdgeFadesSwitch />
</SettingsRow>
<SettingsRow
label={t("settings.appearance.layout.compactSidebar")}
description={t(

View file

@ -346,11 +346,6 @@ export const en = {
label: "Font smoothing",
description: "Use smoothed font anti-aliasing.",
},
edgeFades: {
label: "Edge fades",
description:
"Fade content at panel edges. Off shows a thin divider line instead.",
},
contrast: {
label: "Contrast",
description: "Strength of borders and secondary text.",

View file

@ -321,10 +321,6 @@ export const ja = {
label: "フォントスムージング",
description: "滑らかなアンチエイリアスを使用します。",
},
edgeFades: {
label: "エッジのフェード",
description: "パネル端でコンテンツをフェードします。オフにすると細い区切り線を表示します。",
},
contrast: {
label: "コントラスト",
description: "枠線と補助テキストの強さ。",

View file

@ -344,10 +344,6 @@ export const ptBR = {
label: "Suavização de fonte",
description: "Usar anti-aliasing suavizado nas fontes.",
},
edgeFades: {
label: "Esmaecimento nas bordas",
description: "Esmaece o conteúdo nas bordas dos painéis. Desligado mostra uma linha divisória fina.",
},
contrast: {
label: "Contraste",
description: "Intensidade das bordas e do texto secundário.",

View file

@ -343,10 +343,6 @@ export const zhCN = {
label: "字体平滑",
description: "使用平滑的字体抗锯齿。",
},
edgeFades: {
label: "边缘淡出",
description: "在面板边缘淡出内容。关闭后显示细分隔线。",
},
contrast: {
label: "对比度",
description: "边框和次要文本的强度。",

View file

@ -93,47 +93,6 @@
);
mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent);
}
/* Edge fades off (Appearance setting): every dissolve above becomes a
thin divider line at the same boundary. */
html.no-edge-fades .sidebar-scroll-fade.is-scrolled,
html.no-edge-fades .model-list-scroll.is-scrolled,
html.no-edge-fades .model-list-scroll.is-bottom-faded,
html.no-edge-fades .model-list-scroll.is-scrolled.is-bottom-faded,
html.no-edge-fades .rag-docs-bottom-fade {
-webkit-mask-image: none;
mask-image: none;
}
html.no-edge-fades .sidebar-scroll-fade.is-scrolled {
border-top: 1px solid var(--sidebar-border);
}
html.no-edge-fades .sidebar-bottom-fade::after {
height: 1px;
background: var(--sidebar-border);
}
html.no-edge-fades .model-list-scroll.is-scrolled {
border-top: 1px solid var(--border);
}
html.no-edge-fades .model-list-scroll.is-bottom-faded {
border-bottom: 1px solid var(--border);
}
html.no-edge-fades .rag-docs-bottom-fade {
border-bottom: 1px solid var(--border);
}
/* Chat thread: gradient wash above the composer becomes a hairline at
its top edge; the chat header's under-fade becomes a hairline too.
!important beats the Tailwind gradient/mask utilities on the nodes. */
html.no-edge-fades .thread-bottom-fade {
background: none !important;
backdrop-filter: none !important;
-webkit-mask-image: none !important;
mask-image: none !important;
border-top: 1px solid var(--border);
}
html.no-edge-fades .chat-header-fade {
background: none !important;
border-top: 1px solid var(--border);
}
}
@layer base {