diff --git a/packages/client/src/components/MkTimeline.vue b/packages/client/src/components/MkTimeline.vue
index 2d43dbe220..a921a05037 100644
--- a/packages/client/src/components/MkTimeline.vue
+++ b/packages/client/src/components/MkTimeline.vue
@@ -10,7 +10,7 @@
 <script lang="ts" setup>
 import { computed, provide, onUnmounted } from "vue";
 import XNotes from "@/components/MkNotes.vue";
-import  { defaultStore } from "@/store";
+import { defaultStore } from "@/store";
 import { stream } from "@/stream";
 import * as sound from "@/scripts/sound";
 import { $i } from "@/account";
@@ -97,14 +97,14 @@ if (props.src === "antenna") {
 	endpoint = "notes/global-timeline";
 	connection = stream.useChannel("globalTimeline");
 	connection.on("note", prepend);
-} else if (props.src === 'featured') {
-	endpoint = 'notes/featured';
+} else if (props.src === "featured") {
+	endpoint = "notes/featured";
 	query = {
-		origin: 'combined',
+		origin: "combined",
 		offsetMode: true,
 		days: 5,
 		limit: 10,
-	}
+	};
 } else if (props.src === "mentions") {
 	endpoint = "notes/mentions";
 	connection = stream.useChannel("main");
diff --git a/packages/client/src/pages/admin/emojis.vue b/packages/client/src/pages/admin/emojis.vue
index 911eb9db9c..edba57d0cb 100644
--- a/packages/client/src/pages/admin/emojis.vue
+++ b/packages/client/src/pages/admin/emojis.vue
@@ -154,16 +154,22 @@
 </template>
 
 <script lang="ts" setup>
-import { computed, defineAsyncComponent, defineComponent, ref, toRef } from 'vue';
-import MkButton from '@/components/MkButton.vue';
-import MkInput from '@/components/form/input.vue';
-import MkPagination from '@/components/MkPagination.vue';
-import MkSwitch from '@/components/form/switch.vue';
-import FormSplit from '@/components/form/split.vue';
-import { selectFile, selectFiles } from '@/scripts/select-file';
-import * as os from '@/os';
-import { i18n } from '@/i18n';
-import { definePageMetadata } from '@/scripts/page-metadata';
+import {
+	computed,
+	defineAsyncComponent,
+	defineComponent,
+	ref,
+	toRef,
+} from "vue";
+import MkButton from "@/components/MkButton.vue";
+import MkInput from "@/components/form/input.vue";
+import MkPagination from "@/components/MkPagination.vue";
+import MkSwitch from "@/components/form/switch.vue";
+import FormSplit from "@/components/form/split.vue";
+import { selectFile, selectFiles } from "@/scripts/select-file";
+import * as os from "@/os";
+import { i18n } from "@/i18n";
+import { definePageMetadata } from "@/scripts/page-metadata";
 
 const emojisPaginationComponent = ref<InstanceType<typeof MkPagination>>();
 
diff --git a/packages/client/src/pages/explore.vue b/packages/client/src/pages/explore.vue
index c9ed1234df..f35a938663 100644
--- a/packages/client/src/pages/explore.vue
+++ b/packages/client/src/pages/explore.vue
@@ -1,26 +1,36 @@
 <template>
-<MkStickyContainer>
-	<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
-	<div class="lznhrdub">
-		<MkSpacer :content-max="1200">
-			<swiper
-				:modules="[Virtual]"
-				:space-between="20"
-				:virtual="true"
-				:allow-touch-move="!(deviceKind === 'desktop' && !defaultStore.state.swipeOnDesktop)"
-				@swiper="setSwiperRef"
-				@slide-change="onSlideChange"
+	<MkStickyContainer>
+		<template #header
+			><MkPageHeader
+				v-model:tab="tab"
+				:actions="headerActions"
+				:tabs="headerTabs"
+		/></template>
+		<div class="lznhrdub">
+			<MkSpacer :content-max="1200">
+				<swiper
+					:modules="[Virtual]"
+					:space-between="20"
+					:virtual="true"
+					:allow-touch-move="
+						!(
+							deviceKind === 'desktop' &&
+							!defaultStore.state.swipeOnDesktop
+						)
+					"
+					@swiper="setSwiperRef"
+					@slide-change="onSlideChange"
 				>
-				<swiper-slide>
-					<XUsers/>
-				</swiper-slide>
-				<swiper-slide>
-					<XFeatured/>
-				</swiper-slide>
-			</swiper>
-		</MkSpacer>
-	</div>
-</MkStickyContainer>
+					<swiper-slide>
+						<XUsers />
+					</swiper-slide>
+					<swiper-slide>
+						<XFeatured />
+					</swiper-slide>
+				</swiper>
+			</MkSpacer>
+		</div>
+	</MkStickyContainer>
 </template>
 
 <script lang="ts" setup>
@@ -41,7 +51,7 @@ const props = defineProps<{
 	tag?: string;
 }>();
 
-const tabs = ['users', 'featured'];
+const tabs = ["users", "featured"];
 let tab = $ref(tabs[0]);
 watch($$(tab), () => syncSlide(tabs.indexOf(tab)));
 
@@ -56,15 +66,18 @@ watch(
 
 const headerActions = $computed(() => []);
 
-const headerTabs = $computed(() => [{
-	key: 'users',
-	icon: 'ph-users ph-bold ph-lg',
-	title: i18n.ts.users,
-}, {
-	key: 'featured',
-	icon: 'ph-lightning ph-bold ph-lg',
-	title: i18n.ts.featured,
-}]);
+const headerTabs = $computed(() => [
+	{
+		key: "users",
+		icon: "ph-users ph-bold ph-lg",
+		title: i18n.ts.users,
+	},
+	{
+		key: "featured",
+		icon: "ph-lightning ph-bold ph-lg",
+		title: i18n.ts.featured,
+	},
+]);
 
 definePageMetadata(
 	computed(() => ({
diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue
index 879afe54ee..7bd98a4dac 100644
--- a/packages/client/src/pages/settings/general.vue
+++ b/packages/client/src/pages/settings/general.vue
@@ -1,42 +1,19 @@
 <template>
-<div class="_formRoot">
-	<FormSelect v-model="lang" class="_formBlock">
-		<template #label>{{ i18n.ts.uiLanguage }}</template>
-		<option v-for="x in langs" :key="x[0]" :value="x[0]">{{ x[1] }}</option>
-		<template #caption>
-			<I18n :src="i18n.ts.i18nInfo" tag="span">
-				<template #link>
-					<MkLink url="https://hosted.weblate.org/engage/calckey/">Weblate</MkLink>
-				</template>
-			</I18n>
-		</template>
-	</FormSelect>
-
-	<FormRadios v-model="overridedDeviceKind" class="_formBlock">
-		<template #label>{{ i18n.ts.overridedDeviceKind }}</template>
-		<option :value="null">{{ i18n.ts.auto }}</option>
-		<option value="smartphone"><i class="ph-device-mobile ph-bold ph-lg"/> {{ i18n.ts.smartphone }}</option>
-		<option value="tablet"><i class="ph-device-tablet ph-bold ph-lg"/> {{ i18n.ts.tablet }}</option>
-		<option value="desktop"><i class="ph-desktop ph-bold ph-lg"/> {{ i18n.ts.desktop }}</option>
-	</FormRadios>
-
-	<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{ i18n.ts.showFixedPostForm }}</FormSwitch>
-
-	<FormSection>
-		<template #label>{{ i18n.ts.behavior }}</template>
-		<FormSwitch v-model="imageNewTab" class="_formBlock">{{ i18n.ts.openImageInNewTab }}</FormSwitch>
-		<FormSwitch v-model="enableInfiniteScroll" class="_formBlock">{{ i18n.ts.enableInfiniteScroll }}</FormSwitch>
-		<FormSwitch v-model="useReactionPickerForContextMenu" class="_formBlock">{{ i18n.ts.useReactionPickerForContextMenu }}</FormSwitch>
-		<FormSwitch v-model="swipeOnDesktop" class="_formBlock">{{ i18n.ts.swipeOnDesktop }}</FormSwitch>
-		<FormSwitch v-model="enterSendsMessage" class="_formBlock">{{ i18n.ts.enterSendsMessage }}</FormSwitch>
-		<FormSwitch v-model="disablePagesScript" class="_formBlock">{{ i18n.ts.disablePagesScript }}</FormSwitch>
-
-		<FormSelect v-model="serverDisconnectedBehavior" class="_formBlock">
-			<template #label>{{ i18n.ts.whenServerDisconnected }}</template>
-			<option value="reload">{{ i18n.ts._serverDisconnectedBehavior.reload }}</option>
-			<option value="dialog">{{ i18n.ts._serverDisconnectedBehavior.dialog }}</option>
-			<option value="quiet">{{ i18n.ts._serverDisconnectedBehavior.quiet }}</option>
-			<option value="nothing">{{ i18n.ts._serverDisconnectedBehavior.nothing }}</option>
+	<div class="_formRoot">
+		<FormSelect v-model="lang" class="_formBlock">
+			<template #label>{{ i18n.ts.uiLanguage }}</template>
+			<option v-for="x in langs" :key="x[0]" :value="x[0]">
+				{{ x[1] }}
+			</option>
+			<template #caption>
+				<I18n :src="i18n.ts.i18nInfo" tag="span">
+					<template #link>
+						<MkLink url="https://hosted.weblate.org/engage/calckey/"
+							>Weblate</MkLink
+						>
+					</template>
+				</I18n>
+			</template>
 		</FormSelect>
 
 		<FormRadios v-model="overridedDeviceKind" class="_formBlock">
@@ -55,17 +32,6 @@
 			</option>
 		</FormRadios>
 
-		<FormRadios v-model="showLocalPostsInTimeline" class="_formBlock">
-			<template #label>{{ i18n.ts.showLocalPosts }}</template>
-			<option value="home">
-				<i class="ph-house ph-bold ph-lg" /> {{ i18n.ts.homeTimeline }}
-			</option>
-			<option value="social">
-				<i class="ph-handshake ph-bold ph-lg" />
-				{{ i18n.ts.socialTimeline }}
-			</option>
-		</FormRadios>
-
 		<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{
 			i18n.ts.showFixedPostForm
 		}}</FormSwitch>
@@ -108,6 +74,71 @@
 					{{ i18n.ts._serverDisconnectedBehavior.nothing }}
 				</option>
 			</FormSelect>
+
+			<FormRadios v-model="overridedDeviceKind" class="_formBlock">
+				<template #label>{{ i18n.ts.overridedDeviceKind }}</template>
+				<option :value="null">{{ i18n.ts.auto }}</option>
+				<option value="smartphone">
+					<i class="ph-device-mobile ph-bold ph-lg" />
+					{{ i18n.ts.smartphone }}
+				</option>
+				<option value="tablet">
+					<i class="ph-device-tablet ph-bold ph-lg" />
+					{{ i18n.ts.tablet }}
+				</option>
+				<option value="desktop">
+					<i class="ph-desktop ph-bold ph-lg" /> {{ i18n.ts.desktop }}
+				</option>
+			</FormRadios>
+
+			<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{
+				i18n.ts.showFixedPostForm
+			}}</FormSwitch>
+
+			<FormSection>
+				<template #label>{{ i18n.ts.behavior }}</template>
+				<FormSwitch v-model="imageNewTab" class="_formBlock">{{
+					i18n.ts.openImageInNewTab
+				}}</FormSwitch>
+				<FormSwitch v-model="enableInfiniteScroll" class="_formBlock">{{
+					i18n.ts.enableInfiniteScroll
+				}}</FormSwitch>
+				<FormSwitch
+					v-model="useReactionPickerForContextMenu"
+					class="_formBlock"
+					>{{ i18n.ts.useReactionPickerForContextMenu }}</FormSwitch
+				>
+				<FormSwitch v-model="swipeOnDesktop" class="_formBlock">{{
+					i18n.ts.swipeOnDesktop
+				}}</FormSwitch>
+				<FormSwitch v-model="enterSendsMessage" class="_formBlock">{{
+					i18n.ts.enterSendsMessage
+				}}</FormSwitch>
+				<FormSwitch v-model="disablePagesScript" class="_formBlock">{{
+					i18n.ts.disablePagesScript
+				}}</FormSwitch>
+
+				<FormSelect
+					v-model="serverDisconnectedBehavior"
+					class="_formBlock"
+				>
+					<template #label>{{
+						i18n.ts.whenServerDisconnected
+					}}</template>
+					<option value="reload">
+						{{ i18n.ts._serverDisconnectedBehavior.reload }}
+					</option>
+					<option value="dialog">
+						{{ i18n.ts._serverDisconnectedBehavior.dialog }}
+					</option>
+					<option value="quiet">
+						{{ i18n.ts._serverDisconnectedBehavior.quiet }}
+					</option>
+					<option value="nothing">
+						{{ i18n.ts._serverDisconnectedBehavior.nothing }}
+					</option>
+				</FormSelect>
+			</FormSection>
 		</FormSection>
 
 		<FormSection>
@@ -260,32 +291,76 @@ async function reloadAsk() {
 	unisonReload();
 }
 
-const overridedDeviceKind = computed(defaultStore.makeGetterSetter('overridedDeviceKind'));
-const serverDisconnectedBehavior = computed(defaultStore.makeGetterSetter('serverDisconnectedBehavior'));
-const reduceAnimation = computed(defaultStore.makeGetterSetter('animation', v => !v, v => !v));
-const useBlurEffectForModal = computed(defaultStore.makeGetterSetter('useBlurEffectForModal'));
-const useBlurEffect = computed(defaultStore.makeGetterSetter('useBlurEffect'));
-const showGapBetweenNotesInTimeline = computed(defaultStore.makeGetterSetter('showGapBetweenNotesInTimeline'));
-const showAds = computed(defaultStore.makeGetterSetter('showAds'));
-const disableAnimatedMfm = computed(defaultStore.makeGetterSetter('animatedMfm', v => !v, v => !v));
-const useOsNativeEmojis = computed(defaultStore.makeGetterSetter('useOsNativeEmojis'));
-const disableDrawer = computed(defaultStore.makeGetterSetter('disableDrawer'));
-const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('disableShowingAnimatedImages'));
-const loadRawImages = computed(defaultStore.makeGetterSetter('loadRawImages'));
-const imageNewTab = computed(defaultStore.makeGetterSetter('imageNewTab'));
-const nsfw = computed(defaultStore.makeGetterSetter('nsfw'));
-const disablePagesScript = computed(defaultStore.makeGetterSetter('disablePagesScript'));
-const showFixedPostForm = computed(defaultStore.makeGetterSetter('showFixedPostForm'));
-const numberOfPageCache = computed(defaultStore.makeGetterSetter('numberOfPageCache'));
-const instanceTicker = computed(defaultStore.makeGetterSetter('instanceTicker'));
-const enableInfiniteScroll = computed(defaultStore.makeGetterSetter('enableInfiniteScroll'));
-const enterSendsMessage = computed(defaultStore.makeGetterSetter('enterSendsMessage'));
-const useReactionPickerForContextMenu = computed(defaultStore.makeGetterSetter('useReactionPickerForContextMenu'));
-const seperateRenoteQuote = computed(defaultStore.makeGetterSetter('seperateRenoteQuote'));
-const squareAvatars = computed(defaultStore.makeGetterSetter('squareAvatars'));
-const showUpdates = computed(defaultStore.makeGetterSetter('showUpdates'));
-const swipeOnDesktop = computed(defaultStore.makeGetterSetter('swipeOnDesktop'));
-const showAdminUpdates = computed(defaultStore.makeGetterSetter('showAdminUpdates'));
+const overridedDeviceKind = computed(
+	defaultStore.makeGetterSetter("overridedDeviceKind")
+);
+const serverDisconnectedBehavior = computed(
+	defaultStore.makeGetterSetter("serverDisconnectedBehavior")
+);
+const reduceAnimation = computed(
+	defaultStore.makeGetterSetter(
+		"animation",
+		(v) => !v,
+		(v) => !v
+	)
+);
+const useBlurEffectForModal = computed(
+	defaultStore.makeGetterSetter("useBlurEffectForModal")
+);
+const useBlurEffect = computed(defaultStore.makeGetterSetter("useBlurEffect"));
+const showGapBetweenNotesInTimeline = computed(
+	defaultStore.makeGetterSetter("showGapBetweenNotesInTimeline")
+);
+const showAds = computed(defaultStore.makeGetterSetter("showAds"));
+const disableAnimatedMfm = computed(
+	defaultStore.makeGetterSetter(
+		"animatedMfm",
+		(v) => !v,
+		(v) => !v
+	)
+);
+const useOsNativeEmojis = computed(
+	defaultStore.makeGetterSetter("useOsNativeEmojis")
+);
+const disableDrawer = computed(defaultStore.makeGetterSetter("disableDrawer"));
+const disableShowingAnimatedImages = computed(
+	defaultStore.makeGetterSetter("disableShowingAnimatedImages")
+);
+const loadRawImages = computed(defaultStore.makeGetterSetter("loadRawImages"));
+const imageNewTab = computed(defaultStore.makeGetterSetter("imageNewTab"));
+const nsfw = computed(defaultStore.makeGetterSetter("nsfw"));
+const disablePagesScript = computed(
+	defaultStore.makeGetterSetter("disablePagesScript")
+);
+const showFixedPostForm = computed(
+	defaultStore.makeGetterSetter("showFixedPostForm")
+);
+const numberOfPageCache = computed(
+	defaultStore.makeGetterSetter("numberOfPageCache")
+);
+const instanceTicker = computed(
+	defaultStore.makeGetterSetter("instanceTicker")
+);
+const enableInfiniteScroll = computed(
+	defaultStore.makeGetterSetter("enableInfiniteScroll")
+);
+const enterSendsMessage = computed(
+	defaultStore.makeGetterSetter("enterSendsMessage")
+);
+const useReactionPickerForContextMenu = computed(
+	defaultStore.makeGetterSetter("useReactionPickerForContextMenu")
+);
+const seperateRenoteQuote = computed(
+	defaultStore.makeGetterSetter("seperateRenoteQuote")
+);
+const squareAvatars = computed(defaultStore.makeGetterSetter("squareAvatars"));
+const showUpdates = computed(defaultStore.makeGetterSetter("showUpdates"));
+const swipeOnDesktop = computed(
+	defaultStore.makeGetterSetter("swipeOnDesktop")
+);
+const showAdminUpdates = computed(
+	defaultStore.makeGetterSetter("showAdminUpdates")
+);
 
 watch(lang, () => {
 	localStorage.setItem("lang", lang.value as string);
@@ -308,23 +383,26 @@ watch(useSystemFont, () => {
 	}
 });
 
-watch([
-	lang,
-	fontSize,
-	useSystemFont,
-	enableInfiniteScroll,
-	squareAvatars,
-	showGapBetweenNotesInTimeline,
-	instanceTicker,
-	overridedDeviceKind,
-	showAds,
-	showUpdates,
-	swipeOnDesktop,
-	seperateRenoteQuote,
-	showAdminUpdates,
-], async () => {
-	await reloadAsk();
-});
+watch(
+	[
+		lang,
+		fontSize,
+		useSystemFont,
+		enableInfiniteScroll,
+		squareAvatars,
+		showGapBetweenNotesInTimeline,
+		instanceTicker,
+		overridedDeviceKind,
+		showAds,
+		showUpdates,
+		swipeOnDesktop,
+		seperateRenoteQuote,
+		showAdminUpdates,
+	],
+	async () => {
+		await reloadAsk();
+	}
+);
 
 const headerActions = $computed(() => []);
 
diff --git a/packages/client/src/pages/settings/preferences-backups.vue b/packages/client/src/pages/settings/preferences-backups.vue
index 953fe2b915..9d894ae389 100644
--- a/packages/client/src/pages/settings/preferences-backups.vue
+++ b/packages/client/src/pages/settings/preferences-backups.vue
@@ -73,48 +73,48 @@ const { t, ts } = i18n;
 
 useCssModule();
 
-const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
-	'menu',
-	'visibility',
-	'localOnly',
-	'statusbars',
-	'widgets',
-	'tl',
-	'forYouTl',
-	'discoverTl',
-	'overridedDeviceKind',
-	'serverDisconnectedBehavior',
-	'nsfw',
-	'showAds',
-	'animation',
-	'animatedMfm',
-	'loadRawImages',
-	'imageNewTab',
-	'disableShowingAnimatedImages',
-	'disablePagesScript',
-	'enterSendsMessage',
-	'useOsNativeEmojis',
-	'disableDrawer',
-	'useBlurEffectForModal',
-	'useBlurEffect',
-	'showFixedPostForm',
-	'enableInfiniteScroll',
-	'useReactionPickerForContextMenu',
-	'showGapBetweenNotesInTimeline',
-	'instanceTicker',
-	'reactionPickerSize',
-	'reactionPickerWidth',
-	'reactionPickerHeight',
-	'reactionPickerUseDrawerForMobile',
-	'defaultSideView',
-	'menuDisplay',
-	'reportError',
-	'squareAvatars',
-	'numberOfPageCache',
-	'showUpdates',
-	'swipeOnDesktop',
-	'showAdminUpdates',
-	'enableCustomKaTeXMacro',
+const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
+	"menu",
+	"visibility",
+	"localOnly",
+	"statusbars",
+	"widgets",
+	"tl",
+	"forYouTl",
+	"discoverTl",
+	"overridedDeviceKind",
+	"serverDisconnectedBehavior",
+	"nsfw",
+	"showAds",
+	"animation",
+	"animatedMfm",
+	"loadRawImages",
+	"imageNewTab",
+	"disableShowingAnimatedImages",
+	"disablePagesScript",
+	"enterSendsMessage",
+	"useOsNativeEmojis",
+	"disableDrawer",
+	"useBlurEffectForModal",
+	"useBlurEffect",
+	"showFixedPostForm",
+	"enableInfiniteScroll",
+	"useReactionPickerForContextMenu",
+	"showGapBetweenNotesInTimeline",
+	"instanceTicker",
+	"reactionPickerSize",
+	"reactionPickerWidth",
+	"reactionPickerHeight",
+	"reactionPickerUseDrawerForMobile",
+	"defaultSideView",
+	"menuDisplay",
+	"reportError",
+	"squareAvatars",
+	"numberOfPageCache",
+	"showUpdates",
+	"swipeOnDesktop",
+	"showAdminUpdates",
+	"enableCustomKaTeXMacro",
 ];
 const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
 	"lightTheme",
diff --git a/packages/client/src/pages/timeline.discover.vue b/packages/client/src/pages/timeline.discover.vue
index 7c9ca9883e..81f40c1df9 100644
--- a/packages/client/src/pages/timeline.discover.vue
+++ b/packages/client/src/pages/timeline.discover.vue
@@ -1,9 +1,13 @@
 <template>
 	<MkSpacer :content-max="800">
-		<MkTab v-model="tab" style="margin-bottom: var(--margin);">
+		<MkTab v-model="tab" style="margin-bottom: var(--margin)">
 			<option value="hot">{{ i18n.ts._timelines.hot }}</option>
-			<option v-if="isRecommendedTimelineAvailable" value="recommended">{{ i18n.ts._timelines.recommended }}</option>
-			<option v-if="isGlobalTimelineAvailable" value="global">{{ i18n.ts._timelines.global }}</option>
+			<option v-if="isRecommendedTimelineAvailable" value="recommended">
+				{{ i18n.ts._timelines.recommended }}
+			</option>
+			<option v-if="isGlobalTimelineAvailable" value="global">
+				{{ i18n.ts._timelines.global }}
+			</option>
 		</MkTab>
 		<XTimeline
 			v-if="tab === 'hot'"
@@ -30,25 +34,23 @@
 </template>
 
 <script lang="ts" setup>
-import XTimeline from '@/components/MkTimeline.vue';
-import MkTab from '@/components/MkTab.vue';
-import { defaultStore } from '@/store';
-import { i18n } from '@/i18n';
-import { instance } from '@/instance';
-import { $i } from '@/account';
+import XTimeline from "@/components/MkTimeline.vue";
+import MkTab from "@/components/MkTab.vue";
+import { defaultStore } from "@/store";
+import { i18n } from "@/i18n";
+import { instance } from "@/instance";
+import { $i } from "@/account";
 
 const tab = $computed({
 	get: () => defaultStore.reactiveState.discoverTl.value.src,
 	set: (x) => saveSrc(x),
 });
 
-function saveSrc(
-	newSrc: 'hot' | 'recommended' | 'global',
-): void {
-	defaultStore.set('discoverTl', {
+function saveSrc(newSrc: "hot" | "recommended" | "global"): void {
+	defaultStore.set("discoverTl", {
 		...defaultStore.state.discoverTl,
-		src: newSrc
-	})
+		src: newSrc,
+	});
 }
 
 const isRecommendedTimelineAvailable = !instance.disableRecommendedTimeline;
diff --git a/packages/client/src/pages/timeline.foryou.vue b/packages/client/src/pages/timeline.foryou.vue
index 14812103ff..3ba52f9789 100644
--- a/packages/client/src/pages/timeline.foryou.vue
+++ b/packages/client/src/pages/timeline.foryou.vue
@@ -1,9 +1,13 @@
 <template>
 	<MkSpacer :content-max="800">
-		<MkTab v-model="tab" style="margin-bottom: var(--margin);">
-			<option v-if="isLocalTimelineAvailable" value="social">{{ i18n.ts._timelines.social }}</option>
+		<MkTab v-model="tab" style="margin-bottom: var(--margin)">
+			<option v-if="isLocalTimelineAvailable" value="social">
+				{{ i18n.ts._timelines.social }}
+			</option>
 			<option value="home">{{ i18n.ts._timelines.home }}</option>
-			<option value="local" v-if="isLocalTimelineAvailable">{{ i18n.ts._timelines.local }}</option>
+			<option value="local" v-if="isLocalTimelineAvailable">
+				{{ i18n.ts._timelines.local }}
+			</option>
 		</MkTab>
 		<XTimeline
 			v-if="tab === 'social'"
@@ -30,25 +34,23 @@
 </template>
 
 <script lang="ts" setup>
-import XTimeline from '@/components/MkTimeline.vue';
-import MkTab from '@/components/MkTab.vue';
-import { defaultStore } from '@/store';
-import { i18n } from '@/i18n';
-import { instance } from '@/instance';
-import { $i } from '@/account';
+import XTimeline from "@/components/MkTimeline.vue";
+import MkTab from "@/components/MkTab.vue";
+import { defaultStore } from "@/store";
+import { i18n } from "@/i18n";
+import { instance } from "@/instance";
+import { $i } from "@/account";
 
 const tab = $computed({
 	get: () => defaultStore.reactiveState.forYouTl.value.src,
 	set: (x) => saveSrc(x),
 });
 
-function saveSrc(
-	newSrc: 'home' | 'local' | 'social',
-): void {
-	defaultStore.set('forYouTl', {
+function saveSrc(newSrc: "home" | "local" | "social"): void {
+	defaultStore.set("forYouTl", {
 		...defaultStore.state.forYouTl,
-		src: newSrc
-	})
+		src: newSrc,
+	});
 }
 
 const isLocalTimelineAvailable =
diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue
index 4a29a7ea50..acc203006c 100644
--- a/packages/client/src/pages/timeline.vue
+++ b/packages/client/src/pages/timeline.vue
@@ -15,7 +15,7 @@
 					class="post-form _block"
 					fixed
 				/>
-	
+
 				<div v-if="queue > 0" class="new">
 					<button class="_buttonPrimary" @click="top()">
 						{{ i18n.ts.newNoteRecived }}
@@ -36,218 +36,228 @@
 						:modules="[Virtual]"
 						:space-between="20"
 						:virtual="true"
-						:allow-touch-move="!(deviceKind === 'desktop' && !defaultStore.state.swipeOnDesktop)"
+						:allow-touch-move="
+							!(
+								deviceKind === 'desktop' &&
+								!defaultStore.state.swipeOnDesktop
+							)
+						"
 						@swiper="setSwiperRef"
 						@slide-change="onSlideChange"
-						>
+					>
 						<swiper-slide>
-							<XForYou/>
+							<XForYou />
 						</swiper-slide>
 						<swiper-slide>
-							<XDiscover/>
+							<XDiscover />
 						</swiper-slide>
 					</swiper>
 				</div>
 			</div>
 		</MkSpacer>
 	</MkStickyContainer>
-	</template>
-	
-	<script lang="ts" setup>
-	import { computed, ref, onMounted } from 'vue';
-	import { Virtual } from 'swiper';
-	import { Swiper, SwiperSlide } from 'swiper/vue';
-	import XTutorial from '@/components/MkTutorialDialog.vue';
-	import XPostForm from '@/components/MkPostForm.vue';
-	import XForYou from './timeline.foryou.vue';
-	import XDiscover from './timeline.discover.vue';
-	import { scroll } from '@/scripts/scroll';
-	import * as os from '@/os';
-	import { defaultStore } from '@/store';
-	import { i18n } from '@/i18n';
-	import { definePageMetadata } from '@/scripts/page-metadata';
-	import { deviceKind } from '@/scripts/device-kind';
-	import 'swiper/scss';
-	import 'swiper/scss/virtual';
-	
-	if (defaultStore.reactiveState.tutorial.value !== -1) {
-		os.popup(XTutorial, {}, {}, 'closed');
-	}
-	
-	let timelines = ['forYou', 'discover'];
-	
-	const MOBILE_THRESHOLD = 500;
-	
-	// デスクトップでウィンドウを狭くしたときモバイルUIが表示されて欲しいことはあるので deviceKind === 'desktop' の判定は行わない
-	const isMobile = ref(
-		deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD,
-	);
-	window.addEventListener('resize', () => {
-		isMobile.value =
-			(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD);
-	});
-	
-	const rootEl = $ref<HTMLElement>();
-	
-	let queue = $ref(0);
-	const src = $computed({
-		get: () => defaultStore.reactiveState.tl.value.src,
-		set: (x) => {
-			saveSrc(x);
-			syncSlide(timelines.indexOf(x));
-		},
-	});
-	
-	function top(): void {
-		scroll(rootEl!, { top: 0 });
-	}
-	
-	async function chooseList(ev: MouseEvent): Promise<void> {
-		const lists = await os.api('users/lists/list');
-		const items = [{
-			type: 'link' as const,
+</template>
+
+<script lang="ts" setup>
+import { computed, ref, onMounted } from "vue";
+import { Virtual } from "swiper";
+import { Swiper, SwiperSlide } from "swiper/vue";
+import XTutorial from "@/components/MkTutorialDialog.vue";
+import XPostForm from "@/components/MkPostForm.vue";
+import XForYou from "./timeline.foryou.vue";
+import XDiscover from "./timeline.discover.vue";
+import { scroll } from "@/scripts/scroll";
+import * as os from "@/os";
+import { defaultStore } from "@/store";
+import { i18n } from "@/i18n";
+import { definePageMetadata } from "@/scripts/page-metadata";
+import { deviceKind } from "@/scripts/device-kind";
+import "swiper/scss";
+import "swiper/scss/virtual";
+
+if (defaultStore.reactiveState.tutorial.value !== -1) {
+	os.popup(XTutorial, {}, {}, "closed");
+}
+
+let timelines = ["forYou", "discover"];
+
+const MOBILE_THRESHOLD = 500;
+
+// デスクトップでウィンドウを狭くしたときモバイルUIが表示されて欲しいことはあるので deviceKind === 'desktop' の判定は行わない
+const isMobile = ref(
+	deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD
+);
+window.addEventListener("resize", () => {
+	isMobile.value =
+		deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD;
+});
+
+const rootEl = $ref<HTMLElement>();
+
+let queue = $ref(0);
+const src = $computed({
+	get: () => defaultStore.reactiveState.tl.value.src,
+	set: (x) => {
+		saveSrc(x);
+		syncSlide(timelines.indexOf(x));
+	},
+});
+
+function top(): void {
+	scroll(rootEl!, { top: 0 });
+}
+
+async function chooseList(ev: MouseEvent): Promise<void> {
+	const lists = await os.api("users/lists/list");
+	const items = [
+		{
+			type: "link" as const,
 			text: i18n.ts.manageLists,
-			icon: 'ph-faders-horizontal ph-bold ph-lg',
-			to: '/my/lists',
-		}].concat(lists.map((list) => ({
-			type: 'link' as const,
+			icon: "ph-faders-horizontal ph-bold ph-lg",
+			to: "/my/lists",
+		},
+	].concat(
+		lists.map((list) => ({
+			type: "link" as const,
 			text: list.name,
-			icon: '',
+			icon: "",
 			to: `/timeline/list/${list.id}`,
-		})));
-		os.popupMenu(items, ev.currentTarget ?? ev.target);
-	}
-	
-	async function chooseAntenna(ev: MouseEvent): Promise<void> {
-		const antennas = await os.api('antennas/list');
-		const items = [{
-			type: 'link' as const,
+		}))
+	);
+	os.popupMenu(items, ev.currentTarget ?? ev.target);
+}
+
+async function chooseAntenna(ev: MouseEvent): Promise<void> {
+	const antennas = await os.api("antennas/list");
+	const items = [
+		{
+			type: "link" as const,
 			indicate: false,
 			text: i18n.ts.manageAntennas,
-			icon: 'ph-faders-horizontal ph-bold ph-lg',
-			to: '/my/antennas',
-		}].concat(antennas.map((antenna) => ({
-			type: 'link' as const,
+			icon: "ph-faders-horizontal ph-bold ph-lg",
+			to: "/my/antennas",
+		},
+	].concat(
+		antennas.map((antenna) => ({
+			type: "link" as const,
 			text: antenna.name,
-			icon: '',
+			icon: "",
 			indicate: antenna.hasUnreadNote,
 			to: `/timeline/antenna/${antenna.id}`,
-		})));
-		os.popupMenu(items, ev.currentTarget ?? ev.target);
-	}
-	
-	function saveSrc(
-		newSrc: 'forYou' | 'discover',
-	): void {
-		defaultStore.set('tl', {
-			...defaultStore.state.tl,
-			src: newSrc,
-		});
-	}
-	
-	function saveDiscoverSrc(
-		newSrc: 'hot' | 'recommended' | 'global',
-	): void {
-		defaultStore.set('discoverTl', {
-			...defaultStore.state.discoverTl,
-			src: newSrc
-		})
-	}
-	
-	const headerActions = $computed(() => [
-		{
-			icon: 'ph-list-bullets ph-bold ph-lg',
-			title: i18n.ts.lists,
-			text: i18n.ts.lists,
-			iconOnly: true,
-			handler: chooseList,
-		},
-		{
-			icon: 'ph-flying-saucer ph-bold ph-lg',
-			title: i18n.ts.antennas,
-			text: i18n.ts.antennas,
-			iconOnly: true,
-			handler: chooseAntenna,
-		} /* **TODO: fix timetravel** {
+		}))
+	);
+	os.popupMenu(items, ev.currentTarget ?? ev.target);
+}
+
+function saveSrc(newSrc: "forYou" | "discover"): void {
+	defaultStore.set("tl", {
+		...defaultStore.state.tl,
+		src: newSrc,
+	});
+}
+
+function saveDiscoverSrc(newSrc: "hot" | "recommended" | "global"): void {
+	defaultStore.set("discoverTl", {
+		...defaultStore.state.discoverTl,
+		src: newSrc,
+	});
+}
+
+const headerActions = $computed(() => [
+	{
+		icon: "ph-list-bullets ph-bold ph-lg",
+		title: i18n.ts.lists,
+		text: i18n.ts.lists,
+		iconOnly: true,
+		handler: chooseList,
+	},
+	{
+		icon: "ph-flying-saucer ph-bold ph-lg",
+		title: i18n.ts.antennas,
+		text: i18n.ts.antennas,
+		iconOnly: true,
+		handler: chooseAntenna,
+	} /* **TODO: fix timetravel** {
 		icon: 'ph-calendar-blank ph-bold ph-lg',
 		title: i18n.ts.jumpToSpecifiedDate,
 		iconOnly: true,
 		handler: timetravel,
 	}*/,
-	]);
-	
-	const headerTabs = $computed(() => [
-		{
-			key: 'forYou',
-			title: i18n.ts._timelines.forYou,
-			icon: 'ph-house ph-bold ph-lg',
-		},
-		{
-			key: 'discover',
-			title: i18n.ts._timelines.discover,
-			icon: 'ph-planet ph-bold ph-lg',
-		}
-	]);
-	
-	definePageMetadata(
-		computed(() => ({
-			title: i18n.ts.timeline,
-			icon:
-				src === 'discover'
-					? 'ph-planet ph-bold ph-lg'
-					: 'ph-house ph-bold ph-lg',
-		})),
+]);
+
+const headerTabs = $computed(() => [
+	{
+		key: "forYou",
+		title: i18n.ts._timelines.forYou,
+		icon: "ph-house ph-bold ph-lg",
+	},
+	{
+		key: "discover",
+		title: i18n.ts._timelines.discover,
+		icon: "ph-planet ph-bold ph-lg",
+	},
+]);
+
+definePageMetadata(
+	computed(() => ({
+		title: i18n.ts.timeline,
+		icon:
+			src === "discover"
+				? "ph-planet ph-bold ph-lg"
+				: "ph-house ph-bold ph-lg",
+	}))
+);
+
+let swiperRef: any = null;
+
+function setSwiperRef(swiper) {
+	swiperRef = swiper;
+	syncSlide(timelines.indexOf(src));
+}
+
+function onSlideChange() {
+	saveSrc(timelines[swiperRef.activeIndex]);
+}
+
+function syncSlide(index) {
+	swiperRef.slideTo(index);
+}
+
+onMounted(() => {
+	syncSlide(
+		timelines.indexOf(defaultStore.state.tl?.src || swiperRef.activeIndex)
 	);
-	
-	let swiperRef: any = null;
-	
-	function setSwiperRef(swiper) {
-		swiperRef = swiper;
-		syncSlide(timelines.indexOf(src));
-	}
-	
-	function onSlideChange() {
-		saveSrc(timelines[swiperRef.activeIndex]);
-	}
-	
-	function syncSlide(index) {
-		swiperRef.slideTo(index);
-	}
-	
-	onMounted(() => {
-		syncSlide(timelines.indexOf(defaultStore.state.tl?.src || swiperRef.activeIndex));
-	});
-	
-	</script>
-	
-	<style lang="scss" scoped>
-	.cmuxhskf {
-		--swiper-theme-color: var(--accent);
-	
-		> .new {
-			position: sticky;
-			top: calc(var(--stickyTop, 0px) + 16px);
-			z-index: 1000;
-			width: 100%;
-			pointer-events: none;
-	
-			> button {
-				display: block;
-				margin: var(--margin) auto 0 auto;
-				padding: 8px 16px;
-				border-radius: 32px;
-				pointer-events: all;
-			}
-		}
-	
-		> .post-form {
-			border-radius: var(--radius);
-		}
-	
-		> .tl {
-			background: var(--bg);
-			border-radius: var(--radius);
-			overflow: clip;
+});
+</script>
+
+<style lang="scss" scoped>
+.cmuxhskf {
+	--swiper-theme-color: var(--accent);
+
+	> .new {
+		position: sticky;
+		top: calc(var(--stickyTop, 0px) + 16px);
+		z-index: 1000;
+		width: 100%;
+		pointer-events: none;
+
+		> button {
+			display: block;
+			margin: var(--margin) auto 0 auto;
+			padding: 8px 16px;
+			border-radius: 32px;
+			pointer-events: all;
 		}
 	}
-	</style>
+
+	> .post-form {
+		border-radius: var(--radius);
+	}
+
+	> .tl {
+		background: var(--bg);
+		border-radius: var(--radius);
+		overflow: clip;
+	}
+}
+</style>