diff --git a/src/client/components/ui/radio.vue b/src/client/components/ui/radio.vue
index 79715593d0..0f31d8fa0a 100644
--- a/src/client/components/ui/radio.vue
+++ b/src/client/components/ui/radio.vue
@@ -18,7 +18,6 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import * as os from '@/os';
 
 export default defineComponent({
 	props: {
@@ -51,7 +50,7 @@ export default defineComponent({
 .novjtctn {
 	position: relative;
 	display: inline-block;
-	margin: 16px 32px 0 0;
+	margin: 8px 20px 0 0;
 	text-align: left;
 	cursor: pointer;
 	transition: all 0.3s;
diff --git a/src/client/components/ui/radios.vue b/src/client/components/ui/radios.vue
new file mode 100644
index 0000000000..2fdeab4ce9
--- /dev/null
+++ b/src/client/components/ui/radios.vue
@@ -0,0 +1,51 @@
+<template>
+<div
+	class="novjtcto"
+>
+	<div><slot></slot></div>
+	<MkRadio v-for="def in defs" v-model="value" :value="def.value" :key="def.value">{{ def.label }}</MkRadio>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import MkRadio from '@/components/ui/radio.vue';
+
+export default defineComponent({
+	components: {
+		MkRadio
+	},
+	props: {
+		defs: {
+			required: true
+		},
+		modelValue: {
+			required: false
+		},
+	},
+	data() {
+		return {
+			value: this.modelValue,
+		}
+	},
+	watch: {
+		value() {
+			this.$emit('update:modelValue', this.value);
+		}
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.novjtcto {
+	margin: 32px 0;
+
+	&:first-child {
+		margin-top: 0;
+	}
+
+	&:last-child {
+		margin-bottom: 0;
+	}
+}
+</style>
diff --git a/src/client/pages/settings/general.vue b/src/client/pages/settings/general.vue
index aef3cf2f16..cdaf7f50fd 100644
--- a/src/client/pages/settings/general.vue
+++ b/src/client/pages/settings/general.vue
@@ -1,38 +1,44 @@
 <template>
-<div class="_section">
+<div class="">
 	<section class="_card _vMargin">
 		<div class="_title"><Fa :icon="faCog"/> {{ $t('general') }}</div>
 		<div class="_content">
-			<div>{{ $t('defaultNavigationBehaviour') }}</div>
-			<MkSwitch v-model:value="defaultSideView">{{ $t('openInSideView') }}</MkSwitch>
-		</div>
-		<div class="_content">
-			<div>{{ $t('whenServerDisconnected') }}</div>
-			<MkRadio v-model="serverDisconnectedBehavior" value="reload">{{ $t('_serverDisconnectedBehavior.reload') }}</MkRadio>
-			<MkRadio v-model="serverDisconnectedBehavior" value="dialog">{{ $t('_serverDisconnectedBehavior.dialog') }}</MkRadio>
-			<MkRadio v-model="serverDisconnectedBehavior" value="quiet">{{ $t('_serverDisconnectedBehavior.quiet') }}</MkRadio>
-		</div>
-		<div class="_content">
+			<MkRadios v-model="serverDisconnectedBehavior" :defs="[
+					{ label: $t('_serverDisconnectedBehavior.reload'), value: 'reload' },
+					{ label: $t('_serverDisconnectedBehavior.dialog'), value: 'dialog' },
+					{ label: $t('_serverDisconnectedBehavior.quiet'), value: 'quiet' },
+				]"
+			>
+				{{ $t('whenServerDisconnected') }}
+			</MkRadios>
 			<MkSwitch v-model:value="imageNewTab">{{ $t('openImageInNewTab') }}</MkSwitch>
 			<MkSwitch v-model:value="showFixedPostForm">{{ $t('showFixedPostForm') }}</MkSwitch>
 			<MkSwitch v-model:value="enableInfiniteScroll">{{ $t('enableInfiniteScroll') }}</MkSwitch>
 			<MkSwitch v-model:value="disablePagesScript">{{ $t('disablePagesScript') }}</MkSwitch>
-		</div>
-		<div class="_content">
-			<div>{{ $t('chatOpenBehavior') }}</div>
-			<MkRadio v-model="chatOpenBehavior" value="page">{{ $t('showInPage') }}</MkRadio>
-			<MkRadio v-model="chatOpenBehavior" value="window">{{ $t('openInWindow') }}</MkRadio>
-			<MkRadio v-model="chatOpenBehavior" value="popout">{{ $t('popout') }}</MkRadio>
-		</div>
-		<div class="_content">
 			<MkSelect v-model:value="lang">
 				<template #label>{{ $t('uiLanguage') }}</template>
-
 				<option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</option>
 			</MkSelect>
 		</div>
 	</section>
 
+	<section class="_card _vMargin">
+		<div class="_title"><Fa :icon="faCog"/> {{ $t('defaultNavigationBehaviour') }}</div>
+		<div class="_content">
+			<MkSwitch v-model:value="defaultSideView">{{ $t('openInSideView') }}</MkSwitch>
+		</div>
+		<div class="_content">
+			<MkRadios v-model="chatOpenBehavior" :defs="[
+					{ label: $t('showInPage'), value: 'page' },
+					{ label: $t('openInWindow'), value: 'window' },
+					{ label: $t('popout'), value: 'popout' },
+				]"
+			>
+				{{ $t('chatOpenBehavior') }}
+			</MkRadios>
+		</div>
+	</section>
+
 	<section class="_card _vMargin">
 		<div class="_title"><Fa :icon="faCog"/> {{ $t('appearance') }}</div>
 		<div class="_content">
@@ -88,6 +94,7 @@ import MkButton from '@/components/ui/button.vue';
 import MkSwitch from '@/components/ui/switch.vue';
 import MkSelect from '@/components/ui/select.vue';
 import MkRadio from '@/components/ui/radio.vue';
+import MkRadios from '@/components/ui/radios.vue';
 import MkRange from '@/components/ui/range.vue';
 import { langs } from '@/config';
 import { clientDb, set } from '@/db';
@@ -99,6 +106,7 @@ export default defineComponent({
 		MkSwitch,
 		MkSelect,
 		MkRadio,
+		MkRadios,
 		MkRange,
 	},
 
diff --git a/src/client/pages/settings/index.vue b/src/client/pages/settings/index.vue
index 16098d3bf0..5451c8616b 100644
--- a/src/client/pages/settings/index.vue
+++ b/src/client/pages/settings/index.vue
@@ -31,9 +31,7 @@
 		</div>
 	</div>
 	<div class="main">
-		<transition :name="($store.state.device.animation && !narrow) ? 'view-slide' : ''" appear mode="out-in">
-			<component :is="component" @info="onInfo"/>
-		</transition>
+		<component :is="component" @info="onInfo"/>
 	</div>
 </div>
 </template>
@@ -109,14 +107,6 @@ export default defineComponent({
 </script>
 
 <style lang="scss" scoped>
-.view-slide-enter-active, .view-slide-leave-active {
-	transition: opacity 0.3s, transform 0.3s !important;
-}
-.view-slide-enter-from, .view-slide-leave-to {
-	opacity: 0;
-	transform: translateX(32px);
-}
-
 .vvcocwet {
 	> .nav {
 		> .menu {
@@ -133,7 +123,7 @@ export default defineComponent({
 				width: 100%;
 				box-sizing: border-box;
 				padding: 0 32px;
-				line-height: 48px;
+				line-height: 40px;
 				white-space: nowrap;
 				overflow: hidden;
 				text-overflow: ellipsis;
@@ -168,10 +158,22 @@ export default defineComponent({
 		> .nav {
 			width: 30%;
 			max-width: 300px;
+			font-size: 0.95em;
+			border-right: solid 1px var(--divider);
 		}
 
 		> .main {
 			flex: 1;
+			padding: 32px;
+			--baseContentWidth: 100%;
+
+			::v-deep(._section) {
+				padding: 0 0 32px 0;
+
+				& + ._section {
+					padding-top: 32px;
+				}
+			}
 		}
 	}
 }
diff --git a/src/client/pages/settings/theme.vue b/src/client/pages/settings/theme.vue
index 7bca14adac..c023d56dea 100644
--- a/src/client/pages/settings/theme.vue
+++ b/src/client/pages/settings/theme.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="_section">
+<div class="">
 	<div class="rfqxtzch _card _vMargin">
 		<div class="_content">
 			<div class="darkMode" :class="{ disabled: syncDeviceDarkMode }">
@@ -22,8 +22,12 @@
 					</label>
 				</div>
 			</div>
+		</div>
+		<div class="_content">
 			<MkSwitch v-model:value="syncDeviceDarkMode">{{ $t('syncDeviceDarkMode') }}</MkSwitch>
 		</div>
+	</div>
+	<div class="_card _vMargin">
 		<div class="_content">
 			<MkSelect v-model:value="lightTheme">
 				<template #label>{{ $t('themeForLightMode') }}</template>
diff --git a/src/client/style.scss b/src/client/style.scss
index 75a2e825c1..846cf01939 100644
--- a/src/client/style.scss
+++ b/src/client/style.scss
@@ -244,7 +244,7 @@ hr {
 	> ._title {
 		margin: 0;
 		padding: 22px 32px;
-		font-size: 1.1em;
+		font-size: 1em;
 		border-bottom: solid 1px var(--panelHeaderDivider);
 		font-weight: bold;
 		background: var(--panelHeaderBg);