diff --git a/gulpfile.js b/gulpfile.js
index 90f8ebaabe..07a8a99d69 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -19,8 +19,8 @@ gulp.task('copy:client:fonts', () =>
 	gulp.src('./packages/client/node_modules/three/examples/fonts/**/*').pipe(gulp.dest('./built/_client_dist_/fonts/'))
 );
 
-gulp.task('copy:client:fontawesome', () =>
-	gulp.src('./packages/client/node_modules/@fortawesome/fontawesome-free/**/*').pipe(gulp.dest('./built/_client_dist_/fontawesome/'))
+gulp.task('copy:client:tabler-icons', () =>
+	gulp.src('./packages/client/node_modules/@tabler/icons/iconfont/**/*').pipe(gulp.dest('./built/_client_dist_/tabler-icons/'))
 );
 
 gulp.task('copy:client:locales', cb => {
@@ -53,7 +53,7 @@ gulp.task('build:backend:style', () => {
 });
 
 gulp.task('build', gulp.parallel(
-	'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts', 'copy:client:fontawesome'
+	'copy:client:locales', 'copy:backend:views', 'build:backend:script', 'build:backend:style', 'copy:client:fonts', 'copy:client:tabler-icons'
 ));
 
 gulp.task('default', gulp.task('build'));
diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug
index 7d802d37ce..1b3ac82d2e 100644
--- a/packages/backend/src/server/web/views/base.pug
+++ b/packages/backend/src/server/web/views/base.pug
@@ -34,7 +34,7 @@ html
 		link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg')
 		link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg')
 		link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg')
-		link(rel='stylesheet' href='/assets/fontawesome/css/all.css')
+		link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.css')
 		link(rel='modulepreload' href=`/assets/${clientEntry.file}`)
 
 		if Array.isArray(clientEntry.css)
diff --git a/packages/client/package.json b/packages/client/package.json
index 34556d5fda..6ed9c5d1fe 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -8,11 +8,11 @@
 	},
 	"dependencies": {
 		"@discordapp/twemoji": "14.0.2",
-		"@fortawesome/fontawesome-free": "6.1.2",
 		"@rollup/plugin-alias": "4.0.2",
 		"@rollup/plugin-json": "6.0.0",
 		"@rollup/pluginutils": "5.0.2",
 		"@syuilo/aiscript": "0.11.1",
+		"@tabler/icons": "^1.117.0",
 		"@vitejs/plugin-vue": "4.0.0",
 		"@vue/compiler-sfc": "3.2.45",
 		"autobind-decorator": "2.4.0",
diff --git a/packages/client/src/account.ts b/packages/client/src/account.ts
index e9c29d6b0d..0e991cdfb5 100644
--- a/packages/client/src/account.ts
+++ b/packages/client/src/account.ts
@@ -213,7 +213,7 @@ export async function openAccountMenu(opts: {
 			avatar: $i,
 		}, null, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, {
 			type: 'parent',
-			icon: 'fas fa-plus',
+			icon: 'ti ti-plus',
 			text: i18n.ts.addAccount,
 			children: [{
 				text: i18n.ts.existingAccount,
@@ -224,7 +224,7 @@ export async function openAccountMenu(opts: {
 			}],
 		}, {
 			type: 'link',
-			icon: 'fas fa-users',
+			icon: 'ti ti-users',
 			text: i18n.ts.manageAccounts,
 			to: '/settings/accounts',
 		}]], ev.currentTarget ?? ev.target, {
diff --git a/packages/client/src/components/MkAbuseReportWindow.vue b/packages/client/src/components/MkAbuseReportWindow.vue
index 1862d0a0e4..03890b4e97 100644
--- a/packages/client/src/components/MkAbuseReportWindow.vue
+++ b/packages/client/src/components/MkAbuseReportWindow.vue
@@ -1,7 +1,7 @@
 <template>
 <XWindow ref="uiWindow" :initial-width="400" :initial-height="500" :can-resize="true" @closed="emit('closed')">
 	<template #header>
-		<i class="fas fa-exclamation-circle" style="margin-right: 0.5em;"></i>
+		<i class="ti ti-exclamation-circle" style="margin-right: 0.5em;"></i>
 		<I18n :src="i18n.ts.reportAbuseOf" tag="span">
 			<template #name>
 				<b><MkAcct :user="user"/></b>
diff --git a/packages/client/src/components/MkButton.vue b/packages/client/src/components/MkButton.vue
index 64698aa00c..1cee1725aa 100644
--- a/packages/client/src/components/MkButton.vue
+++ b/packages/client/src/components/MkButton.vue
@@ -108,7 +108,7 @@ function onMousedown(evt: MouseEvent): void {
 	padding: 8px 16px;
 	text-align: center;
 	font-weight: normal;
-	font-size: 1em;
+	font-size: 90%;
 	box-shadow: none;
 	text-decoration: none;
 	background: var(--buttonBg);
diff --git a/packages/client/src/components/MkChannelFollowButton.vue b/packages/client/src/components/MkChannelFollowButton.vue
index dff02beec0..46d57b4fc6 100644
--- a/packages/client/src/components/MkChannelFollowButton.vue
+++ b/packages/client/src/components/MkChannelFollowButton.vue
@@ -6,14 +6,14 @@
 >
 	<template v-if="!wait">
 		<template v-if="isFollowing">
-			<span v-if="full">{{ i18n.ts.unfollow }}</span><i class="fas fa-minus"></i>
+			<span v-if="full">{{ i18n.ts.unfollow }}</span><i class="ti ti-minus"></i>
 		</template>
 		<template v-else>
-			<span v-if="full">{{ i18n.ts.follow }}</span><i class="fas fa-plus"></i>
+			<span v-if="full">{{ i18n.ts.follow }}</span><i class="ti ti-plus"></i>
 		</template>
 	</template>
 	<template v-else>
-		<span v-if="full">{{ i18n.ts.processing }}</span><i class="fas fa-spinner fa-pulse fa-fw"></i>
+		<span v-if="full">{{ i18n.ts.processing }}</span><i class="fas fa-spinner fa-pulse ti-fw"></i>
 	</template>
 </button>
 </template>
diff --git a/packages/client/src/components/MkChannelPreview.vue b/packages/client/src/components/MkChannelPreview.vue
index dd3794a657..6ef50bddcf 100644
--- a/packages/client/src/components/MkChannelPreview.vue
+++ b/packages/client/src/components/MkChannelPreview.vue
@@ -2,10 +2,10 @@
 <MkA :to="`/channels/${channel.id}`" class="eftoefju _panel" tabindex="-1">
 	<div class="banner" :style="bannerStyle">
 		<div class="fade"></div>
-		<div class="name"><i class="fas fa-satellite-dish"></i> {{ channel.name }}</div>
+		<div class="name"><i class="ti ti-device-tv"></i> {{ channel.name }}</div>
 		<div class="status">
 			<div>
-				<i class="fas fa-users fa-fw"></i>
+				<i class="ti ti-users ti-fw"></i>
 				<I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;">
 					<template #n>
 						<b>{{ channel.usersCount }}</b>
@@ -13,7 +13,7 @@
 				</I18n>
 			</div>
 			<div>
-				<i class="fas fa-pencil-alt fa-fw"></i>
+				<i class="ti ti-pencil ti-fw"></i>
 				<I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;">
 					<template #n>
 						<b>{{ channel.notesCount }}</b>
diff --git a/packages/client/src/components/MkContainer.vue b/packages/client/src/components/MkContainer.vue
index 4be59adc2a..c097946c19 100644
--- a/packages/client/src/components/MkContainer.vue
+++ b/packages/client/src/components/MkContainer.vue
@@ -5,8 +5,8 @@
 		<div class="sub">
 			<slot name="func"></slot>
 			<button v-if="foldable" class="_button" @click="() => showBody = !showBody">
-				<template v-if="showBody"><i class="fas fa-angle-up"></i></template>
-				<template v-else><i class="fas fa-angle-down"></i></template>
+				<template v-if="showBody"><i class="ti ti-chevron-up"></i></template>
+				<template v-else><i class="ti ti-chevron-down"></i></template>
 			</button>
 		</div>
 	</header>
diff --git a/packages/client/src/components/MkDateSeparatedList.vue b/packages/client/src/components/MkDateSeparatedList.vue
index f63d9782b6..68903f3526 100644
--- a/packages/client/src/components/MkDateSeparatedList.vue
+++ b/packages/client/src/components/MkDateSeparatedList.vue
@@ -64,14 +64,14 @@ export default defineComponent({
 				}, [
 					h('span', [
 						h('i', {
-							class: 'fas fa-angle-up icon',
+							class: 'ti ti-chevron-up icon',
 						}),
 						getDateText(item.createdAt),
 					]),
 					h('span', [
 						getDateText(props.items[i + 1].createdAt),
 						h('i', {
-							class: 'fas fa-angle-down icon',
+							class: 'ti ti-chevron-down icon',
 						}),
 					]),
 				]));
diff --git a/packages/client/src/components/MkDialog.vue b/packages/client/src/components/MkDialog.vue
index 513e2d22ba..8a46e9cdde 100644
--- a/packages/client/src/components/MkDialog.vue
+++ b/packages/client/src/components/MkDialog.vue
@@ -5,17 +5,17 @@
 			<i :class="icon"></i>
 		</div>
 		<div v-else-if="!input && !select" class="icon" :class="type">
-			<i v-if="type === 'success'" class="fas fa-check"></i>
-			<i v-else-if="type === 'error'" class="fas fa-times-circle"></i>
-			<i v-else-if="type === 'warning'" class="fas fa-exclamation-triangle"></i>
-			<i v-else-if="type === 'info'" class="fas fa-info-circle"></i>
-			<i v-else-if="type === 'question'" class="fas fa-question-circle"></i>
+			<i v-if="type === 'success'" class="ti ti-check"></i>
+			<i v-else-if="type === 'error'" class="ti ti-circle-x"></i>
+			<i v-else-if="type === 'warning'" class="ti ti-alert-triangle"></i>
+			<i v-else-if="type === 'info'" class="ti ti-info-circle"></i>
+			<i v-else-if="type === 'question'" class="ti ti-question-circle"></i>
 			<i v-else-if="type === 'waiting'" class="fas fa-spinner fa-pulse"></i>
 		</div>
 		<header v-if="title"><Mfm :text="title"/></header>
 		<div v-if="text" class="body"><Mfm :text="text"/></div>
 		<MkInput v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder || undefined" @keydown="onInputKeydown">
-			<template v-if="input.type === 'password'" #prefix><i class="fas fa-lock"></i></template>
+			<template v-if="input.type === 'password'" #prefix><i class="ti ti-lock"></i></template>
 		</MkInput>
 		<MkSelect v-if="select" v-model="selectedValue" autofocus>
 			<template v-if="select.items">
@@ -155,7 +155,7 @@ onBeforeUnmount(() => {
 	border-radius: var(--radius);
 
 	> .icon {
-		font-size: 32px;
+		font-size: 24px;
 
 		&.info {
 			color: #55c4dd;
diff --git a/packages/client/src/components/MkDrive.file.vue b/packages/client/src/components/MkDrive.file.vue
index 22916d5680..4ac63d5b95 100644
--- a/packages/client/src/components/MkDrive.file.vue
+++ b/packages/client/src/components/MkDrive.file.vue
@@ -63,30 +63,30 @@ const title = computed(() => `${props.file.name}\n${props.file.type} ${bytes(pro
 function getMenu() {
 	return [{
 		text: i18n.ts.rename,
-		icon: 'fas fa-i-cursor',
+		icon: 'ti ti-cursor-text',
 		action: rename,
 	}, {
 		text: props.file.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive,
-		icon: props.file.isSensitive ? 'fas fa-eye' : 'fas fa-eye-slash',
+		icon: props.file.isSensitive ? 'ti ti-eye' : 'ti ti-eye-off',
 		action: toggleSensitive,
 	}, {
 		text: i18n.ts.describeFile,
-		icon: 'fas fa-i-cursor',
+		icon: 'ti ti-cursor-text',
 		action: describe,
 	}, null, {
 		text: i18n.ts.copyUrl,
-		icon: 'fas fa-link',
+		icon: 'ti ti-link',
 		action: copyUrl,
 	}, {
 		type: 'a',
 		href: props.file.url,
 		target: '_blank',
 		text: i18n.ts.download,
-		icon: 'fas fa-download',
+		icon: 'ti ti-download',
 		download: props.file.name,
 	}, null, {
 		text: i18n.ts.delete,
-		icon: 'fas fa-trash-alt',
+		icon: 'ti ti-trash',
 		danger: true,
 		action: deleteFile,
 	}];
diff --git a/packages/client/src/components/MkDrive.folder.vue b/packages/client/src/components/MkDrive.folder.vue
index 6c522c0862..78d1816522 100644
--- a/packages/client/src/components/MkDrive.folder.vue
+++ b/packages/client/src/components/MkDrive.folder.vue
@@ -16,8 +16,8 @@
 	@dragend="onDragend"
 >
 	<p class="name">
-		<template v-if="hover"><i class="fas fa-folder-open fa-fw"></i></template>
-		<template v-if="!hover"><i class="fas fa-folder fa-fw"></i></template>
+		<template v-if="hover"><i class="fas fa-folder-open ti-fw"></i></template>
+		<template v-if="!hover"><i class="fas fa-folder ti-fw"></i></template>
 		{{ folder.name }}
 	</p>
 	<p v-if="defaultStore.state.uploadFolder == folder.id" class="upload">
@@ -253,11 +253,11 @@ function onContextmenu(ev: MouseEvent) {
 		},
 	}, null, {
 		text: i18n.ts.rename,
-		icon: 'fas fa-i-cursor',
+		icon: 'ti ti-cursor-text',
 		action: rename,
 	}, null, {
 		text: i18n.ts.delete,
-		icon: 'fas fa-trash-alt',
+		icon: 'ti ti-trash',
 		danger: true,
 		action: deleteFolder,
 	}], ev);
diff --git a/packages/client/src/components/MkDrive.navFolder.vue b/packages/client/src/components/MkDrive.navFolder.vue
index 455c14f95e..3614113501 100644
--- a/packages/client/src/components/MkDrive.navFolder.vue
+++ b/packages/client/src/components/MkDrive.navFolder.vue
@@ -7,7 +7,7 @@
 	@dragleave="onDragleave"
 	@drop.stop="onDrop"
 >
-	<i v-if="folder == null" class="fas fa-cloud"></i>
+	<i v-if="folder == null" class="ti ti-cloud"></i>
 	<span>{{ folder == null ? i18n.ts.drive : folder.name }}</span>
 </div>
 </template>
diff --git a/packages/client/src/components/MkDrive.vue b/packages/client/src/components/MkDrive.vue
index c79ab97000..83b16cfc60 100644
--- a/packages/client/src/components/MkDrive.vue
+++ b/packages/client/src/components/MkDrive.vue
@@ -11,7 +11,7 @@
 				@removeFolder="removeFolder"
 			/>
 			<template v-for="f in hierarchyFolders">
-				<span class="separator"><i class="fas fa-angle-right"></i></span>
+				<span class="separator"><i class="ti ti-chevron-right"></i></span>
 				<XNavFolder
 					:folder="f"
 					:parent-folder="folder"
@@ -21,10 +21,10 @@
 					@removeFolder="removeFolder"
 				/>
 			</template>
-			<span v-if="folder != null" class="separator"><i class="fas fa-angle-right"></i></span>
+			<span v-if="folder != null" class="separator"><i class="ti ti-chevron-right"></i></span>
 			<span v-if="folder != null" class="folder current">{{ folder.name }}</span>
 		</div>
-		<button class="menu _button" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
+		<button class="menu _button" @click="showMenu"><i class="ti ti-dots"></i></button>
 	</nav>
 	<div
 		ref="main" class="main"
@@ -588,22 +588,22 @@ function getMenu() {
 		type: 'label',
 	}, {
 		text: i18n.ts.upload,
-		icon: 'fas fa-upload',
+		icon: 'ti ti-upload',
 		action: () => { selectLocalFile(); },
 	}, {
 		text: i18n.ts.fromUrl,
-		icon: 'fas fa-link',
+		icon: 'ti ti-link',
 		action: () => { urlUpload(); },
 	}, null, {
 		text: folder.value ? folder.value.name : i18n.ts.drive,
 		type: 'label',
 	}, folder.value ? {
 		text: i18n.ts.renameFolder,
-		icon: 'fas fa-i-cursor',
+		icon: 'ti ti-cursor-text',
 		action: () => { renameFolder(folder.value); },
 	} : undefined, folder.value ? {
 		text: i18n.ts.deleteFolder,
-		icon: 'fas fa-trash-alt',
+		icon: 'ti ti-trash',
 		action: () => { deleteFolder(folder.value as Misskey.entities.DriveFolder); },
 	} : undefined, {
 		text: i18n.ts.createFolder,
diff --git a/packages/client/src/components/MkDriveFileThumbnail.vue b/packages/client/src/components/MkDriveFileThumbnail.vue
index de65d2f25b..33379ed5ca 100644
--- a/packages/client/src/components/MkDriveFileThumbnail.vue
+++ b/packages/client/src/components/MkDriveFileThumbnail.vue
@@ -1,16 +1,16 @@
 <template>
 <div ref="thumbnail" class="zdjebgpv">
 	<ImgWithBlurhash v-if="isThumbnailAvailable" :hash="file.blurhash" :src="file.thumbnailUrl" :alt="file.name" :title="file.name" :cover="fit !== 'contain'"/>
-	<i v-else-if="is === 'image'" class="fas fa-file-image icon"></i>
-	<i v-else-if="is === 'video'" class="fas fa-file-video icon"></i>
-	<i v-else-if="is === 'audio' || is === 'midi'" class="fas fa-music icon"></i>
-	<i v-else-if="is === 'csv'" class="fas fa-file-csv icon"></i>
-	<i v-else-if="is === 'pdf'" class="fas fa-file-pdf icon"></i>
-	<i v-else-if="is === 'textfile'" class="fas fa-file-alt icon"></i>
-	<i v-else-if="is === 'archive'" class="fas fa-file-archive icon"></i>
-	<i v-else class="fas fa-file icon"></i>
+	<i v-else-if="is === 'image'" class="ti ti-photo icon"></i>
+	<i v-else-if="is === 'video'" class="ti ti-video icon"></i>
+	<i v-else-if="is === 'audio' || is === 'midi'" class="ti ti-file-music icon"></i>
+	<i v-else-if="is === 'csv'" class="ti ti-file-text icon"></i>
+	<i v-else-if="is === 'pdf'" class="ti ti-file-text icon"></i>
+	<i v-else-if="is === 'textfile'" class="ti ti-file-text icon"></i>
+	<i v-else-if="is === 'archive'" class="ti ti-file-zip icon"></i>
+	<i v-else class="ti ti-file icon"></i>
 
-	<i v-if="isThumbnailAvailable && is === 'video'" class="fas fa-film icon-sub"></i>
+	<i v-if="isThumbnailAvailable && is === 'video'" class="ti ti-video icon-sub"></i>
 </div>
 </template>
 
diff --git a/packages/client/src/components/MkEmojiPicker.section.vue b/packages/client/src/components/MkEmojiPicker.section.vue
index e2a80d5466..f6ba7abfc4 100644
--- a/packages/client/src/components/MkEmojiPicker.section.vue
+++ b/packages/client/src/components/MkEmojiPicker.section.vue
@@ -2,7 +2,7 @@
 <!-- このコンポーネントの要素のclassは親から利用されるのでむやみに弄らないこと -->
 <section>
 	<header class="_acrylic" @click="shown = !shown">
-		<i class="toggle fa-fw" :class="shown ? 'fas fa-chevron-down' : 'fas fa-chevron-up'"></i> <slot></slot> ({{ emojis.length }})
+		<i class="toggle ti-fw" :class="shown ? 'ti ti-chevron-down' : 'ti ti-chevron-up'"></i> <slot></slot> ({{ emojis.length }})
 	</header>
 	<div v-if="shown" class="body">
 		<button
diff --git a/packages/client/src/components/MkEmojiPicker.vue b/packages/client/src/components/MkEmojiPicker.vue
index 3dc90ce545..a85ba2b9be 100644
--- a/packages/client/src/components/MkEmojiPicker.vue
+++ b/packages/client/src/components/MkEmojiPicker.vue
@@ -46,7 +46,7 @@
 			</section>
 
 			<section>
-				<header class="_acrylic"><i class="far fa-clock fa-fw"></i> {{ i18n.ts.recentUsed }}</header>
+				<header class="_acrylic"><i class="far fa-clock ti-fw"></i> {{ i18n.ts.recentUsed }}</header>
 				<div class="body">
 					<button
 						v-for="emoji in recentlyUsedEmojis"
@@ -69,10 +69,10 @@
 		</div>
 	</div>
 	<div class="tabs">
-		<button class="_button tab" :class="{ active: tab === 'index' }" @click="tab = 'index'"><i class="fas fa-asterisk fa-fw"></i></button>
-		<button class="_button tab" :class="{ active: tab === 'custom' }" @click="tab = 'custom'"><i class="fas fa-laugh fa-fw"></i></button>
-		<button class="_button tab" :class="{ active: tab === 'unicode' }" @click="tab = 'unicode'"><i class="fas fa-leaf fa-fw"></i></button>
-		<button class="_button tab" :class="{ active: tab === 'tags' }" @click="tab = 'tags'"><i class="fas fa-hashtag fa-fw"></i></button>
+		<button class="_button tab" :class="{ active: tab === 'index' }" @click="tab = 'index'"><i class="fas fa-asterisk ti-fw"></i></button>
+		<button class="_button tab" :class="{ active: tab === 'custom' }" @click="tab = 'custom'"><i class="ti ti-mood-happy ti-fw"></i></button>
+		<button class="_button tab" :class="{ active: tab === 'unicode' }" @click="tab = 'unicode'"><i class="fas fa-leaf ti-fw"></i></button>
+		<button class="_button tab" :class="{ active: tab === 'tags' }" @click="tab = 'tags'"><i class="ti ti-hash ti-fw"></i></button>
 	</div>
 </div>
 </template>
diff --git a/packages/client/src/components/MkFolder.vue b/packages/client/src/components/MkFolder.vue
index 7daa82cbd3..bc9bff99b6 100644
--- a/packages/client/src/components/MkFolder.vue
+++ b/packages/client/src/components/MkFolder.vue
@@ -4,8 +4,8 @@
 		<div class="title"><slot name="header"></slot></div>
 		<div class="divider"></div>
 		<button class="_button">
-			<template v-if="showBody"><i class="fas fa-angle-up"></i></template>
-			<template v-else><i class="fas fa-angle-down"></i></template>
+			<template v-if="showBody"><i class="ti ti-chevron-up"></i></template>
+			<template v-else><i class="ti ti-chevron-down"></i></template>
 		</button>
 	</header>
 	<transition :name="$store.state.animation ? 'folder-toggle' : ''"
diff --git a/packages/client/src/components/MkFollowButton.vue b/packages/client/src/components/MkFollowButton.vue
index efee795e43..1099893b0d 100644
--- a/packages/client/src/components/MkFollowButton.vue
+++ b/packages/client/src/components/MkFollowButton.vue
@@ -12,17 +12,17 @@
 			<span v-if="full">{{ i18n.ts.processing }}</span><i class="fas fa-spinner fa-pulse"></i>
 		</template>
 		<template v-else-if="isFollowing">
-			<span v-if="full">{{ i18n.ts.unfollow }}</span><i class="fas fa-minus"></i>
+			<span v-if="full">{{ i18n.ts.unfollow }}</span><i class="ti ti-minus"></i>
 		</template>
 		<template v-else-if="!isFollowing && user.isLocked">
-			<span v-if="full">{{ i18n.ts.followRequest }}</span><i class="fas fa-plus"></i>
+			<span v-if="full">{{ i18n.ts.followRequest }}</span><i class="ti ti-plus"></i>
 		</template>
 		<template v-else-if="!isFollowing && !user.isLocked">
-			<span v-if="full">{{ i18n.ts.follow }}</span><i class="fas fa-plus"></i>
+			<span v-if="full">{{ i18n.ts.follow }}</span><i class="ti ti-plus"></i>
 		</template>
 	</template>
 	<template v-else>
-		<span v-if="full">{{ i18n.ts.processing }}</span><i class="fas fa-spinner fa-pulse fa-fw"></i>
+		<span v-if="full">{{ i18n.ts.processing }}</span><i class="fas fa-spinner fa-pulse ti-fw"></i>
 	</template>
 </button>
 </template>
diff --git a/packages/client/src/components/MkGoogle.vue b/packages/client/src/components/MkGoogle.vue
index bb4b439ee8..d104cd4cd4 100644
--- a/packages/client/src/components/MkGoogle.vue
+++ b/packages/client/src/components/MkGoogle.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="mk-google">
 	<input v-model="query" type="search" :placeholder="q">
-	<button @click="search"><i class="fas fa-search"></i> {{ $ts.searchByGoogle }}</button>
+	<button @click="search"><i class="ti ti-search"></i> {{ $ts.searchByGoogle }}</button>
 </div>
 </template>
 
diff --git a/packages/client/src/components/MkInfo.vue b/packages/client/src/components/MkInfo.vue
index 4fdfc5c5e6..2eb6bdbe47 100644
--- a/packages/client/src/components/MkInfo.vue
+++ b/packages/client/src/components/MkInfo.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="fpezltsf" :class="{ warn }">
-	<i v-if="warn" class="fas fa-exclamation-triangle"></i>
-	<i v-else class="fas fa-info-circle"></i>
+	<i v-if="warn" class="ti ti-alert-triangle"></i>
+	<i v-else class="ti ti-info-circle"></i>
 	<slot></slot>
 </div>
 </template>
diff --git a/packages/client/src/components/MkLaunchPad.vue b/packages/client/src/components/MkLaunchPad.vue
index 19283178c9..1ccc648c72 100644
--- a/packages/client/src/components/MkLaunchPad.vue
+++ b/packages/client/src/components/MkLaunchPad.vue
@@ -6,12 +6,12 @@
 				<button v-if="item.action" v-click-anime class="_button" @click="$event => { item.action($event); close(); }">
 					<i class="icon" :class="item.icon"></i>
 					<div class="text">{{ item.text }}</div>
-					<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
+					<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
 				</button>
 				<MkA v-else v-click-anime :to="item.to" @click.passive="close()">
 					<i class="icon" :class="item.icon"></i>
 					<div class="text">{{ item.text }}</div>
-					<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
+					<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
 				</MkA>
 			</template>
 		</div>
diff --git a/packages/client/src/components/MkLink.vue b/packages/client/src/components/MkLink.vue
index 649523abc2..6148ec6195 100644
--- a/packages/client/src/components/MkLink.vue
+++ b/packages/client/src/components/MkLink.vue
@@ -1,9 +1,10 @@
 <template>
-<component :is="self ? 'MkA' : 'a'" ref="el" class="xlcxczvw _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
+<component
+	:is="self ? 'MkA' : 'a'" ref="el" class="xlcxczvw _link" :[attr]="self ? url.substr(local.length) : url" :rel="rel" :target="target"
 	:title="url"
 >
 	<slot></slot>
-	<i v-if="target === '_blank'" class="fas fa-external-link-square-alt icon"></i>
+	<i v-if="target === '_blank'" class="ti ti-external-link icon"></i>
 </component>
 </template>
 
diff --git a/packages/client/src/components/MkMediaBanner.vue b/packages/client/src/components/MkMediaBanner.vue
index 5093f11e97..aa06c00fc6 100644
--- a/packages/client/src/components/MkMediaBanner.vue
+++ b/packages/client/src/components/MkMediaBanner.vue
@@ -1,25 +1,28 @@
 <template>
 <div class="mk-media-banner">
 	<div v-if="media.isSensitive && hide" class="sensitive" @click="hide = false">
-		<span class="icon"><i class="fas fa-exclamation-triangle"></i></span>
+		<span class="icon"><i class="ti ti-alert-triangle"></i></span>
 		<b>{{ $ts.sensitive }}</b>
 		<span>{{ $ts.clickToShow }}</span>
 	</div>
 	<div v-else-if="media.type.startsWith('audio') && media.type !== 'audio/midi'" class="audio">
-		<audio ref="audioEl"
+		<audio
+			ref="audioEl"
 			class="audio"
 			:src="media.url"
 			:title="media.name"
 			controls
 			preload="metadata"
-			@volumechange="volumechange" />
+			@volumechange="volumechange"
+		/>
 	</div>
-	<a v-else class="download"
+	<a
+		v-else class="download"
 		:href="media.url"
 		:title="media.name"
 		:download="media.name"
 	>
-		<span class="icon"><i class="fas fa-download"></i></span>
+		<span class="icon"><i class="ti ti-download"></i></span>
 		<b>{{ media.name }}</b>
 	</a>
 </div>
diff --git a/packages/client/src/components/MkMediaImage.vue b/packages/client/src/components/MkMediaImage.vue
index 92f1bd2dbd..56570eaa05 100644
--- a/packages/client/src/components/MkMediaImage.vue
+++ b/packages/client/src/components/MkMediaImage.vue
@@ -3,7 +3,7 @@
 	<ImgWithBlurhash class="bg" :hash="image.blurhash" :title="image.comment" :alt="image.comment"/>
 	<div class="text">
 		<div class="wrapper">
-			<b style="display: block;"><i class="fas fa-exclamation-triangle"></i> {{ $ts.sensitive }}</b>
+			<b style="display: block;"><i class="ti ti-alert-triangle"></i> {{ $ts.sensitive }}</b>
 			<span style="display: block;">{{ $ts.clickToShow }}</span>
 		</div>
 	</div>
@@ -16,7 +16,7 @@
 		<ImgWithBlurhash :hash="image.blurhash" :src="url" :alt="image.comment" :title="image.comment" :cover="false"/>
 		<div v-if="image.type === 'image/gif'" class="gif">GIF</div>
 	</a>
-	<button v-tooltip="$ts.hide" class="_button hide" @click="hide = true"><i class="fas fa-eye-slash"></i></button>
+	<button v-tooltip="$ts.hide" class="_button hide" @click="hide = true"><i class="ti ti-eye-off"></i></button>
 </div>
 </template>
 
diff --git a/packages/client/src/components/MkMediaVideo.vue b/packages/client/src/components/MkMediaVideo.vue
index 5c38691e69..df0bf84116 100644
--- a/packages/client/src/components/MkMediaVideo.vue
+++ b/packages/client/src/components/MkMediaVideo.vue
@@ -1,7 +1,7 @@
 <template>
 <div v-if="hide" class="icozogqfvdetwohsdglrbswgrejoxbdj" @click="hide = false">
 	<div>
-		<b><i class="fas fa-exclamation-triangle"></i> {{ $ts.sensitive }}</b>
+		<b><i class="ti ti-alert-triangle"></i> {{ $ts.sensitive }}</b>
 		<span>{{ $ts.clickToShow }}</span>
 	</div>
 </div>
@@ -19,7 +19,7 @@
 			:type="video.type"
 		>
 	</video>
-	<i class="fas fa-eye-slash" @click="hide = true"></i>
+	<i class="ti ti-eye-off" @click="hide = true"></i>
 </div>
 </template>
 
diff --git a/packages/client/src/components/MkMenu.vue b/packages/client/src/components/MkMenu.vue
index 87755916a7..64d18b6b7c 100644
--- a/packages/client/src/components/MkMenu.vue
+++ b/packages/client/src/components/MkMenu.vue
@@ -16,33 +16,33 @@
 				<span><MkEllipsis/></span>
 			</span>
 			<MkA v-else-if="item.type === 'link'" :to="item.to" :tabindex="i" class="_button item" @click.passive="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
-				<i v-if="item.icon" class="fa-fw" :class="item.icon"></i>
+				<i v-if="item.icon" class="ti-fw" :class="item.icon"></i>
 				<MkAvatar v-if="item.avatar" :user="item.avatar" class="avatar"/>
 				<span>{{ item.text }}</span>
-				<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
+				<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
 			</MkA>
 			<a v-else-if="item.type === 'a'" :href="item.href" :target="item.target" :download="item.download" :tabindex="i" class="_button item" @click="close(true)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
-				<i v-if="item.icon" class="fa-fw" :class="item.icon"></i>
+				<i v-if="item.icon" class="ti-fw" :class="item.icon"></i>
 				<span>{{ item.text }}</span>
-				<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
+				<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
 			</a>
 			<button v-else-if="item.type === 'user'" :tabindex="i" class="_button item" :class="{ active: item.active }" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
 				<MkAvatar :user="item.user" class="avatar"/><MkUserName :user="item.user"/>
-				<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
+				<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
 			</button>
 			<span v-else-if="item.type === 'switch'" :tabindex="i" class="item" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
 				<FormSwitch v-model="item.ref" :disabled="item.disabled" class="form-switch">{{ item.text }}</FormSwitch>
 			</span>
 			<button v-else-if="item.type === 'parent'" :tabindex="i" class="_button item parent" :class="{ childShowing: childShowingItem === item }" @mouseenter="showChildren(item, $event)">
-				<i v-if="item.icon" class="fa-fw" :class="item.icon"></i>
+				<i v-if="item.icon" class="ti-fw" :class="item.icon"></i>
 				<span>{{ item.text }}</span>
-				<span class="caret"><i class="fas fa-caret-right fa-fw"></i></span>
+				<span class="caret"><i class="ti ti-caret-right ti-fw"></i></span>
 			</button>
 			<button v-else :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active }" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)">
-				<i v-if="item.icon" class="fa-fw" :class="item.icon"></i>
+				<i v-if="item.icon" class="ti-fw" :class="item.icon"></i>
 				<MkAvatar v-if="item.avatar" :user="item.avatar" class="avatar"/>
 				<span>{{ item.text }}</span>
-				<span v-if="item.indicate" class="indicator"><i class="fas fa-circle"></i></span>
+				<span v-if="item.indicate" class="indicator"><i class="_indicatorCircle"></i></span>
 			</button>
 		</template>
 		<span v-if="items2.length === 0" class="none item">
diff --git a/packages/client/src/components/MkModalPageWindow.vue b/packages/client/src/components/MkModalPageWindow.vue
index cc3f4c96cc..82b04b6670 100644
--- a/packages/client/src/components/MkModalPageWindow.vue
+++ b/packages/client/src/components/MkModalPageWindow.vue
@@ -2,13 +2,13 @@
 <MkModal ref="modal" @click="$emit('click')" @closed="$emit('closed')">
 	<div ref="rootEl" class="hrmcaedk _narrow_" :style="{ width: `${width}px`, height: (height ? `min(${height}px, 100%)` : '100%') }">
 		<div class="header" @contextmenu="onContextmenu">
-			<button v-if="history.length > 0" v-tooltip="$ts.goBack" class="_button" @click="back()"><i class="fas fa-arrow-left"></i></button>
+			<button v-if="history.length > 0" v-tooltip="$ts.goBack" class="_button" @click="back()"><i class="ti ti-arrow-left"></i></button>
 			<span v-else style="display: inline-block; width: 20px"></span>
 			<span v-if="pageMetadata?.value" class="title">
 				<i v-if="pageMetadata?.value.icon" class="icon" :class="pageMetadata?.value.icon"></i>
 				<span>{{ pageMetadata?.value.title }}</span>
 			</span>
-			<button class="_button" @click="$refs.modal.close()"><i class="fas fa-times"></i></button>
+			<button class="_button" @click="$refs.modal.close()"><i class="ti ti-x"></i></button>
 		</div>
 		<div class="body">
 			<MkStickyContainer>
@@ -68,22 +68,22 @@ const contextmenu = $computed(() => {
 		type: 'label',
 		text: path,
 	}, {
-		icon: 'fas fa-expand-alt',
+		icon: 'ti ti-arrows-maximize',
 		text: i18n.ts.showInPage,
 		action: expand,
 	}, {
-		icon: 'fas fa-external-link-alt',
+		icon: 'ti ti-external-link',
 		text: i18n.ts.popout,
 		action: popout,
 	}, null, {
-		icon: 'fas fa-external-link-alt',
+		icon: 'ti ti-external-link',
 		text: i18n.ts.openInNewTab,
 		action: () => {
 			window.open(pageUrl, '_blank');
 			modal.close();
 		},
 	}, {
-		icon: 'fas fa-link',
+		icon: 'ti ti-link',
 		text: i18n.ts.copyLink,
 		action: () => {
 			copyToClipboard(pageUrl);
diff --git a/packages/client/src/components/MkModalWindow.vue b/packages/client/src/components/MkModalWindow.vue
index 5acd8c921f..d977ca6e9c 100644
--- a/packages/client/src/components/MkModalWindow.vue
+++ b/packages/client/src/components/MkModalWindow.vue
@@ -2,12 +2,12 @@
 <MkModal ref="modal" :prefer-type="'dialog'" @click="onBgClick" @closed="$emit('closed')">
 	<div ref="rootEl" class="ebkgoccj _narrow_" :style="{ width: `${width}px`, height: scroll ? (height ? `${height}px` : null) : (height ? `min(${height}px, 100%)` : '100%') }" @keydown="onKeydown">
 		<div ref="headerEl" class="header">
-			<button v-if="withOkButton" class="_button" @click="$emit('close')"><i class="fas fa-times"></i></button>
+			<button v-if="withOkButton" class="_button" @click="$emit('close')"><i class="ti ti-x"></i></button>
 			<span class="title">
 				<slot name="header"></slot>
 			</span>
-			<button v-if="!withOkButton" class="_button" @click="$emit('close')"><i class="fas fa-times"></i></button>
-			<button v-if="withOkButton" class="_button" :disabled="okButtonDisabled" @click="$emit('ok')"><i class="fas fa-check"></i></button>
+			<button v-if="!withOkButton" class="_button" @click="$emit('close')"><i class="ti ti-x"></i></button>
+			<button v-if="withOkButton" class="_button" :disabled="okButtonDisabled" @click="$emit('ok')"><i class="ti ti-check"></i></button>
 		</div>
 		<div class="body">
 			<slot :width="bodyWidth" :height="bodyHeight"></slot>
diff --git a/packages/client/src/components/MkNote.vue b/packages/client/src/components/MkNote.vue
index 97eadb1945..da51d14f03 100644
--- a/packages/client/src/components/MkNote.vue
+++ b/packages/client/src/components/MkNote.vue
@@ -10,12 +10,12 @@
 	:class="{ renote: isRenote }"
 >
 	<MkNoteSub v-if="appearNote.reply" :note="appearNote.reply" class="reply-to"/>
-	<div v-if="pinned" class="info"><i class="fas fa-thumbtack"></i> {{ i18n.ts.pinnedNote }}</div>
-	<div v-if="appearNote._prId_" class="info"><i class="fas fa-bullhorn"></i> {{ i18n.ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ i18n.ts.hideThisNote }} <i class="fas fa-times"></i></button></div>
-	<div v-if="appearNote._featuredId_" class="info"><i class="fas fa-bolt"></i> {{ i18n.ts.featured }}</div>
+	<div v-if="pinned" class="info"><i class="ti ti-pin"></i> {{ i18n.ts.pinnedNote }}</div>
+	<div v-if="appearNote._prId_" class="info"><i class="fas fa-bullhorn"></i> {{ i18n.ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ i18n.ts.hideThisNote }} <i class="ti ti-x"></i></button></div>
+	<div v-if="appearNote._featuredId_" class="info"><i class="ti ti-bolt"></i> {{ i18n.ts.featured }}</div>
 	<div v-if="isRenote" class="renote">
 		<MkAvatar class="avatar" :user="note.user"/>
-		<i class="fas fa-retweet"></i>
+		<i class="ti ti-repeat"></i>
 		<I18n :src="i18n.ts.renotedBy" tag="span">
 			<template #user>
 				<MkA v-user-preview="note.userId" class="name" :to="userPage(note.user)">
@@ -25,7 +25,7 @@
 		</I18n>
 		<div class="info">
 			<button ref="renoteTime" class="_button time" @click="showRenoteMenu()">
-				<i v-if="isMyRenote" class="fas fa-ellipsis-h dropdownIcon"></i>
+				<i v-if="isMyRenote" class="ti ti-dots dropdownIcon"></i>
 				<MkTime :time="note.createdAt"/>
 			</button>
 			<MkVisibility :note="note"/>
@@ -44,7 +44,7 @@
 				<div v-show="appearNote.cw == null || showContent" class="content" :class="{ collapsed, isLong }">
 					<div class="text">
 						<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
-						<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
+						<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
 						<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
 						<a v-if="appearNote.renote != null" class="rp">RN:</a>
 						<div v-if="translating || translation" class="translation">
@@ -68,24 +68,24 @@
 						<span>{{ i18n.ts.showLess }}</span>
 					</button>
 				</div>
-				<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="fas fa-satellite-dish"></i> {{ appearNote.channel.name }}</MkA>
+				<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
 			</div>
 			<footer class="footer">
 				<XReactionsViewer ref="reactionsViewer" :note="appearNote"/>
 				<button class="button _button" @click="reply()">
-					<template v-if="appearNote.reply"><i class="fas fa-reply-all"></i></template>
-					<template v-else><i class="fas fa-reply"></i></template>
+					<template v-if="appearNote.reply"><i class="ti ti-arrow-back-up-all"></i></template>
+					<template v-else><i class="ti ti-arrow-back-up"></i></template>
 					<p v-if="appearNote.repliesCount > 0" class="count">{{ appearNote.repliesCount }}</p>
 				</button>
 				<XRenoteButton ref="renoteButton" class="button" :note="appearNote" :count="appearNote.renoteCount"/>
 				<button v-if="appearNote.myReaction == null" ref="reactButton" class="button _button" @click="react()">
-					<i class="fas fa-plus"></i>
+					<i class="ti ti-plus"></i>
 				</button>
 				<button v-if="appearNote.myReaction != null" ref="reactButton" class="button _button reacted" @click="undoReact(appearNote)">
-					<i class="fas fa-minus"></i>
+					<i class="ti ti-minus"></i>
 				</button>
 				<button ref="menuButton" class="button _button" @click="menu()">
-					<i class="fas fa-ellipsis-h"></i>
+					<i class="ti ti-dots"></i>
 				</button>
 			</footer>
 		</div>
@@ -256,7 +256,7 @@ function showRenoteMenu(viaKeyboard = false): void {
 	if (!isMyRenote) return;
 	os.popupMenu([{
 		text: i18n.ts.unrenote,
-		icon: 'fas fa-trash-alt',
+		icon: 'ti ti-trash',
 		danger: true,
 		action: () => {
 			os.api('notes/delete', {
diff --git a/packages/client/src/components/MkNoteDetailed.vue b/packages/client/src/components/MkNoteDetailed.vue
index 0ba93bbd76..19e895e11d 100644
--- a/packages/client/src/components/MkNoteDetailed.vue
+++ b/packages/client/src/components/MkNoteDetailed.vue
@@ -13,7 +13,7 @@
 	<MkNoteSub v-if="appearNote.reply" :note="appearNote.reply" class="reply-to"/>
 	<div v-if="isRenote" class="renote">
 		<MkAvatar class="avatar" :user="note.user"/>
-		<i class="fas fa-retweet"></i>
+		<i class="ti ti-repeat"></i>
 		<I18n :src="i18n.ts.renotedBy" tag="span">
 			<template #user>
 				<MkA v-user-preview="note.userId" class="name" :to="userPage(note.user)">
@@ -23,7 +23,7 @@
 		</I18n>
 		<div class="info">
 			<button ref="renoteTime" class="_button time" @click="showRenoteMenu()">
-				<i v-if="isMyRenote" class="fas fa-ellipsis-h dropdownIcon"></i>
+				<i v-if="isMyRenote" class="ti ti-dots dropdownIcon"></i>
 				<MkTime :time="note.createdAt"/>
 			</button>
 			<MkVisibility :note="note"/>
@@ -55,7 +55,7 @@
 				<div v-show="appearNote.cw == null || showContent" class="content">
 					<div class="text">
 						<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
-						<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
+						<MkA v-if="appearNote.replyId" class="reply" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
 						<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
 						<a v-if="appearNote.renote != null" class="rp">RN:</a>
 						<div v-if="translating || translation" class="translation">
@@ -73,7 +73,7 @@
 					<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" class="url-preview"/>
 					<div v-if="appearNote.renote" class="renote"><XNoteSimple :note="appearNote.renote"/></div>
 				</div>
-				<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="fas fa-satellite-dish"></i> {{ appearNote.channel.name }}</MkA>
+				<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
 			</div>
 			<footer class="footer">
 				<div class="info">
@@ -83,19 +83,19 @@
 				</div>
 				<XReactionsViewer ref="reactionsViewer" :note="appearNote"/>
 				<button class="button _button" @click="reply()">
-					<template v-if="appearNote.reply"><i class="fas fa-reply-all"></i></template>
-					<template v-else><i class="fas fa-reply"></i></template>
+					<template v-if="appearNote.reply"><i class="ti ti-arrow-back-up-all"></i></template>
+					<template v-else><i class="ti ti-arrow-back-up"></i></template>
 					<p v-if="appearNote.repliesCount > 0" class="count">{{ appearNote.repliesCount }}</p>
 				</button>
 				<XRenoteButton ref="renoteButton" class="button" :note="appearNote" :count="appearNote.renoteCount"/>
 				<button v-if="appearNote.myReaction == null" ref="reactButton" class="button _button" @click="react()">
-					<i class="fas fa-plus"></i>
+					<i class="ti ti-plus"></i>
 				</button>
 				<button v-if="appearNote.myReaction != null" ref="reactButton" class="button _button reacted" @click="undoReact(appearNote)">
-					<i class="fas fa-minus"></i>
+					<i class="ti ti-minus"></i>
 				</button>
 				<button ref="menuButton" class="button _button" @click="menu()">
-					<i class="fas fa-ellipsis-h"></i>
+					<i class="ti ti-dots"></i>
 				</button>
 			</footer>
 		</div>
@@ -259,7 +259,7 @@ function showRenoteMenu(viaKeyboard = false): void {
 	if (!isMyRenote) return;
 	os.popupMenu([{
 		text: i18n.ts.unrenote,
-		icon: 'fas fa-trash-alt',
+		icon: 'ti ti-trash',
 		danger: true,
 		action: () => {
 			os.api('notes/delete', {
diff --git a/packages/client/src/components/MkNoteSub.vue b/packages/client/src/components/MkNoteSub.vue
index a69336f8a1..95b6b71be9 100644
--- a/packages/client/src/components/MkNoteSub.vue
+++ b/packages/client/src/components/MkNoteSub.vue
@@ -19,7 +19,7 @@
 		<MkNoteSub v-for="reply in replies" :key="reply.id" :note="reply" class="reply" :detail="true" :depth="depth + 1"/>
 	</template>
 	<div v-else class="more">
-		<MkA class="text _link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="fas fa-angle-double-right"></i></MkA>
+		<MkA class="text _link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="ti ti-chevron-double-right"></i></MkA>
 	</div>
 </div>
 </template>
diff --git a/packages/client/src/components/MkNotification.vue b/packages/client/src/components/MkNotification.vue
index c00e9fbf42..dd846e3e66 100644
--- a/packages/client/src/components/MkNotification.vue
+++ b/packages/client/src/components/MkNotification.vue
@@ -5,16 +5,16 @@
 		<MkAvatar v-else-if="notification.user" class="icon" :user="notification.user"/>
 		<img v-else-if="notification.icon" class="icon" :src="notification.icon" alt=""/>
 		<div class="sub-icon" :class="notification.type">
-			<i v-if="notification.type === 'follow'" class="fas fa-plus"></i>
-			<i v-else-if="notification.type === 'receiveFollowRequest'" class="fas fa-clock"></i>
-			<i v-else-if="notification.type === 'followRequestAccepted'" class="fas fa-check"></i>
+			<i v-if="notification.type === 'follow'" class="ti ti-plus"></i>
+			<i v-else-if="notification.type === 'receiveFollowRequest'" class="ti ti-clock"></i>
+			<i v-else-if="notification.type === 'followRequestAccepted'" class="ti ti-check"></i>
 			<i v-else-if="notification.type === 'groupInvited'" class="fas fa-id-card-alt"></i>
-			<i v-else-if="notification.type === 'renote'" class="fas fa-retweet"></i>
-			<i v-else-if="notification.type === 'reply'" class="fas fa-reply"></i>
-			<i v-else-if="notification.type === 'mention'" class="fas fa-at"></i>
-			<i v-else-if="notification.type === 'quote'" class="fas fa-quote-left"></i>
-			<i v-else-if="notification.type === 'pollVote'" class="fas fa-poll-h"></i>
-			<i v-else-if="notification.type === 'pollEnded'" class="fas fa-poll-h"></i>
+			<i v-else-if="notification.type === 'renote'" class="ti ti-repeat"></i>
+			<i v-else-if="notification.type === 'reply'" class="ti ti-arrow-back-up"></i>
+			<i v-else-if="notification.type === 'mention'" class="ti ti-at"></i>
+			<i v-else-if="notification.type === 'quote'" class="ti ti-quote"></i>
+			<i v-else-if="notification.type === 'pollVote'" class="ti ti-chart-arrows"></i>
+			<i v-else-if="notification.type === 'pollEnded'" class="ti ti-chart-arrows"></i>
 			<!-- notification.reaction が null になることはまずないが、ここでoptional chaining使うと一部ブラウザで刺さるので念の為 -->
 			<XReactionIcon
 				v-else-if="notification.type === 'reaction'"
@@ -33,14 +33,14 @@
 			<MkTime v-if="withTime" :time="notification.createdAt" class="time"/>
 		</header>
 		<MkA v-if="notification.type === 'reaction'" class="text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
-			<i class="fas fa-quote-left"></i>
+			<i class="ti ti-quote"></i>
 			<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
-			<i class="fas fa-quote-right"></i>
+			<i class="ti ti-quote"></i>
 		</MkA>
 		<MkA v-if="notification.type === 'renote'" class="text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note.renote)">
-			<i class="fas fa-quote-left"></i>
+			<i class="ti ti-quote"></i>
 			<Mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.renote.emojis"/>
-			<i class="fas fa-quote-right"></i>
+			<i class="ti ti-quote"></i>
 		</MkA>
 		<MkA v-if="notification.type === 'reply'" class="text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
 			<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
@@ -52,14 +52,14 @@
 			<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
 		</MkA>
 		<MkA v-if="notification.type === 'pollVote'" class="text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
-			<i class="fas fa-quote-left"></i>
+			<i class="ti ti-quote"></i>
 			<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
-			<i class="fas fa-quote-right"></i>
+			<i class="ti ti-quote"></i>
 		</MkA>
 		<MkA v-if="notification.type === 'pollEnded'" class="text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
-			<i class="fas fa-quote-left"></i>
+			<i class="ti ti-quote"></i>
 			<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="!full" :custom-emojis="notification.note.emojis"/>
-			<i class="fas fa-quote-right"></i>
+			<i class="ti ti-quote"></i>
 		</MkA>
 		<span v-if="notification.type === 'follow'" class="text" style="opacity: 0.6;">{{ i18n.ts.youGotNewFollower }}<div v-if="full"><MkFollowButton :user="notification.user" :full="true"/></div></span>
 		<span v-if="notification.type === 'followRequestAccepted'" class="text" style="opacity: 0.6;">{{ i18n.ts.followRequestAccepted }}</span>
diff --git a/packages/client/src/components/MkPageWindow.vue b/packages/client/src/components/MkPageWindow.vue
index d58b914036..d5fff4be0a 100644
--- a/packages/client/src/components/MkPageWindow.vue
+++ b/packages/client/src/components/MkPageWindow.vue
@@ -57,7 +57,7 @@ const buttonsLeft = $computed(() => {
 
 	if (history.length > 1) {
 		buttons.push({
-			icon: 'fas fa-arrow-left',
+			icon: 'ti ti-arrow-left',
 			onClick: back,
 		});
 	}
@@ -66,7 +66,7 @@ const buttonsLeft = $computed(() => {
 });
 const buttonsRight = $computed(() => {
 	const buttons = [{
-		icon: 'fas fa-expand-alt',
+		icon: 'ti ti-arrows-maximize',
 		title: i18n.ts.showInPage,
 		onClick: expand,
 	}];
@@ -86,22 +86,22 @@ provide('shouldOmitHeaderTitle', true);
 provide('shouldHeaderThin', true);
 
 const contextmenu = $computed(() => ([{
-	icon: 'fas fa-expand-alt',
+	icon: 'ti ti-arrows-maximize',
 	text: i18n.ts.showInPage,
 	action: expand,
 }, {
-	icon: 'fas fa-external-link-alt',
+	icon: 'ti ti-external-link',
 	text: i18n.ts.popout,
 	action: popout,
 }, {
-	icon: 'fas fa-external-link-alt',
+	icon: 'ti ti-external-link',
 	text: i18n.ts.openInNewTab,
 	action: () => {
 		window.open(url + router.getCurrentPath(), '_blank');
 		windowEl.close();
 	},
 }, {
-	icon: 'fas fa-link',
+	icon: 'ti ti-link',
 	text: i18n.ts.copyLink,
 	action: () => {
 		copyToClipboard(url + router.getCurrentPath());
diff --git a/packages/client/src/components/MkPoll.vue b/packages/client/src/components/MkPoll.vue
index d90af1cfee..a1b927e42a 100644
--- a/packages/client/src/components/MkPoll.vue
+++ b/packages/client/src/components/MkPoll.vue
@@ -4,7 +4,7 @@
 		<li v-for="(choice, i) in note.poll.choices" :key="i" :class="{ voted: choice.voted }" @click="vote(i)">
 			<div class="backdrop" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div>
 			<span>
-				<template v-if="choice.isVoted"><i class="fas fa-check"></i></template>
+				<template v-if="choice.isVoted"><i class="ti ti-check"></i></template>
 				<Mfm :text="choice.text" :plain="true" :custom-emojis="note.emojis"/>
 				<span v-if="showResult" class="votes">({{ $t('_poll.votesCount', { n: choice.votes }) }})</span>
 			</span>
diff --git a/packages/client/src/components/MkPollEditor.vue b/packages/client/src/components/MkPollEditor.vue
index 3b08a63535..4b3bc58ed9 100644
--- a/packages/client/src/components/MkPollEditor.vue
+++ b/packages/client/src/components/MkPollEditor.vue
@@ -1,14 +1,14 @@
 <template>
 <div class="zmdxowus">
 	<p v-if="choices.length < 2" class="caution">
-		<i class="fas fa-exclamation-triangle"></i>{{ i18n.ts._poll.noOnlyOneChoice }}
+		<i class="ti ti-alert-triangle"></i>{{ i18n.ts._poll.noOnlyOneChoice }}
 	</p>
 	<ul>
 		<li v-for="(choice, i) in choices" :key="i">
 			<MkInput class="input" small :model-value="choice" :placeholder="$t('_poll.choiceN', { n: i + 1 })" @update:modelValue="onInput(i, $event)">
 			</MkInput>
 			<button class="_button" @click="remove(i)">
-				<i class="fas fa-times"></i>
+				<i class="ti ti-x"></i>
 			</button>
 		</li>
 	</ul>
diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue
index 308dd63dd3..26ce4464bc 100644
--- a/packages/client/src/components/MkPostForm.vue
+++ b/packages/client/src/components/MkPostForm.vue
@@ -8,35 +8,35 @@
 	@drop.stop="onDrop"
 >
 	<header>
-		<button v-if="!fixed" class="cancel _button" @click="cancel"><i class="fas fa-times"></i></button>
+		<button v-if="!fixed" class="cancel _button" @click="cancel"><i class="ti ti-x"></i></button>
 		<button v-click-anime v-tooltip="i18n.ts.switchAccount" class="account _button" @click="openAccountMenu">
 			<MkAvatar :user="postAccount ?? $i" class="avatar"/>
 		</button>
 		<div class="right">
 			<span class="text-count" :class="{ over: textLength > maxTextLength }">{{ maxTextLength - textLength }}</span>
-			<span v-if="localOnly" class="local-only"><i class="fas fa-biohazard"></i></span>
+			<span v-if="localOnly" class="local-only"><i class="ti ti-world-off"></i></span>
 			<button ref="visibilityButton" v-tooltip="i18n.ts.visibility" class="_button visibility" :disabled="channel != null" @click="setVisibility">
-				<span v-if="visibility === 'public'"><i class="fas fa-globe"></i></span>
-				<span v-if="visibility === 'home'"><i class="fas fa-home"></i></span>
-				<span v-if="visibility === 'followers'"><i class="fas fa-unlock"></i></span>
-				<span v-if="visibility === 'specified'"><i class="fas fa-envelope"></i></span>
+				<span v-if="visibility === 'public'"><i class="ti ti-world"></i></span>
+				<span v-if="visibility === 'home'"><i class="ti ti-home"></i></span>
+				<span v-if="visibility === 'followers'"><i class="ti ti-lock-open"></i></span>
+				<span v-if="visibility === 'specified'"><i class="ti ti-mail"></i></span>
 			</button>
 			<button v-tooltip="i18n.ts.previewNoteText" class="_button preview" :class="{ active: showPreview }" @click="showPreview = !showPreview"><i class="fas fa-file-code"></i></button>
-			<button class="submit _buttonGradate" :disabled="!canPost" data-cy-open-post-form-submit @click="post">{{ submitText }}<i :class="reply ? 'fas fa-reply' : renote ? 'fas fa-quote-right' : 'fas fa-paper-plane'"></i></button>
+			<button class="submit _buttonGradate" :disabled="!canPost" data-cy-open-post-form-submit @click="post">{{ submitText }}<i :class="reply ? 'ti ti-arrow-back-up' : renote ? 'ti ti-quote' : 'ti ti-send'"></i></button>
 		</div>
 	</header>
 	<div class="form" :class="{ fixed }">
 		<XNoteSimple v-if="reply" class="preview" :note="reply"/>
 		<XNoteSimple v-if="renote" class="preview" :note="renote"/>
-		<div v-if="quoteId" class="with-quote"><i class="fas fa-quote-left"></i> {{ i18n.ts.quoteAttached }}<button @click="quoteId = null"><i class="fas fa-times"></i></button></div>
+		<div v-if="quoteId" class="with-quote"><i class="ti ti-quote"></i> {{ i18n.ts.quoteAttached }}<button @click="quoteId = null"><i class="ti ti-x"></i></button></div>
 		<div v-if="visibility === 'specified'" class="to-specified">
 			<span style="margin-right: 8px;">{{ i18n.ts.recipient }}</span>
 			<div class="visibleUsers">
 				<span v-for="u in visibleUsers" :key="u.id">
 					<MkAcct :user="u"/>
-					<button class="_button" @click="removeVisibleUser(u)"><i class="fas fa-times"></i></button>
+					<button class="_button" @click="removeVisibleUser(u)"><i class="ti ti-x"></i></button>
 				</span>
-				<button class="_buttonPrimary" @click="addVisibleUser"><i class="fas fa-plus fa-fw"></i></button>
+				<button class="_buttonPrimary" @click="addVisibleUser"><i class="ti ti-plus ti-fw"></i></button>
 			</div>
 		</div>
 		<MkInfo v-if="hasNotSpecifiedMentions" warn class="hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo>
@@ -47,13 +47,13 @@
 		<XPollEditor v-if="poll" v-model="poll" @destroyed="poll = null"/>
 		<XNotePreview v-if="showPreview" class="preview" :text="text"/>
 		<footer>
-			<button v-tooltip="i18n.ts.attachFile" class="_button" @click="chooseFileFrom"><i class="fas fa-photo-video"></i></button>
-			<button v-tooltip="i18n.ts.poll" class="_button" :class="{ active: poll }" @click="togglePoll"><i class="fas fa-poll-h"></i></button>
-			<button v-tooltip="i18n.ts.useCw" class="_button" :class="{ active: useCw }" @click="useCw = !useCw"><i class="fas fa-eye-slash"></i></button>
-			<button v-tooltip="i18n.ts.mention" class="_button" @click="insertMention"><i class="fas fa-at"></i></button>
-			<button v-tooltip="i18n.ts.hashtags" class="_button" :class="{ active: withHashtags }" @click="withHashtags = !withHashtags"><i class="fas fa-hashtag"></i></button>
-			<button v-tooltip="i18n.ts.emoji" class="_button" @click="insertEmoji"><i class="fas fa-laugh-squint"></i></button>
-			<button v-if="postFormActions.length > 0" v-tooltip="i18n.ts.plugin" class="_button" @click="showActions"><i class="fas fa-plug"></i></button>
+			<button v-tooltip="i18n.ts.attachFile" class="_button" @click="chooseFileFrom"><i class="ti ti-photo-plus"></i></button>
+			<button v-tooltip="i18n.ts.poll" class="_button" :class="{ active: poll }" @click="togglePoll"><i class="ti ti-chart-arrows"></i></button>
+			<button v-tooltip="i18n.ts.useCw" class="_button" :class="{ active: useCw }" @click="useCw = !useCw"><i class="ti ti-eye-off"></i></button>
+			<button v-tooltip="i18n.ts.mention" class="_button" @click="insertMention"><i class="ti ti-at"></i></button>
+			<button v-tooltip="i18n.ts.hashtags" class="_button" :class="{ active: withHashtags }" @click="withHashtags = !withHashtags"><i class="ti ti-hash"></i></button>
+			<button v-tooltip="i18n.ts.emoji" class="_button" @click="insertEmoji"><i class="ti ti-mood-happy"></i></button>
+			<button v-if="postFormActions.length > 0" v-tooltip="i18n.ts.plugin" class="_button" @click="showActions"><i class="ti ti-plug"></i></button>
 		</footer>
 		<datalist id="hashtags">
 			<option v-for="hashtag in recentHashtags" :key="hashtag" :value="hashtag"/>
@@ -734,7 +734,7 @@ onMounted(() => {
 
 		> .cancel {
 			padding: 0;
-			font-size: 20px;
+			font-size: 1em;
 			width: 64px;
 			line-height: 66px;
 		}
@@ -925,9 +925,9 @@ onMounted(() => {
 				display: inline-block;
 				padding: 0;
 				margin: 0;
-				font-size: 16px;
-				width: 48px;
-				height: 48px;
+				font-size: 1em;
+				width: 46px;
+				height: 46px;
 				border-radius: 6px;
 
 				&:hover {
diff --git a/packages/client/src/components/MkPostFormAttaches.vue b/packages/client/src/components/MkPostFormAttaches.vue
index a8ec8c33ba..b533786d36 100644
--- a/packages/client/src/components/MkPostFormAttaches.vue
+++ b/packages/client/src/components/MkPostFormAttaches.vue
@@ -5,7 +5,7 @@
 			<div class="file" @click="showFileMenu(element, $event)" @contextmenu.prevent="showFileMenu(element, $event)">
 				<MkDriveFileThumbnail :data-id="element.id" class="thumbnail" :file="element" fit="cover"/>
 				<div v-if="element.isSensitive" class="sensitive">
-					<i class="fas fa-exclamation-triangle icon"></i>
+					<i class="ti ti-alert-triangle icon"></i>
 				</div>
 			</div>
 		</template>
@@ -113,19 +113,19 @@ export default defineComponent({
 			if (this.menu) return;
 			this.menu = os.popupMenu([{
 				text: this.$ts.renameFile,
-				icon: 'fas fa-i-cursor',
+				icon: 'ti ti-cursor-text',
 				action: () => { this.rename(file); },
 			}, {
 				text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive,
-				icon: file.isSensitive ? 'fas fa-eye-slash' : 'fas fa-eye',
+				icon: file.isSensitive ? 'ti ti-eye-off' : 'ti ti-eye',
 				action: () => { this.toggleSensitive(file); },
 			}, {
 				text: this.$ts.describeFile,
-				icon: 'fas fa-i-cursor',
+				icon: 'ti ti-cursor-text',
 				action: () => { this.describe(file); },
 			}, {
 				text: this.$ts.attachCancel,
-				icon: 'fas fa-times-circle',
+				icon: 'ti ti-circle-x',
 				action: () => { this.detachMedia(file.id); },
 			}], ev.currentTarget ?? ev.target).then(() => this.menu = null);
 		},
diff --git a/packages/client/src/components/MkRemoteCaution.vue b/packages/client/src/components/MkRemoteCaution.vue
index e9461197ca..d5dc01c1f8 100644
--- a/packages/client/src/components/MkRemoteCaution.vue
+++ b/packages/client/src/components/MkRemoteCaution.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="jmgmzlwq _block"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i>{{ i18n.ts.remoteUserCaution }}<a class="link" :href="href" rel="nofollow noopener" target="_blank">{{ i18n.ts.showOnRemote }}</a></div>
+<div class="jmgmzlwq _block"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i>{{ i18n.ts.remoteUserCaution }}<a class="link" :href="href" rel="nofollow noopener" target="_blank">{{ i18n.ts.showOnRemote }}</a></div>
 </template>
 
 <script lang="ts" setup>
diff --git a/packages/client/src/components/MkRenoteButton.vue b/packages/client/src/components/MkRenoteButton.vue
index 413f3406a4..e0b1eaafc9 100644
--- a/packages/client/src/components/MkRenoteButton.vue
+++ b/packages/client/src/components/MkRenoteButton.vue
@@ -5,11 +5,11 @@
 	class="eddddedb _button canRenote"
 	@click="renote()"
 >
-	<i class="fas fa-retweet"></i>
+	<i class="ti ti-repeat"></i>
 	<p v-if="count > 0" class="count">{{ count }}</p>
 </button>
 <button v-else class="eddddedb _button">
-	<i class="fas fa-ban"></i>
+	<i class="ti ti-ban"></i>
 </button>
 </template>
 
@@ -54,7 +54,7 @@ const renote = (viaKeyboard = false) => {
 	pleaseLogin();
 	os.popupMenu([{
 		text: i18n.ts.renote,
-		icon: 'fas fa-retweet',
+		icon: 'ti ti-repeat',
 		action: () => {
 			os.api('notes/create', {
 				renoteId: props.note.id,
@@ -62,7 +62,7 @@ const renote = (viaKeyboard = false) => {
 		},
 	}, {
 		text: i18n.ts.quote,
-		icon: 'fas fa-quote-right',
+		icon: 'ti ti-quote',
 		action: () => {
 			os.post({
 				renote: props.note,
diff --git a/packages/client/src/components/MkSignin.vue b/packages/client/src/components/MkSignin.vue
index 5613e5cf02..b51bcb2dc3 100644
--- a/packages/client/src/components/MkSignin.vue
+++ b/packages/client/src/components/MkSignin.vue
@@ -11,7 +11,7 @@
 				<template #suffix>@{{ host }}</template>
 			</MkInput>
 			<MkInput v-if="!user || user && !user.usePasswordLessLogin" v-model="password" class="_formBlock" :placeholder="i18n.ts.password" type="password" :with-password-toggle="true" required data-cy-signin-password>
-				<template #prefix><i class="fas fa-lock"></i></template>
+				<template #prefix><i class="ti ti-lock"></i></template>
 				<template #caption><button class="_textButton" type="button" @click="resetPassword">{{ i18n.ts.forgotPassword }}</button></template>
 			</MkInput>
 			<MkButton class="_formBlock" type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? i18n.ts.loggingIn : i18n.ts.login }}</MkButton>
@@ -30,7 +30,7 @@
 				<p style="margin-bottom:0;">{{ i18n.ts.twoStepAuthentication }}</p>
 				<MkInput v-if="user && user.usePasswordLessLogin" v-model="password" type="password" :with-password-toggle="true" required>
 					<template #label>{{ i18n.ts.password }}</template>
-					<template #prefix><i class="fas fa-lock"></i></template>
+					<template #prefix><i class="ti ti-lock"></i></template>
 				</MkInput>
 				<MkInput v-model="token" type="text" pattern="^[0-9]{6}$" autocomplete="off" :spellcheck="false" required>
 					<template #label>{{ i18n.ts.token }}</template>
diff --git a/packages/client/src/components/MkSignup.vue b/packages/client/src/components/MkSignup.vue
index c1f91b18c2..e6281b1f84 100644
--- a/packages/client/src/components/MkSignup.vue
+++ b/packages/client/src/components/MkSignup.vue
@@ -2,52 +2,52 @@
 <form class="qlvuhzng _formRoot" autocomplete="new-password" @submit.prevent="onSubmit">
 	<MkInput v-if="instance.disableRegistration" v-model="invitationCode" class="_formBlock" type="text" :spellcheck="false" required>
 		<template #label>{{ i18n.ts.invitationCode }}</template>
-		<template #prefix><i class="fas fa-key"></i></template>
+		<template #prefix><i class="ti ti-key"></i></template>
 	</MkInput>
 	<MkInput v-model="username" class="_formBlock" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false" required data-cy-signup-username @update:modelValue="onChangeUsername">
 		<template #label>{{ i18n.ts.username }} <div v-tooltip:dialog="i18n.ts.usernameInfo" class="_button _help"><i class="far fa-question-circle"></i></div></template>
 		<template #prefix>@</template>
 		<template #suffix>@{{ host }}</template>
 		<template #caption>
-			<span v-if="usernameState === 'wait'" style="color:#999"><i class="fas fa-spinner fa-pulse fa-fw"></i> {{ i18n.ts.checking }}</span>
-			<span v-else-if="usernameState === 'ok'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ i18n.ts.available }}</span>
-			<span v-else-if="usernameState === 'unavailable'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.unavailable }}</span>
-			<span v-else-if="usernameState === 'error'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.error }}</span>
-			<span v-else-if="usernameState === 'invalid-format'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.usernameInvalidFormat }}</span>
-			<span v-else-if="usernameState === 'min-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.tooShort }}</span>
-			<span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.tooLong }}</span>
+			<span v-if="usernameState === 'wait'" style="color:#999"><i class="fas fa-spinner fa-pulse ti-fw"></i> {{ i18n.ts.checking }}</span>
+			<span v-else-if="usernameState === 'ok'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
+			<span v-else-if="usernameState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
+			<span v-else-if="usernameState === 'error'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
+			<span v-else-if="usernameState === 'invalid-format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.usernameInvalidFormat }}</span>
+			<span v-else-if="usernameState === 'min-range'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooShort }}</span>
+			<span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooLong }}</span>
 		</template>
 	</MkInput>
 	<MkInput v-if="instance.emailRequiredForSignup" v-model="email" class="_formBlock" :debounce="true" type="email" :spellcheck="false" required data-cy-signup-email @update:modelValue="onChangeEmail">
 		<template #label>{{ i18n.ts.emailAddress }} <div v-tooltip:dialog="i18n.ts._signup.emailAddressInfo" class="_button _help"><i class="far fa-question-circle"></i></div></template>
-		<template #prefix><i class="fas fa-envelope"></i></template>
+		<template #prefix><i class="ti ti-mail"></i></template>
 		<template #caption>
-			<span v-if="emailState === 'wait'" style="color:#999"><i class="fas fa-spinner fa-pulse fa-fw"></i> {{ i18n.ts.checking }}</span>
-			<span v-else-if="emailState === 'ok'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ i18n.ts.available }}</span>
-			<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
-			<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
-			<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
-			<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
-			<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
-			<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.unavailable }}</span>
-			<span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.error }}</span>
+			<span v-if="emailState === 'wait'" style="color:#999"><i class="fas fa-spinner fa-pulse ti-fw"></i> {{ i18n.ts.checking }}</span>
+			<span v-else-if="emailState === 'ok'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
+			<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
+			<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
+			<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
+			<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
+			<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
+			<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
+			<span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
 		</template>
 	</MkInput>
 	<MkInput v-model="password" class="_formBlock" type="password" autocomplete="new-password" required data-cy-signup-password @update:modelValue="onChangePassword">
 		<template #label>{{ i18n.ts.password }}</template>
-		<template #prefix><i class="fas fa-lock"></i></template>
+		<template #prefix><i class="ti ti-lock"></i></template>
 		<template #caption>
-			<span v-if="passwordStrength == 'low'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.weakPassword }}</span>
-			<span v-if="passwordStrength == 'medium'" style="color: var(--warn)"><i class="fas fa-check fa-fw"></i> {{ i18n.ts.normalPassword }}</span>
-			<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ i18n.ts.strongPassword }}</span>
+			<span v-if="passwordStrength == 'low'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.weakPassword }}</span>
+			<span v-if="passwordStrength == 'medium'" style="color: var(--warn)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.normalPassword }}</span>
+			<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.strongPassword }}</span>
 		</template>
 	</MkInput>
 	<MkInput v-model="retypedPassword" class="_formBlock" type="password" autocomplete="new-password" required data-cy-signup-password-retype @update:modelValue="onChangePasswordRetype">
 		<template #label>{{ i18n.ts.password }} ({{ i18n.ts.retype }})</template>
-		<template #prefix><i class="fas fa-lock"></i></template>
+		<template #prefix><i class="ti ti-lock"></i></template>
 		<template #caption>
-			<span v-if="passwordRetypeState == 'match'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ i18n.ts.passwordMatched }}</span>
-			<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ i18n.ts.passwordNotMatched }}</span>
+			<span v-if="passwordRetypeState == 'match'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.passwordMatched }}</span>
+			<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.passwordNotMatched }}</span>
 		</template>
 	</MkInput>
 	<MkSwitch v-if="instance.tosUrl" v-model="ToSAgreement" class="_formBlock tou">
diff --git a/packages/client/src/components/MkSubNoteContent.vue b/packages/client/src/components/MkSubNoteContent.vue
index 237f4cf228..210923be46 100644
--- a/packages/client/src/components/MkSubNoteContent.vue
+++ b/packages/client/src/components/MkSubNoteContent.vue
@@ -3,7 +3,7 @@
 	<div class="body">
 		<span v-if="note.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
 		<span v-if="note.deletedAt" style="opacity: 0.5">({{ i18n.ts.deleted }})</span>
-		<MkA v-if="note.replyId" class="reply" :to="`/notes/${note.replyId}`"><i class="fas fa-reply"></i></MkA>
+		<MkA v-if="note.replyId" class="reply" :to="`/notes/${note.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
 		<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" :custom-emojis="note.emojis"/>
 		<MkA v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
 	</div>
diff --git a/packages/client/src/components/MkSuperMenu.vue b/packages/client/src/components/MkSuperMenu.vue
index fa8921bdde..3179188518 100644
--- a/packages/client/src/components/MkSuperMenu.vue
+++ b/packages/client/src/components/MkSuperMenu.vue
@@ -6,15 +6,15 @@
 		<div class="items">
 			<template v-for="(item, i) in group.items">
 				<a v-if="item.type === 'a'" :href="item.href" :target="item.target" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active }">
-					<i v-if="item.icon" class="icon fa-fw" :class="item.icon"></i>
+					<i v-if="item.icon" class="icon ti-fw" :class="item.icon"></i>
 					<span class="text">{{ item.text }}</span>
 				</a>
 				<button v-else-if="item.type === 'button'" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active }" :disabled="item.active" @click="ev => item.action(ev)">
-					<i v-if="item.icon" class="icon fa-fw" :class="item.icon"></i>
+					<i v-if="item.icon" class="icon ti-fw" :class="item.icon"></i>
 					<span class="text">{{ item.text }}</span>
 				</button>
 				<MkA v-else :to="item.to" :tabindex="i" class="_button item" :class="{ danger: item.danger, active: item.active }">
-					<i v-if="item.icon" class="icon fa-fw" :class="item.icon"></i>
+					<i v-if="item.icon" class="icon ti-fw" :class="item.icon"></i>
 					<span class="text">{{ item.text }}</span>
 				</MkA>
 			</template>
diff --git a/packages/client/src/components/MkUrlPreview.vue b/packages/client/src/components/MkUrlPreview.vue
index 8fd1ce133d..5814faef19 100644
--- a/packages/client/src/components/MkUrlPreview.vue
+++ b/packages/client/src/components/MkUrlPreview.vue
@@ -1,6 +1,6 @@
 <template>
 <div v-if="playerEnabled" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
-	<button class="disablePlayer" :title="i18n.ts.disablePlayer" @click="playerEnabled = false"><i class="fas fa-times"></i></button>
+	<button class="disablePlayer" :title="i18n.ts.disablePlayer" @click="playerEnabled = false"><i class="ti ti-x"></i></button>
 	<iframe :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen/>
 </div>
 <div v-else-if="tweetId && tweetExpanded" ref="twitter" class="twitter">
diff --git a/packages/client/src/components/MkVisibility.vue b/packages/client/src/components/MkVisibility.vue
index ca1f9a6cd8..229907fbb8 100644
--- a/packages/client/src/components/MkVisibility.vue
+++ b/packages/client/src/components/MkVisibility.vue
@@ -1,10 +1,10 @@
 <template>
 <span v-if="note.visibility !== 'public'" :class="$style.visibility" :title="i18n.ts._visibility[note.visibility]">
-	<i v-if="note.visibility === 'home'" class="fas fa-home"></i>
-	<i v-else-if="note.visibility === 'followers'" class="fas fa-unlock"></i>
-	<i v-else-if="note.visibility === 'specified'" ref="specified" class="fas fa-envelope"></i>
+	<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
+	<i v-else-if="note.visibility === 'followers'" class="ti ti-lock-open"></i>
+	<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
 </span>
-<span v-if="note.localOnly" :class="$style.localOnly" :title="i18n.ts._visibility['localOnly']"><i class="fas fa-biohazard"></i></span>
+<span v-if="note.localOnly" :class="$style.localOnly" :title="i18n.ts._visibility['localOnly']"><i class="ti ti-world-off"></i></span>
 </template>
 
 <script lang="ts" setup>
diff --git a/packages/client/src/components/MkVisibilityPicker.vue b/packages/client/src/components/MkVisibilityPicker.vue
index ecc022eca0..8f0bcdeae8 100644
--- a/packages/client/src/components/MkVisibilityPicker.vue
+++ b/packages/client/src/components/MkVisibilityPicker.vue
@@ -2,28 +2,28 @@
 <MkModal ref="modal" :z-priority="'high'" :src="src" @click="modal.close()" @closed="emit('closed')">
 	<div class="gqyayizv _popup">
 		<button key="public" class="_button" :class="{ active: v === 'public' }" data-index="1" @click="choose('public')">
-			<div><i class="fas fa-globe"></i></div>
+			<div><i class="ti ti-world"></i></div>
 			<div>
 				<span>{{ i18n.ts._visibility.public }}</span>
 				<span>{{ i18n.ts._visibility.publicDescription }}</span>
 			</div>
 		</button>
 		<button key="home" class="_button" :class="{ active: v === 'home' }" data-index="2" @click="choose('home')">
-			<div><i class="fas fa-home"></i></div>
+			<div><i class="ti ti-home"></i></div>
 			<div>
 				<span>{{ i18n.ts._visibility.home }}</span>
 				<span>{{ i18n.ts._visibility.homeDescription }}</span>
 			</div>
 		</button>
 		<button key="followers" class="_button" :class="{ active: v === 'followers' }" data-index="3" @click="choose('followers')">
-			<div><i class="fas fa-unlock"></i></div>
+			<div><i class="ti ti-lock-open"></i></div>
 			<div>
 				<span>{{ i18n.ts._visibility.followers }}</span>
 				<span>{{ i18n.ts._visibility.followersDescription }}</span>
 			</div>
 		</button>
 		<button key="specified" :disabled="localOnly" class="_button" :class="{ active: v === 'specified' }" data-index="4" @click="choose('specified')">
-			<div><i class="fas fa-envelope"></i></div>
+			<div><i class="ti ti-mail"></i></div>
 			<div>
 				<span>{{ i18n.ts._visibility.specified }}</span>
 				<span>{{ i18n.ts._visibility.specifiedDescription }}</span>
@@ -31,12 +31,12 @@
 		</button>
 		<div class="divider"></div>
 		<button key="localOnly" class="_button localOnly" :class="{ active: localOnly }" data-index="5" @click="localOnly = !localOnly">
-			<div><i class="fas fa-biohazard"></i></div>
+			<div><i class="ti ti-world-off"></i></div>
 			<div>
 				<span>{{ i18n.ts._visibility.localOnly }}</span>
 				<span>{{ i18n.ts._visibility.localOnlyDescription }}</span>
 			</div>
-			<div><i :class="localOnly ? 'fas fa-toggle-on' : 'fas fa-toggle-off'"></i></div>
+			<div><i :class="localOnly ? 'ti ti-toggle-right' : 'ti ti-toggle-left'"></i></div>
 		</button>
 	</div>
 </MkModal>
diff --git a/packages/client/src/components/MkWaitingDialog.vue b/packages/client/src/components/MkWaitingDialog.vue
index 77b664d3b1..ee86aec967 100644
--- a/packages/client/src/components/MkWaitingDialog.vue
+++ b/packages/client/src/components/MkWaitingDialog.vue
@@ -1,7 +1,7 @@
 <template>
 <MkModal ref="modal" :prefer-type="'dialog'" :z-priority="'high'" @click="success ? done() : () => {}" @closed="emit('closed')">
 	<div class="iuyakobc" :class="{ iconOnly: (text == null) || success }">
-		<i v-if="success" class="fas fa-check icon success"></i>
+		<i v-if="success" class="ti ti-check icon success"></i>
 		<i v-else class="fas fa-spinner fa-pulse icon waiting"></i>
 		<div v-if="text && !success" class="text">{{ text }}<MkEllipsis/></div>
 	</div>
diff --git a/packages/client/src/components/MkWidgets.vue b/packages/client/src/components/MkWidgets.vue
index fcb0d11af4..dd2a2aa89a 100644
--- a/packages/client/src/components/MkWidgets.vue
+++ b/packages/client/src/components/MkWidgets.vue
@@ -6,7 +6,7 @@
 				<template #label>{{ i18n.ts.selectWidget }}</template>
 				<option v-for="widget in widgetDefs" :key="widget" :value="widget">{{ i18n.t(`_widgets.${widget}`) }}</option>
 			</MkSelect>
-			<MkButton inline primary class="mk-widget-add" @click="addWidget"><i class="fas fa-plus"></i> {{ i18n.ts.add }}</MkButton>
+			<MkButton inline primary class="mk-widget-add" @click="addWidget"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
 			<MkButton inline @click="$emit('exit')">{{ i18n.ts.close }}</MkButton>
 		</header>
 		<XDraggable
@@ -17,8 +17,8 @@
 		>
 			<template #item="{element}">
 				<div class="customize-container">
-					<button class="config _button" @click.prevent.stop="configWidget(element.id)"><i class="fas fa-cog"></i></button>
-					<button class="remove _button" @click.prevent.stop="removeWidget(element)"><i class="fas fa-times"></i></button>
+					<button class="config _button" @click.prevent.stop="configWidget(element.id)"><i class="ti ti-settings"></i></button>
+					<button class="remove _button" @click.prevent.stop="removeWidget(element)"><i class="ti ti-x"></i></button>
 					<div class="handle">
 						<component :is="`mkw-${element.name}`" :ref="el => widgetRefs[element.id] = el" class="widget" :widget="element" @updateProps="updateWidget(element.id, $event)"/>
 					</div>
@@ -104,7 +104,7 @@ function onContextmenu(widget: Widget, ev: MouseEvent) {
 		type: 'label',
 		text: i18n.t(`_widgets.${widget.name}`),
 	}, {
-		icon: 'fas fa-cog',
+		icon: 'ti ti-settings',
 		text: i18n.ts.settings,
 		action: () => {
 			configWidget(widget.id);
diff --git a/packages/client/src/components/MkWindow.vue b/packages/client/src/components/MkWindow.vue
index 0ab4382632..fb786ecf65 100644
--- a/packages/client/src/components/MkWindow.vue
+++ b/packages/client/src/components/MkWindow.vue
@@ -13,7 +13,7 @@
 					<button v-for="button in buttonsRight" v-tooltip="button.title" class="button _button" :class="{ highlighted: button.highlighted }" @click="button.onClick"><i :class="button.icon"></i></button>
 					<button v-if="canResize && maximized" class="button _button" @click="unMaximize()"><i class="fas fa-window-restore"></i></button>
 					<button v-else-if="canResize && !maximized" class="button _button" @click="maximize()"><i class="fas fa-window-maximize"></i></button>
-					<button v-if="closeButton" class="button _button" @click="close()"><i class="fas fa-times"></i></button>
+					<button v-if="closeButton" class="button _button" @click="close()"><i class="ti ti-x"></i></button>
 				</span>
 			</div>
 			<div class="body">
diff --git a/packages/client/src/components/form/checkbox.vue b/packages/client/src/components/form/checkbox.vue
index bd56c9c7ea..ba3b2dc146 100644
--- a/packages/client/src/components/form/checkbox.vue
+++ b/packages/client/src/components/form/checkbox.vue
@@ -10,7 +10,7 @@
 		@keydown.enter="toggle"
 	>
 	<span ref="button" v-adaptive-border v-tooltip="checked ? i18n.ts.itsOn : i18n.ts.itsOff" class="button" @click.prevent="toggle">
-		<i class="check fas fa-check"></i>
+		<i class="check ti ti-check"></i>
 	</span>
 	<span class="label">
 		<!-- TODO: 無名slotの方は廃止 -->
diff --git a/packages/client/src/components/form/folder.vue b/packages/client/src/components/form/folder.vue
index a9d8bd97b8..1256dfcbb4 100644
--- a/packages/client/src/components/form/folder.vue
+++ b/packages/client/src/components/form/folder.vue
@@ -5,8 +5,8 @@
 		<span class="text"><slot name="label"></slot></span>
 		<span class="right">
 			<span class="text"><slot name="suffix"></slot></span>
-			<i v-if="opened" class="fas fa-angle-up icon"></i>
-			<i v-else class="fas fa-angle-down icon"></i>
+			<i v-if="opened" class="ti ti-chevron-up icon"></i>
+			<i v-else class="ti ti-chevron-down icon"></i>
 		</span>
 	</div>
 	<KeepAlive>
@@ -23,7 +23,7 @@
 const props = withDefaults(defineProps<{
 	defaultOpen: boolean;
 }>(), {
-  defaultOpen: false,
+	defaultOpen: false,
 });
 
 let opened = $ref(props.defaultOpen);
@@ -46,7 +46,7 @@ const toggle = () => {
 		align-items: center;
 		width: 100%;
 		box-sizing: border-box;
-		padding: 12px 14px 12px 14px;
+		padding: 10px 14px 10px 14px;
 		background: var(--buttonBg);
 		border-radius: 6px;
 
diff --git a/packages/client/src/components/form/input.vue b/packages/client/src/components/form/input.vue
index 382b2ed528..939e9691a6 100644
--- a/packages/client/src/components/form/input.vue
+++ b/packages/client/src/components/form/input.vue
@@ -29,7 +29,7 @@
 	</div>
 	<div class="caption"><slot name="caption"></slot></div>
 
-	<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="fas fa-check"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
diff --git a/packages/client/src/components/form/link.vue b/packages/client/src/components/form/link.vue
index 899394cb62..a1775c0bdb 100644
--- a/packages/client/src/components/form/link.vue
+++ b/packages/client/src/components/form/link.vue
@@ -5,7 +5,7 @@
 		<span class="text"><slot></slot></span>
 		<span class="right">
 			<span class="text"><slot name="suffix"></slot></span>
-			<i class="fas fa-external-link-alt icon"></i>
+			<i class="ti ti-external-link icon"></i>
 		</span>
 	</a>
 	<MkA v-else class="main _button" :class="{ active }" :to="to" :behavior="behavior">
@@ -13,7 +13,7 @@
 		<span class="text"><slot></slot></span>
 		<span class="right">
 			<span class="text"><slot name="suffix"></slot></span>
-			<i class="fas fa-chevron-right icon"></i>
+			<i class="ti ti-chevron-right icon"></i>
 		</span>
 	</MkA>
 </div>
diff --git a/packages/client/src/components/form/radio.vue b/packages/client/src/components/form/radio.vue
index b36f7e9fdc..fcf454c77a 100644
--- a/packages/client/src/components/form/radio.vue
+++ b/packages/client/src/components/form/radio.vue
@@ -45,12 +45,13 @@ function toggle(): void {
 	display: inline-block;
 	text-align: left;
 	cursor: pointer;
-	padding: 8px 10px;
+	padding: 7px 10px;
 	min-width: 60px;
 	background-color: var(--panel);
 	background-clip: padding-box !important;
 	border: solid 1px var(--panel);
 	border-radius: 6px;
+	font-size: 90%;
 	transition: all 0.2s;
 
 	> * {
diff --git a/packages/client/src/components/form/select.vue b/packages/client/src/components/form/select.vue
index 313ba41cd3..eaf4b131cd 100644
--- a/packages/client/src/components/form/select.vue
+++ b/packages/client/src/components/form/select.vue
@@ -18,11 +18,11 @@
 		>
 			<slot></slot>
 		</select>
-		<div ref="suffixEl" class="suffix"><i class="fas fa-chevron-down"></i></div>
+		<div ref="suffixEl" class="suffix"><i class="ti ti-chevron-down"></i></div>
 	</div>
 	<div class="caption"><slot name="caption"></slot></div>
 
-	<MkButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton v-if="manualSave && changed" primary @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
diff --git a/packages/client/src/components/form/suspense.vue b/packages/client/src/components/form/suspense.vue
index 132eafd138..58d80264c1 100644
--- a/packages/client/src/components/form/suspense.vue
+++ b/packages/client/src/components/form/suspense.vue
@@ -8,7 +8,7 @@
 	</div>
 	<div v-else>
 		<div class="wszdbhzo">
-			<div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div>
+			<div><i class="ti ti-alert-triangle"></i> {{ $ts.somethingHappened }}</div>
 			<MkButton inline class="retry" @click="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton>
 		</div>
 	</div>
diff --git a/packages/client/src/components/form/textarea.vue b/packages/client/src/components/form/textarea.vue
index ca57aa62a5..d34d7b1775 100644
--- a/packages/client/src/components/form/textarea.vue
+++ b/packages/client/src/components/form/textarea.vue
@@ -22,7 +22,7 @@
 	</div>
 	<div class="caption"><slot name="caption"></slot></div>
 
-	<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton v-if="manualSave && changed" primary class="save" @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
diff --git a/packages/client/src/components/global/MkA.vue b/packages/client/src/components/global/MkA.vue
index 67bf54def8..dbdf89a0ba 100644
--- a/packages/client/src/components/global/MkA.vue
+++ b/packages/client/src/components/global/MkA.vue
@@ -41,25 +41,25 @@ function onContextmenu(ev) {
 		type: 'label',
 		text: props.to,
 	}, {
-		icon: 'fas fa-window-maximize',
+		icon: 'ti ti-window-maximize',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(props.to);
 		},
 	}, {
-		icon: 'fas fa-expand-alt',
+		icon: 'ti ti-arrows-maximize',
 		text: i18n.ts.showInPage,
 		action: () => {
 			router.push(props.to, 'forcePage');
 		},
 	}, null, {
-		icon: 'fas fa-external-link-alt',
+		icon: 'ti ti-external-link',
 		text: i18n.ts.openInNewTab,
 		action: () => {
 			window.open(props.to, '_blank');
 		},
 	}, {
-		icon: 'fas fa-link',
+		icon: 'ti ti-link',
 		text: i18n.ts.copyLink,
 		action: () => {
 			copyToClipboard(`${url}${props.to}`);
diff --git a/packages/client/src/components/global/MkAd.vue b/packages/client/src/components/global/MkAd.vue
index 8161ef3792..a80efb142c 100644
--- a/packages/client/src/components/global/MkAd.vue
+++ b/packages/client/src/components/global/MkAd.vue
@@ -3,7 +3,7 @@
 	<div v-if="!showMenu" class="main" :class="chosen.place">
 		<a :href="chosen.url" target="_blank">
 			<img :src="chosen.imageUrl">
-			<button class="_button menu" @click.prevent.stop="toggleMenu"><span class="fas fa-info-circle info-circle"></span></button>
+			<button class="_button menu" @click.prevent.stop="toggleMenu"><span class="ti ti-info-circle info-circle"></span></button>
 		</a>
 	</div>
 	<div v-else class="menu">
diff --git a/packages/client/src/components/global/MkError.vue b/packages/client/src/components/global/MkError.vue
index 6e75a69ec3..e135d4184b 100644
--- a/packages/client/src/components/global/MkError.vue
+++ b/packages/client/src/components/global/MkError.vue
@@ -2,7 +2,7 @@
 <transition :name="$store.state.animation ? 'zoom' : ''" appear>
 	<div class="mjndxjcg">
 		<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
-		<p><i class="fas fa-exclamation-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
+		<p><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
 		<MkButton class="button" @click="() => $emit('retry')">{{ i18n.ts.retry }}</MkButton>
 	</div>
 </transition>
diff --git a/packages/client/src/components/global/MkPageHeader.vue b/packages/client/src/components/global/MkPageHeader.vue
index ba75b2446b..cce3f727fc 100644
--- a/packages/client/src/components/global/MkPageHeader.vue
+++ b/packages/client/src/components/global/MkPageHeader.vue
@@ -16,7 +16,7 @@
 				</div>
 				<div v-if="narrow && hasTabs" class="subtitle activeTab">
 					{{ tabs.find(tab => tab.key === props.tab)?.title }}
-					<i class="chevron fas fa-chevron-down"></i>
+					<i class="chevron ti ti-chevron-down"></i>
 				</div>
 			</div>
 		</div>
diff --git a/packages/client/src/components/global/MkUrl.vue b/packages/client/src/components/global/MkUrl.vue
index 740ce29080..9f5be96224 100644
--- a/packages/client/src/components/global/MkUrl.vue
+++ b/packages/client/src/components/global/MkUrl.vue
@@ -14,7 +14,7 @@
 	<span v-if="pathname != ''" class="pathname">{{ self ? pathname.substring(1) : pathname }}</span>
 	<span class="query">{{ query }}</span>
 	<span class="hash">{{ hash }}</span>
-	<i v-if="target === '_blank'" class="fas fa-external-link-square-alt icon"></i>
+	<i v-if="target === '_blank'" class="ti ti-external-link icon"></i>
 </component>
 </template>
 
diff --git a/packages/client/src/components/page/page.post.vue b/packages/client/src/components/page/page.post.vue
index 954c7675bd..0ef50d65cd 100644
--- a/packages/client/src/components/page/page.post.vue
+++ b/packages/client/src/components/page/page.post.vue
@@ -2,8 +2,8 @@
 <div class="ngbfujlo">
 	<MkTextarea :model-value="text" readonly style="margin: 0;"></MkTextarea>
 	<MkButton class="button" primary :disabled="posting || posted" @click="post()">
-		<i v-if="posted" class="fas fa-check"></i>
-		<i v-else class="fas fa-paper-plane"></i>
+		<i v-if="posted" class="ti ti-check"></i>
+		<i v-else class="ti ti-send"></i>
 	</MkButton>
 </div>
 </template>
diff --git a/packages/client/src/navbar.ts b/packages/client/src/navbar.ts
index 03e00b1c17..18b1cddc79 100644
--- a/packages/client/src/navbar.ts
+++ b/packages/client/src/navbar.ts
@@ -9,70 +9,70 @@ import { unisonReload } from '@/scripts/unison-reload';
 export const navbarItemDef = reactive({
 	notifications: {
 		title: 'notifications',
-		icon: 'fas fa-bell',
+		icon: 'ti ti-bell',
 		show: computed(() => $i != null),
 		indicated: computed(() => $i != null && $i.hasUnreadNotification),
 		to: '/my/notifications',
 	},
 	messaging: {
 		title: 'messaging',
-		icon: 'fas fa-comments',
+		icon: 'ti ti-messages',
 		show: computed(() => $i != null),
 		indicated: computed(() => $i != null && $i.hasUnreadMessagingMessage),
 		to: '/my/messaging',
 	},
 	drive: {
 		title: 'drive',
-		icon: 'fas fa-cloud',
+		icon: 'ti ti-cloud',
 		show: computed(() => $i != null),
 		to: '/my/drive',
 	},
 	followRequests: {
 		title: 'followRequests',
-		icon: 'fas fa-user-clock',
+		icon: 'ti ti-user-clock',
 		show: computed(() => $i != null && $i.isLocked),
 		indicated: computed(() => $i != null && $i.hasPendingReceivedFollowRequest),
 		to: '/my/follow-requests',
 	},
 	explore: {
 		title: 'explore',
-		icon: 'fas fa-hashtag',
+		icon: 'ti ti-hash',
 		to: '/explore',
 	},
 	announcements: {
 		title: 'announcements',
-		icon: 'fas fa-broadcast-tower',
+		icon: 'ti ti-speakerphone',
 		indicated: computed(() => $i != null && $i.hasUnreadAnnouncement),
 		to: '/announcements',
 	},
 	search: {
 		title: 'search',
-		icon: 'fas fa-search',
+		icon: 'ti ti-search',
 		action: () => search(),
 	},
 	lists: {
 		title: 'lists',
-		icon: 'fas fa-list-ul',
+		icon: 'ti ti-list',
 		show: computed(() => $i != null),
 		to: '/my/lists',
 	},
 	/*
 	groups: {
 		title: 'groups',
-		icon: 'fas fa-users',
+		icon: 'ti ti-users',
 		show: computed(() => $i != null),
 		to: '/my/groups',
 	},
 	*/
 	antennas: {
 		title: 'antennas',
-		icon: 'fas fa-satellite',
+		icon: 'ti ti-antenna',
 		show: computed(() => $i != null),
 		to: '/my/antennas',
 	},
 	favorites: {
 		title: 'favorites',
-		icon: 'fas fa-star',
+		icon: 'ti ti-star',
 		show: computed(() => $i != null),
 		to: '/my/favorites',
 	},
@@ -83,23 +83,23 @@ export const navbarItemDef = reactive({
 	},
 	gallery: {
 		title: 'gallery',
-		icon: 'fas fa-icons',
+		icon: 'ti ti-icons',
 		to: '/gallery',
 	},
 	clips: {
 		title: 'clip',
-		icon: 'fas fa-paperclip',
+		icon: 'ti ti-paperclip',
 		show: computed(() => $i != null),
 		to: '/my/clips',
 	},
 	channels: {
 		title: 'channel',
-		icon: 'fas fa-satellite-dish',
+		icon: 'ti ti-device-tv',
 		to: '/channels',
 	},
 	ui: {
 		title: 'switchUi',
-		icon: 'fas fa-columns',
+		icon: 'ti ti-columns',
 		action: (ev) => {
 			os.popupMenu([{
 				text: i18n.ts.default,
@@ -127,7 +127,7 @@ export const navbarItemDef = reactive({
 	},
 	reload: {
 		title: 'reload',
-		icon: 'fas fa-refresh',
+		icon: 'ti ti-refresh',
 		action: (ev) => {
 			location.reload();
 		},
diff --git a/packages/client/src/pages/_error_.vue b/packages/client/src/pages/_error_.vue
index a90a023cb6..232d525347 100644
--- a/packages/client/src/pages/_error_.vue
+++ b/packages/client/src/pages/_error_.vue
@@ -3,7 +3,7 @@
 <transition :name="$store.state.animation ? 'zoom' : ''" appear>
 	<div v-show="loaded" class="mjndxjch">
 		<img src="https://xn--931a.moe/assets/error.jpg" class="_ghost"/>
-		<p><b><i class="fas fa-exclamation-triangle"></i> {{ i18n.ts.pageLoadError }}</b></p>
+		<p><b><i class="ti ti-alert-triangle"></i> {{ i18n.ts.pageLoadError }}</b></p>
 		<p v-if="meta && (version === meta.version)">{{ i18n.ts.pageLoadErrorDescription }}</p>
 		<p v-else-if="serverIsDead">{{ i18n.ts.serverIsDead }}</p>
 		<template v-else>
@@ -58,7 +58,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.error,
-	icon: 'fas fa-exclamation-triangle',
+	icon: 'ti ti-alert-triangle',
 });
 </script>
 
diff --git a/packages/client/src/pages/about-misskey.vue b/packages/client/src/pages/about-misskey.vue
index 7bcccea98f..3ec972bcda 100644
--- a/packages/client/src/pages/about-misskey.vue
+++ b/packages/client/src/pages/about-misskey.vue
@@ -20,17 +20,17 @@
 				<FormSection>
 					<div class="_formLinks">
 						<FormLink to="https://github.com/misskey-dev/misskey" external>
-							<template #icon><i class="fas fa-code"></i></template>
+							<template #icon><i class="ti ti-code"></i></template>
 							{{ i18n.ts._aboutMisskey.source }}
 							<template #suffix>GitHub</template>
 						</FormLink>
 						<FormLink to="https://crowdin.com/project/misskey" external>
-							<template #icon><i class="fas fa-language"></i></template>
+							<template #icon><i class="ti ti-language-hiragana"></i></template>
 							{{ i18n.ts._aboutMisskey.translation }}
 							<template #suffix>Crowdin</template>
 						</FormLink>
 						<FormLink to="https://www.patreon.com/syuilo" external>
-							<template #icon><i class="fas fa-hand-holding-medical"></i></template>
+							<template #icon><i class="ti ti-pig-money"></i></template>
 							{{ i18n.ts._aboutMisskey.donate }}
 							<template #suffix>Patreon</template>
 						</FormLink>
diff --git a/packages/client/src/pages/about.emojis.vue b/packages/client/src/pages/about.emojis.vue
index df64378c01..53ce1e4b75 100644
--- a/packages/client/src/pages/about.emojis.vue
+++ b/packages/client/src/pages/about.emojis.vue
@@ -2,7 +2,7 @@
 <div class="driuhtrh">
 	<div class="query">
 		<MkInput v-model="q" class="" :placeholder="$ts.search">
-			<template #prefix><i class="fas fa-search"></i></template>
+			<template #prefix><i class="ti ti-search"></i></template>
 		</MkInput>
 
 		<!-- たくさんあると邪魔
diff --git a/packages/client/src/pages/about.federation.vue b/packages/client/src/pages/about.federation.vue
index c501a77582..6c92ab1264 100644
--- a/packages/client/src/pages/about.federation.vue
+++ b/packages/client/src/pages/about.federation.vue
@@ -2,7 +2,7 @@
 <div class="taeiyria">
 	<div class="query">
 		<MkInput v-model="host" :debounce="true" class="">
-			<template #prefix><i class="fas fa-search"></i></template>
+			<template #prefix><i class="ti ti-search"></i></template>
 			<template #label>{{ i18n.ts.host }}</template>
 		</MkInput>
 		<FormSplit style="margin-top: var(--margin);">
diff --git a/packages/client/src/pages/about.vue b/packages/client/src/pages/about.vue
index d124db55a7..0ed692c5c5 100644
--- a/packages/client/src/pages/about.vue
+++ b/packages/client/src/pages/about.vue
@@ -119,20 +119,20 @@ const headerTabs = $computed(() => [{
 }, {
 	key: 'emojis',
 	title: i18n.ts.customEmojis,
-	icon: 'fas fa-laugh',
+	icon: 'ti ti-mood-happy',
 }, {
 	key: 'federation',
 	title: i18n.ts.federation,
-	icon: 'fas fa-globe',
+	icon: 'ti ti-whirl',
 }, {
 	key: 'charts',
 	title: i18n.ts.charts,
-	icon: 'fas fa-chart-simple',
+	icon: 'ti ti-chart-line',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.instanceInfo,
-	icon: 'fas fa-info-circle',
+	icon: 'ti ti-info-circle',
 })));
 </script>
 
diff --git a/packages/client/src/pages/admin-file.vue b/packages/client/src/pages/admin-file.vue
index a62e0f630f..1b16a66ac4 100644
--- a/packages/client/src/pages/admin-file.vue
+++ b/packages/client/src/pages/admin-file.vue
@@ -36,7 +36,7 @@
 			</div>
 
 			<div class="_formBlock">
-				<MkButton danger @click="del"><i class="fas fa-trash-alt"></i> {{ i18n.ts.delete }}</MkButton>
+				<MkButton danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
 			</div>
 		</div>
 		<div v-else-if="tab === 'ip' && info" class="_formRoot">
@@ -114,7 +114,7 @@ async function toggleIsSensitive(v) {
 
 const headerActions = $computed(() => [{
 	text: i18n.ts.openInNewTab,
-	icon: 'fas fa-external-link-alt',
+	icon: 'ti ti-external-link',
 	handler: () => {
 		window.open(file.url, '_blank');
 	},
@@ -123,15 +123,15 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'overview',
 	title: i18n.ts.overview,
-	icon: 'fas fa-info-circle',
+	icon: 'ti ti-info-circle',
 }, iAmModerator ? {
 	key: 'ip',
 	title: 'IP',
-	icon: 'fas fa-bars-staggered',
+	icon: 'ti ti-password',
 } : null, {
 	key: 'raw',
 	title: 'Raw data',
-	icon: 'fas fa-code',
+	icon: 'ti ti-code',
 }]);
 
 definePageMetadata(computed(() => ({
diff --git a/packages/client/src/pages/admin/abuses.vue b/packages/client/src/pages/admin/abuses.vue
index 9907d4d235..973ec871ab 100644
--- a/packages/client/src/pages/admin/abuses.vue
+++ b/packages/client/src/pages/admin/abuses.vue
@@ -86,7 +86,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.abuseReports,
-	icon: 'fas fa-exclamation-circle',
+	icon: 'ti ti-exclamation-circle',
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/ads.vue b/packages/client/src/pages/admin/ads.vue
index 9a28d2ad61..2ec926c65c 100644
--- a/packages/client/src/pages/admin/ads.vue
+++ b/packages/client/src/pages/admin/ads.vue
@@ -37,8 +37,8 @@
 					<template #label>{{ i18n.ts.memo }}</template>
 				</MkTextarea>
 				<div class="buttons _formBlock">
-					<MkButton class="button" inline primary style="margin-right: 12px;" @click="save(ad)"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
-					<MkButton class="button" inline danger @click="remove(ad)"><i class="fas fa-trash-alt"></i> {{ i18n.ts.remove }}</MkButton>
+					<MkButton class="button" inline primary style="margin-right: 12px;" @click="save(ad)"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton class="button" inline danger @click="remove(ad)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
 				</div>
 			</div>
 		</div>
@@ -106,7 +106,7 @@ function save(ad) {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.add,
 	handler: add,
 }]);
@@ -115,7 +115,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.ads,
-	icon: 'fas fa-audio-description',
+	icon: 'ti ti-ad',
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/announcements.vue b/packages/client/src/pages/admin/announcements.vue
index f10693314a..607ad8aa02 100644
--- a/packages/client/src/pages/admin/announcements.vue
+++ b/packages/client/src/pages/admin/announcements.vue
@@ -16,8 +16,8 @@
 					</MkInput>
 					<p v-if="announcement.reads">{{ i18n.t('nUsersRead', { n: announcement.reads }) }}</p>
 					<div class="buttons">
-						<MkButton class="button" inline primary @click="save(announcement)"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
-						<MkButton class="button" inline @click="remove(announcement)"><i class="fas fa-trash-alt"></i> {{ i18n.ts.remove }}</MkButton>
+						<MkButton class="button" inline primary @click="save(announcement)"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+						<MkButton class="button" inline @click="remove(announcement)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
 					</div>
 				</div>
 			</section>
@@ -92,7 +92,7 @@ function save(announcement) {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.add,
 	handler: add,
 }]);
@@ -101,7 +101,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.announcements,
-	icon: 'fas fa-broadcast-tower',
+	icon: 'ti ti-speakerphone',
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/bot-protection.vue b/packages/client/src/pages/admin/bot-protection.vue
index 484a9d1a1a..d03961cf95 100644
--- a/packages/client/src/pages/admin/bot-protection.vue
+++ b/packages/client/src/pages/admin/bot-protection.vue
@@ -11,11 +11,11 @@
 
 			<template v-if="provider === 'hcaptcha'">
 				<FormInput v-model="hcaptchaSiteKey" class="_formBlock">
-					<template #prefix><i class="fas fa-key"></i></template>
+					<template #prefix><i class="ti ti-key"></i></template>
 					<template #label>{{ i18n.ts.hcaptchaSiteKey }}</template>
 				</FormInput>
 				<FormInput v-model="hcaptchaSecretKey" class="_formBlock">
-					<template #prefix><i class="fas fa-key"></i></template>
+					<template #prefix><i class="ti ti-key"></i></template>
 					<template #label>{{ i18n.ts.hcaptchaSecretKey }}</template>
 				</FormInput>
 				<FormSlot class="_formBlock">
@@ -25,11 +25,11 @@
 			</template>
 			<template v-else-if="provider === 'recaptcha'">
 				<FormInput v-model="recaptchaSiteKey" class="_formBlock">
-					<template #prefix><i class="fas fa-key"></i></template>
+					<template #prefix><i class="ti ti-key"></i></template>
 					<template #label>{{ i18n.ts.recaptchaSiteKey }}</template>
 				</FormInput>
 				<FormInput v-model="recaptchaSecretKey" class="_formBlock">
-					<template #prefix><i class="fas fa-key"></i></template>
+					<template #prefix><i class="ti ti-key"></i></template>
 					<template #label>{{ i18n.ts.recaptchaSecretKey }}</template>
 				</FormInput>
 				<FormSlot v-if="recaptchaSiteKey" class="_formBlock">
@@ -39,11 +39,11 @@
 			</template>
 			<template v-else-if="provider === 'turnstile'">
 				<FormInput v-model="turnstileSiteKey" class="_formBlock">
-					<template #prefix><i class="fas fa-key"></i></template>
+					<template #prefix><i class="ti ti-key"></i></template>
 					<template #label>{{ i18n.ts.turnstileSiteKey }}</template>
 				</FormInput>
 				<FormInput v-model="turnstileSecretKey" class="_formBlock">
-					<template #prefix><i class="fas fa-key"></i></template>
+					<template #prefix><i class="ti ti-key"></i></template>
 					<template #label>{{ i18n.ts.turnstileSecretKey }}</template>
 				</FormInput>
 				<FormSlot class="_formBlock">
@@ -52,7 +52,7 @@
 				</FormSlot>
 			</template>
 
-			<FormButton primary @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
+			<FormButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
 		</div>
 	</FormSuspense>
 </div>
diff --git a/packages/client/src/pages/admin/database.vue b/packages/client/src/pages/admin/database.vue
index 1c2656b8f5..5a0d3d5e51 100644
--- a/packages/client/src/pages/admin/database.vue
+++ b/packages/client/src/pages/admin/database.vue
@@ -1,13 +1,15 @@
-<template><MkStickyContainer>
+<template>
+<MkStickyContainer>
 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
-		<MkSpacer :content-max="800" :margin-min="16" :margin-max="32">
-	<FormSuspense v-slot="{ result: database }" :p="databasePromiseFactory">
-		<MkKeyValue v-for="table in database" :key="table[0]" oneline style="margin: 1em 0;">
-			<template #key>{{ table[0] }}</template>
-			<template #value>{{ bytes(table[1].size) }} ({{ number(table[1].count) }} recs)</template>
-		</MkKeyValue>
-	</FormSuspense>
-</MkSpacer></MkStickyContainer>
+	<MkSpacer :content-max="800" :margin-min="16" :margin-max="32">
+		<FormSuspense v-slot="{ result: database }" :p="databasePromiseFactory">
+			<MkKeyValue v-for="table in database" :key="table[0]" oneline style="margin: 1em 0;">
+				<template #key>{{ table[0] }}</template>
+				<template #value>{{ bytes(table[1].size) }} ({{ number(table[1].count) }} recs)</template>
+			</MkKeyValue>
+		</FormSuspense>
+	</MkSpacer>
+</MkStickyContainer>
 </template>
 
 <script lang="ts" setup>
@@ -28,6 +30,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.database,
-	icon: 'fas fa-database',
+	icon: 'ti ti-database',
 });
 </script>
diff --git a/packages/client/src/pages/admin/email-settings.vue b/packages/client/src/pages/admin/email-settings.vue
index 64137f0c3e..6c9dee1704 100644
--- a/packages/client/src/pages/admin/email-settings.vue
+++ b/packages/client/src/pages/admin/email-settings.vue
@@ -112,7 +112,7 @@ const headerActions = $computed(() => [{
 	handler: testEmail,
 }, {
 	asFullButton: true,
-	icon: 'fas fa-check',
+	icon: 'ti ti-check',
 	text: i18n.ts.save,
 	handler: save,
 }]);
@@ -121,6 +121,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.emailServer,
-	icon: 'fas fa-envelope',
+	icon: 'ti ti-mail',
 });
 </script>
diff --git a/packages/client/src/pages/admin/emoji-edit-dialog.vue b/packages/client/src/pages/admin/emoji-edit-dialog.vue
index 090dd9afc1..bd601cb1de 100644
--- a/packages/client/src/pages/admin/emoji-edit-dialog.vue
+++ b/packages/client/src/pages/admin/emoji-edit-dialog.vue
@@ -22,7 +22,7 @@
 				<template #label>{{ i18n.ts.tags }}</template>
 				<template #caption>{{ i18n.ts.setMultipleBySeparatingWithSpace }}</template>
 			</MkInput>
-			<MkButton danger @click="del()"><i class="fas fa-trash-alt"></i> {{ i18n.ts.delete }}</MkButton>
+			<MkButton danger @click="del()"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
 		</div>
 	</div>
 </XModalWindow>
diff --git a/packages/client/src/pages/admin/emojis.vue b/packages/client/src/pages/admin/emojis.vue
index 94f152d7db..14c8466d73 100644
--- a/packages/client/src/pages/admin/emojis.vue
+++ b/packages/client/src/pages/admin/emojis.vue
@@ -6,7 +6,7 @@
 			<div class="ogwlenmc">
 				<div v-if="tab === 'local'" class="local">
 					<MkInput v-model="query" :debounce="true" type="search">
-						<template #prefix><i class="fas fa-search"></i></template>
+						<template #prefix><i class="ti ti-search"></i></template>
 						<template #label>{{ i18n.ts.search }}</template>
 					</MkInput>
 					<MkSwitch v-model="selectMode" style="margin: 8px 0;">
@@ -39,7 +39,7 @@
 				<div v-else-if="tab === 'remote'" class="remote">
 					<FormSplit>
 						<MkInput v-model="queryRemote" :debounce="true" type="search">
-							<template #prefix><i class="fas fa-search"></i></template>
+							<template #prefix><i class="ti ti-search"></i></template>
 							<template #label>{{ i18n.ts.search }}</template>
 						</MkInput>
 						<MkInput v-model="host" :debounce="true">
@@ -164,49 +164,49 @@ const remoteMenu = (emoji, ev: MouseEvent) => {
 		text: ':' + emoji.name + ':',
 	}, {
 		text: i18n.ts.import,
-		icon: 'fas fa-plus',
+		icon: 'ti ti-plus',
 		action: () => { im(emoji); },
 	}], ev.currentTarget ?? ev.target);
 };
 
 const menu = (ev: MouseEvent) => {
 	os.popupMenu([{
-		icon: 'fas fa-download',
+		icon: 'ti ti-download',
 		text: i18n.ts.export,
 		action: async () => {
 			os.api('export-custom-emojis', {
 			})
-			.then(() => {
-				os.alert({
-					type: 'info',
-					text: i18n.ts.exportRequested,
+				.then(() => {
+					os.alert({
+						type: 'info',
+						text: i18n.ts.exportRequested,
+					});
+				}).catch((err) => {
+					os.alert({
+						type: 'error',
+						text: err.message,
+					});
 				});
-			}).catch((err) => {
-				os.alert({
-					type: 'error',
-					text: err.message,
-				});
-			});
 		},
 	}, {
-		icon: 'fas fa-upload',
+		icon: 'ti ti-upload',
 		text: i18n.ts.import,
 		action: async () => {
 			const file = await selectFile(ev.currentTarget ?? ev.target);
 			os.api('admin/emoji/import-zip', {
 				fileId: file.id,
 			})
-			.then(() => {
-				os.alert({
-					type: 'info',
-					text: i18n.ts.importRequested,
+				.then(() => {
+					os.alert({
+						type: 'info',
+						text: i18n.ts.importRequested,
+					});
+				}).catch((err) => {
+					os.alert({
+						type: 'error',
+						text: err.message,
+					});
 				});
-			}).catch((err) => {
-				os.alert({
-					type: 'error',
-					text: err.message,
-				});
-			});
 		},
 	}], ev.currentTarget ?? ev.target);
 };
@@ -273,11 +273,11 @@ const delBulk = async () => {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.addEmoji,
 	handler: add,
 }, {
-	icon: 'fas fa-ellipsis-h',
+	icon: 'ti ti-dots',
 	handler: menu,
 }]);
 
@@ -291,7 +291,7 @@ const headerTabs = $computed(() => [{
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.customEmojis,
-	icon: 'fas fa-laugh',
+	icon: 'ti ti-mood-happy',
 })));
 </script>
 
diff --git a/packages/client/src/pages/admin/files.vue b/packages/client/src/pages/admin/files.vue
index 2e3a807ba6..8ad6bd4fc0 100644
--- a/packages/client/src/pages/admin/files.vue
+++ b/packages/client/src/pages/admin/files.vue
@@ -97,11 +97,11 @@ async function find() {
 
 const headerActions = $computed(() => [{
 	text: i18n.ts.lookup,
-	icon: 'fas fa-search',
+	icon: 'ti ti-search',
 	handler: find,
 }, {
 	text: i18n.ts.clearCachedFiles,
-	icon: 'fas fa-trash-alt',
+	icon: 'ti ti-trash',
 	handler: clear,
 }]);
 
@@ -109,7 +109,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.files,
-	icon: 'fas fa-cloud',
+	icon: 'ti ti-cloud',
 })));
 </script>
 
diff --git a/packages/client/src/pages/admin/index.vue b/packages/client/src/pages/admin/index.vue
index 20f82bba28..75d3fcae70 100644
--- a/packages/client/src/pages/admin/index.vue
+++ b/packages/client/src/pages/admin/index.vue
@@ -40,7 +40,7 @@ const router = useRouter();
 
 const indexInfo = {
 	title: i18n.ts.controlPanel,
-	icon: 'fas fa-cog',
+	icon: 'ti ti-settings',
 	hideHeader: true,
 };
 
@@ -75,34 +75,34 @@ const menuDef = $computed(() => [{
 	title: i18n.ts.quickAction,
 	items: [{
 		type: 'button',
-		icon: 'fas fa-search',
+		icon: 'ti ti-search',
 		text: i18n.ts.lookup,
 		action: lookup,
 	}, ...(instance.disableRegistration ? [{
 		type: 'button',
-		icon: 'fas fa-user',
+		icon: 'ti ti-user',
 		text: i18n.ts.invite,
 		action: invite,
 	}] : [])],
 }, {
 	title: i18n.ts.administration,
 	items: [{
-		icon: 'fas fa-tachometer-alt',
+		icon: 'ti ti-dashboard',
 		text: i18n.ts.dashboard,
 		to: '/admin/overview',
 		active: currentPage?.route.name === 'overview',
 	}, {
-		icon: 'fas fa-users',
+		icon: 'ti ti-users',
 		text: i18n.ts.users,
 		to: '/admin/users',
 		active: currentPage?.route.name === 'users',
 	}, {
-		icon: 'fas fa-laugh',
+		icon: 'ti ti-mood-happy',
 		text: i18n.ts.customEmojis,
 		to: '/admin/emojis',
 		active: currentPage?.route.name === 'emojis',
 	}, {
-		icon: 'fas fa-globe',
+		icon: 'ti ti-whirl',
 		text: i18n.ts.federation,
 		to: '/about#federation',
 		active: currentPage?.route.name === 'federation',
@@ -112,22 +112,22 @@ const menuDef = $computed(() => [{
 		to: '/admin/queue',
 		active: currentPage?.route.name === 'queue',
 	}, {
-		icon: 'fas fa-cloud',
+		icon: 'ti ti-cloud',
 		text: i18n.ts.files,
 		to: '/admin/files',
 		active: currentPage?.route.name === 'files',
 	}, {
-		icon: 'fas fa-broadcast-tower',
+		icon: 'ti ti-speakerphone',
 		text: i18n.ts.announcements,
 		to: '/admin/announcements',
 		active: currentPage?.route.name === 'announcements',
 	}, {
-		icon: 'fas fa-audio-description',
+		icon: 'ti ti-ad',
 		text: i18n.ts.ads,
 		to: '/admin/ads',
 		active: currentPage?.route.name === 'ads',
 	}, {
-		icon: 'fas fa-exclamation-circle',
+		icon: 'ti ti-exclamation-circle',
 		text: i18n.ts.abuseReports,
 		to: '/admin/abuses',
 		active: currentPage?.route.name === 'abuses',
@@ -135,37 +135,37 @@ const menuDef = $computed(() => [{
 }, {
 	title: i18n.ts.settings,
 	items: [{
-		icon: 'fas fa-cog',
+		icon: 'ti ti-settings',
 		text: i18n.ts.general,
 		to: '/admin/settings',
 		active: currentPage?.route.name === 'settings',
 	}, {
-		icon: 'fas fa-envelope',
+		icon: 'ti ti-mail',
 		text: i18n.ts.emailServer,
 		to: '/admin/email-settings',
 		active: currentPage?.route.name === 'email-settings',
 	}, {
-		icon: 'fas fa-cloud',
+		icon: 'ti ti-cloud',
 		text: i18n.ts.objectStorage,
 		to: '/admin/object-storage',
 		active: currentPage?.route.name === 'object-storage',
 	}, {
-		icon: 'fas fa-lock',
+		icon: 'ti ti-lock',
 		text: i18n.ts.security,
 		to: '/admin/security',
 		active: currentPage?.route.name === 'security',
 	}, {
-		icon: 'fas fa-globe',
+		icon: 'ti ti-planet',
 		text: i18n.ts.relays,
 		to: '/admin/relays',
 		active: currentPage?.route.name === 'relays',
 	}, {
-		icon: 'fas fa-share-alt',
+		icon: 'ti ti-share',
 		text: i18n.ts.integration,
 		to: '/admin/integrations',
 		active: currentPage?.route.name === 'integrations',
 	}, {
-		icon: 'fas fa-ban',
+		icon: 'ti ti-ban',
 		text: i18n.ts.instanceBlocking,
 		to: '/admin/instance-block',
 		active: currentPage?.route.name === 'instance-block',
@@ -175,7 +175,7 @@ const menuDef = $computed(() => [{
 		to: '/admin/proxy-account',
 		active: currentPage?.route.name === 'proxy-account',
 	}, {
-		icon: 'fas fa-cogs',
+		icon: 'ti ti-adjustments',
 		text: i18n.ts.other,
 		to: '/admin/other-settings',
 		active: currentPage?.route.name === 'other-settings',
@@ -183,7 +183,7 @@ const menuDef = $computed(() => [{
 }, {
 	title: i18n.ts.info,
 	items: [{
-		icon: 'fas fa-database',
+		icon: 'ti ti-database',
 		text: i18n.ts.database,
 		to: '/admin/database',
 		active: currentPage?.route.name === 'database',
@@ -234,25 +234,25 @@ const invite = () => {
 const lookup = (ev) => {
 	os.popupMenu([{
 		text: i18n.ts.user,
-		icon: 'fas fa-user',
+		icon: 'ti ti-user',
 		action: () => {
 			lookupUser();
 		},
 	}, {
 		text: i18n.ts.note,
-		icon: 'fas fa-pencil-alt',
+		icon: 'ti ti-pencil',
 		action: () => {
 			alert('TODO');
 		},
 	}, {
 		text: i18n.ts.file,
-		icon: 'fas fa-cloud',
+		icon: 'ti ti-cloud',
 		action: () => {
 			alert('TODO');
 		},
 	}, {
 		text: i18n.ts.instance,
-		icon: 'fas fa-globe',
+		icon: 'ti ti-planet',
 		action: () => {
 			alert('TODO');
 		},
diff --git a/packages/client/src/pages/admin/instance-block.vue b/packages/client/src/pages/admin/instance-block.vue
index 94b740a4d5..1bdd174de4 100644
--- a/packages/client/src/pages/admin/instance-block.vue
+++ b/packages/client/src/pages/admin/instance-block.vue
@@ -8,7 +8,7 @@
 				<template #caption>{{ i18n.ts.blockedInstancesDescription }}</template>
 			</FormTextarea>
 
-			<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
+			<FormButton primary class="_formBlock" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
 		</FormSuspense>
 	</MkSpacer>
 </MkStickyContainer>
@@ -46,6 +46,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.instanceBlocking,
-	icon: 'fas fa-ban',
+	icon: 'ti ti-ban',
 });
 </script>
diff --git a/packages/client/src/pages/admin/integrations.discord.vue b/packages/client/src/pages/admin/integrations.discord.vue
index 0ab6ecbb4f..0a69c44c93 100644
--- a/packages/client/src/pages/admin/integrations.discord.vue
+++ b/packages/client/src/pages/admin/integrations.discord.vue
@@ -9,17 +9,17 @@
 			<FormInfo class="_formBlock">Callback URL: {{ `${uri}/api/dc/cb` }}</FormInfo>
 		
 			<FormInput v-model="discordClientId" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
+				<template #prefix><i class="ti ti-key"></i></template>
 				<template #label>Client ID</template>
 			</FormInput>
 
 			<FormInput v-model="discordClientSecret" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
+				<template #prefix><i class="ti ti-key"></i></template>
 				<template #label>Client Secret</template>
 			</FormInput>
 		</template>
 
-		<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
+		<FormButton primary class="_formBlock" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
 	</div>
 </FormSuspense>
 </template>
diff --git a/packages/client/src/pages/admin/integrations.github.vue b/packages/client/src/pages/admin/integrations.github.vue
index 34761e9a7b..66419d5891 100644
--- a/packages/client/src/pages/admin/integrations.github.vue
+++ b/packages/client/src/pages/admin/integrations.github.vue
@@ -9,17 +9,17 @@
 			<FormInfo class="_formBlock">Callback URL: {{ `${uri}/api/gh/cb` }}</FormInfo>
 		
 			<FormInput v-model="githubClientId" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
+				<template #prefix><i class="ti ti-key"></i></template>
 				<template #label>Client ID</template>
 			</FormInput>
 
 			<FormInput v-model="githubClientSecret" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
+				<template #prefix><i class="ti ti-key"></i></template>
 				<template #label>Client Secret</template>
 			</FormInput>
 		</template>
 
-		<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
+		<FormButton primary class="_formBlock" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
 	</div>
 </FormSuspense>
 </template>
diff --git a/packages/client/src/pages/admin/integrations.twitter.vue b/packages/client/src/pages/admin/integrations.twitter.vue
index a870d76a4d..1e8d882b9c 100644
--- a/packages/client/src/pages/admin/integrations.twitter.vue
+++ b/packages/client/src/pages/admin/integrations.twitter.vue
@@ -9,17 +9,17 @@
 			<FormInfo class="_formBlock">Callback URL: {{ `${uri}/api/tw/cb` }}</FormInfo>
 		
 			<FormInput v-model="twitterConsumerKey" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
+				<template #prefix><i class="ti ti-key"></i></template>
 				<template #label>Consumer Key</template>
 			</FormInput>
 
 			<FormInput v-model="twitterConsumerSecret" class="_formBlock">
-				<template #prefix><i class="fas fa-key"></i></template>
+				<template #prefix><i class="ti ti-key"></i></template>
 				<template #label>Consumer Secret</template>
 			</FormInput>
 		</template>
 
-		<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
+		<FormButton primary class="_formBlock" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
 	</div>
 </FormSuspense>
 </template>
diff --git a/packages/client/src/pages/admin/integrations.vue b/packages/client/src/pages/admin/integrations.vue
index 9964426a68..d02fc48076 100644
--- a/packages/client/src/pages/admin/integrations.vue
+++ b/packages/client/src/pages/admin/integrations.vue
@@ -52,6 +52,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.integration,
-	icon: 'fas fa-share-alt',
+	icon: 'ti ti-share',
 });
 </script>
diff --git a/packages/client/src/pages/admin/object-storage.vue b/packages/client/src/pages/admin/object-storage.vue
index 5cc3018532..f2ab30eaa5 100644
--- a/packages/client/src/pages/admin/object-storage.vue
+++ b/packages/client/src/pages/admin/object-storage.vue
@@ -34,12 +34,12 @@
 
 					<FormSplit :min-width="280">
 						<FormInput v-model="objectStorageAccessKey" class="_formBlock">
-							<template #prefix><i class="fas fa-key"></i></template>
+							<template #prefix><i class="ti ti-key"></i></template>
 							<template #label>Access key</template>
 						</FormInput>
 
 						<FormInput v-model="objectStorageSecretKey" class="_formBlock">
-							<template #prefix><i class="fas fa-key"></i></template>
+							<template #prefix><i class="ti ti-key"></i></template>
 							<template #label>Secret key</template>
 						</FormInput>
 					</FormSplit>
@@ -134,7 +134,7 @@ function save() {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-check',
+	icon: 'ti ti-check',
 	text: i18n.ts.save,
 	handler: save,
 }]);
@@ -143,6 +143,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.objectStorage,
-	icon: 'fas fa-cloud',
+	icon: 'ti ti-cloud',
 });
 </script>
diff --git a/packages/client/src/pages/admin/other-settings.vue b/packages/client/src/pages/admin/other-settings.vue
index ee4e8edba0..62dff6ce7f 100644
--- a/packages/client/src/pages/admin/other-settings.vue
+++ b/packages/client/src/pages/admin/other-settings.vue
@@ -30,7 +30,7 @@ function save() {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-check',
+	icon: 'ti ti-check',
 	text: i18n.ts.save,
 	handler: save,
 }]);
@@ -39,6 +39,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.other,
-	icon: 'fas fa-cogs',
+	icon: 'ti ti-adjustments',
 });
 </script>
diff --git a/packages/client/src/pages/admin/overview.vue b/packages/client/src/pages/admin/overview.vue
index b0d1b543d0..07b808d55b 100644
--- a/packages/client/src/pages/admin/overview.vue
+++ b/packages/client/src/pages/admin/overview.vue
@@ -467,7 +467,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.dashboard,
-	icon: 'fas fa-tachometer-alt',
+	icon: 'ti ti-dashboard',
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/relays.vue b/packages/client/src/pages/admin/relays.vue
index e6f7f4ead1..4768ae67b1 100644
--- a/packages/client/src/pages/admin/relays.vue
+++ b/packages/client/src/pages/admin/relays.vue
@@ -5,12 +5,12 @@
 		<div v-for="relay in relays" :key="relay.inbox" class="relaycxt _panel _block" style="padding: 16px;">
 			<div>{{ relay.inbox }}</div>
 			<div class="status">
-				<i v-if="relay.status === 'accepted'" class="fas fa-check icon accepted"></i>
-				<i v-else-if="relay.status === 'rejected'" class="fas fa-ban icon rejected"></i>
-				<i v-else class="fas fa-clock icon requesting"></i>
+				<i v-if="relay.status === 'accepted'" class="ti ti-check icon accepted"></i>
+				<i v-else-if="relay.status === 'rejected'" class="ti ti-ban icon rejected"></i>
+				<i v-else class="ti ti-clock icon requesting"></i>
 				<span>{{ $t(`_relayStatus.${relay.status}`) }}</span>
 			</div>
-			<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="fas fa-trash-alt"></i> {{ i18n.ts.remove }}</MkButton>
+			<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
 		</div>
 	</MkSpacer>
 </MkStickyContainer>
@@ -68,7 +68,7 @@ refresh();
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.addRelay,
 	handler: addRelay,
 }]);
@@ -77,7 +77,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.relays,
-	icon: 'fas fa-globe',
+	icon: 'ti ti-planet',
 });
 </script>
 
diff --git a/packages/client/src/pages/admin/security.vue b/packages/client/src/pages/admin/security.vue
index 65d079c2cf..11c06257cc 100644
--- a/packages/client/src/pages/admin/security.vue
+++ b/packages/client/src/pages/admin/security.vue
@@ -5,7 +5,7 @@
 		<FormSuspense :p="init">
 			<div class="_formRoot">
 				<FormFolder class="_formBlock">
-					<template #icon><i class="fas fa-shield-alt"></i></template>
+					<template #icon><i class="ti ti-shield"></i></template>
 					<template #label>{{ i18n.ts.botProtection }}</template>
 					<template v-if="enableHcaptcha" #suffix>hCaptcha</template>
 					<template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template>
@@ -16,7 +16,7 @@
 				</FormFolder>
 
 				<FormFolder class="_formBlock">
-					<template #icon><i class="fas fa-eye-slash"></i></template>
+					<template #icon><i class="ti ti-eye-off"></i></template>
 					<template #label>{{ i18n.ts.sensitiveMediaDetection }}</template>
 					<template v-if="sensitiveMediaDetection === 'all'" #suffix>{{ i18n.ts.all }}</template>
 					<template v-else-if="sensitiveMediaDetection === 'local'" #suffix>{{ i18n.ts.localOnly }}</template>
@@ -54,7 +54,7 @@
 						</FormSwitch>
 						-->
 
-						<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
+						<FormButton primary class="_formBlock" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
 					</div>
 				</FormFolder>
 
@@ -88,11 +88,11 @@
 
 					<div class="_formRoot">
 						<FormInput v-model="summalyProxy" class="_formBlock">
-							<template #prefix><i class="fas fa-link"></i></template>
+							<template #prefix><i class="ti ti-link"></i></template>
 							<template #label>Summaly Proxy URL</template>
 						</FormInput>
 
-						<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
+						<FormButton primary class="_formBlock" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
 					</div>
 				</FormFolder>
 			</div>
@@ -174,6 +174,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.security,
-	icon: 'fas fa-lock',
+	icon: 'ti ti-lock',
 });
 </script>
diff --git a/packages/client/src/pages/admin/settings.vue b/packages/client/src/pages/admin/settings.vue
index cf6b1f17e9..460eb92694 100644
--- a/packages/client/src/pages/admin/settings.vue
+++ b/packages/client/src/pages/admin/settings.vue
@@ -14,7 +14,7 @@
 					</FormTextarea>
 
 					<FormInput v-model="tosUrl" class="_formBlock">
-						<template #prefix><i class="fas fa-link"></i></template>
+						<template #prefix><i class="ti ti-link"></i></template>
 						<template #label>{{ i18n.ts.tosUrl }}</template>
 					</FormInput>
 
@@ -24,7 +24,7 @@
 						</FormInput>
 
 						<FormInput v-model="maintainerEmail" type="email" class="_formBlock">
-							<template #prefix><i class="fas fa-envelope"></i></template>
+							<template #prefix><i class="ti ti-mail"></i></template>
 							<template #label>{{ i18n.ts.maintainerEmail }}</template>
 						</FormInput>
 					</FormSplit>
@@ -54,22 +54,22 @@
 						<template #label>{{ i18n.ts.theme }}</template>
 
 						<FormInput v-model="iconUrl" class="_formBlock">
-							<template #prefix><i class="fas fa-link"></i></template>
+							<template #prefix><i class="ti ti-link"></i></template>
 							<template #label>{{ i18n.ts.iconUrl }}</template>
 						</FormInput>
 
 						<FormInput v-model="bannerUrl" class="_formBlock">
-							<template #prefix><i class="fas fa-link"></i></template>
+							<template #prefix><i class="ti ti-link"></i></template>
 							<template #label>{{ i18n.ts.bannerUrl }}</template>
 						</FormInput>
 
 						<FormInput v-model="backgroundImageUrl" class="_formBlock">
-							<template #prefix><i class="fas fa-link"></i></template>
+							<template #prefix><i class="ti ti-link"></i></template>
 							<template #label>{{ i18n.ts.backgroundImageUrl }}</template>
 						</FormInput>
 
 						<FormInput v-model="themeColor" class="_formBlock">
-							<template #prefix><i class="fas fa-palette"></i></template>
+							<template #prefix><i class="ti ti-palette"></i></template>
 							<template #label>{{ i18n.ts.themeColor }}</template>
 							<template #caption>#RRGGBB</template>
 						</FormInput>
@@ -118,12 +118,12 @@
 
 						<template v-if="enableServiceWorker">
 							<FormInput v-model="swPublicKey" class="_formBlock">
-								<template #prefix><i class="fas fa-key"></i></template>
+								<template #prefix><i class="ti ti-key"></i></template>
 								<template #label>Public key</template>
 							</FormInput>
 
 							<FormInput v-model="swPrivateKey" class="_formBlock">
-								<template #prefix><i class="fas fa-key"></i></template>
+								<template #prefix><i class="ti ti-key"></i></template>
 								<template #label>Private key</template>
 							</FormInput>
 						</template>
@@ -133,7 +133,7 @@
 						<template #label>DeepL Translation</template>
 
 						<FormInput v-model="deeplAuthKey" class="_formBlock">
-							<template #prefix><i class="fas fa-key"></i></template>
+							<template #prefix><i class="ti ti-key"></i></template>
 							<template #label>DeepL Auth Key</template>
 						</FormInput>
 						<FormSwitch v-model="deeplIsPro" class="_formBlock">
@@ -248,7 +248,7 @@ function save() {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-check',
+	icon: 'ti ti-check',
 	text: i18n.ts.save,
 	handler: save,
 }]);
@@ -257,6 +257,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.general,
-	icon: 'fas fa-cog',
+	icon: 'ti ti-settings',
 });
 </script>
diff --git a/packages/client/src/pages/admin/users.vue b/packages/client/src/pages/admin/users.vue
index eeb335a430..bf630d28d2 100644
--- a/packages/client/src/pages/admin/users.vue
+++ b/packages/client/src/pages/admin/users.vue
@@ -115,17 +115,17 @@ function show(user) {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'fas fa-search',
+	icon: 'ti ti-search',
 	text: i18n.ts.search,
 	handler: searchUser,
 }, {
 	asFullButton: true,
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.addUser,
 	handler: addUser,
 }, {
 	asFullButton: true,
-	icon: 'fas fa-search',
+	icon: 'ti ti-search',
 	text: i18n.ts.lookup,
 	handler: lookupUser,
 }]);
@@ -134,7 +134,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.users,
-	icon: 'fas fa-users',
+	icon: 'ti ti-users',
 })));
 </script>
 
diff --git a/packages/client/src/pages/announcements.vue b/packages/client/src/pages/announcements.vue
index 5f66596997..6a93b3b9fa 100644
--- a/packages/client/src/pages/announcements.vue
+++ b/packages/client/src/pages/announcements.vue
@@ -10,7 +10,7 @@
 					<img v-if="announcement.imageUrl" :src="announcement.imageUrl"/>
 				</div>
 				<div v-if="$i && !announcement.isRead" class="_footer">
-					<MkButton primary @click="read(items, announcement, i)"><i class="fas fa-check"></i> {{ $ts.gotIt }}</MkButton>
+					<MkButton primary @click="read(items, announcement, i)"><i class="ti ti-check"></i> {{ $ts.gotIt }}</MkButton>
 				</div>
 			</section>
 		</MkPagination>
@@ -46,7 +46,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.announcements,
-	icon: 'fas fa-broadcast-tower',
+	icon: 'ti ti-speakerphone',
 });
 </script>
 
diff --git a/packages/client/src/pages/antenna-timeline.vue b/packages/client/src/pages/antenna-timeline.vue
index 500cb3a7c5..592131b2a8 100644
--- a/packages/client/src/pages/antenna-timeline.vue
+++ b/packages/client/src/pages/antenna-timeline.vue
@@ -76,7 +76,7 @@ const headerActions = $computed(() => antenna ? [{
 	text: i18n.ts.jumpToSpecifiedDate,
 	handler: timetravel,
 }, {
-	icon: 'fas fa-cog',
+	icon: 'ti ti-settings',
 	text: i18n.ts.settings,
 	handler: settings,
 }] : []);
@@ -85,7 +85,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => antenna ? {
 	title: antenna.name,
-	icon: 'fas fa-satellite',
+	icon: 'ti ti-antenna',
 } : null));
 </script>
 
diff --git a/packages/client/src/pages/api-console.vue b/packages/client/src/pages/api-console.vue
index 0064e4c3f1..a46b85462e 100644
--- a/packages/client/src/pages/api-console.vue
+++ b/packages/client/src/pages/api-console.vue
@@ -15,7 +15,7 @@
 				</MkSwitch>
 				<MkButton class="_formBlock" primary :disabled="sending" @click="send">
 					<template v-if="sending"><MkEllipsis/></template>
-					<template v-else><i class="fas fa-paper-plane"></i> Send</template>
+					<template v-else><i class="ti ti-send"></i> Send</template>
 				</MkButton>
 			</div>
 			<div v-if="res" class="_formBlock">
@@ -84,6 +84,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'API console',
-	icon: 'fas fa-terminal',
+	icon: 'ti ti-terminal-2',
 });
 </script>
diff --git a/packages/client/src/pages/channel-editor.vue b/packages/client/src/pages/channel-editor.vue
index 3e94b5f041..5ae7e63f99 100644
--- a/packages/client/src/pages/channel-editor.vue
+++ b/packages/client/src/pages/channel-editor.vue
@@ -12,14 +12,14 @@
 			</MkTextarea>
 
 			<div class="banner">
-				<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="fas fa-plus"></i> {{ i18n.ts._channel.setBanner }}</MkButton>
+				<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="ti ti-plus"></i> {{ i18n.ts._channel.setBanner }}</MkButton>
 				<div v-else-if="bannerUrl">
 					<img :src="bannerUrl" style="width: 100%;"/>
-					<MkButton @click="removeBannerImage()"><i class="fas fa-trash-alt"></i> {{ i18n.ts._channel.removeBanner }}</MkButton>
+					<MkButton @click="removeBannerImage()"><i class="ti ti-trash"></i> {{ i18n.ts._channel.removeBanner }}</MkButton>
 				</div>
 			</div>
 			<div class="_formBlock">
-				<MkButton primary @click="save()"><i class="fas fa-save"></i> {{ channelId ? i18n.ts.save : i18n.ts.create }}</MkButton>
+				<MkButton primary @click="save()"><i class="ti ti-device-floppy"></i> {{ channelId ? i18n.ts.save : i18n.ts.create }}</MkButton>
 			</div>
 		</div>
 	</MkSpacer>
@@ -110,10 +110,10 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => props.channelId ? {
 	title: i18n.ts._channel.edit,
-	icon: 'fas fa-satellite-dish',
+	icon: 'ti ti-device-tv',
 } : {
 	title: i18n.ts._channel.create,
-	icon: 'fas fa-satellite-dish',
+	icon: 'ti ti-device-tv',
 }));
 </script>
 
diff --git a/packages/client/src/pages/channel.vue b/packages/client/src/pages/channel.vue
index 380c3efc8e..f271bb270f 100644
--- a/packages/client/src/pages/channel.vue
+++ b/packages/client/src/pages/channel.vue
@@ -6,15 +6,15 @@
 			<div class="wpgynlbz _panel _gap" :class="{ hide: !showBanner }">
 				<XChannelFollowButton :channel="channel" :full="true" class="subscribe"/>
 				<button class="_button toggle" @click="() => showBanner = !showBanner">
-					<template v-if="showBanner"><i class="fas fa-angle-up"></i></template>
-					<template v-else><i class="fas fa-angle-down"></i></template>
+					<template v-if="showBanner"><i class="ti ti-chevron-up"></i></template>
+					<template v-else><i class="ti ti-chevron-down"></i></template>
 				</button>
 				<div v-if="!showBanner" class="hideOverlay">
 				</div>
 				<div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" class="banner">
 					<div class="status">
-						<div><i class="fas fa-users fa-fw"></i><I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
-						<div><i class="fas fa-pencil-alt fa-fw"></i><I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
+						<div><i class="ti ti-users ti-fw"></i><I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.usersCount }}</b></template></I18n></div>
+						<div><i class="ti ti-pencil ti-fw"></i><I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;"><template #n><b>{{ channel.notesCount }}</b></template></I18n></div>
 					</div>
 					<div class="fade"></div>
 				</div>
@@ -70,7 +70,7 @@ function edit() {
 }
 
 const headerActions = $computed(() => channel && channel.userId ? [{
-	icon: 'fas fa-cog',
+	icon: 'ti ti-settings',
 	text: i18n.ts.edit,
 	handler: edit,
 }] : null);
@@ -79,7 +79,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => channel ? {
 	title: channel.name,
-	icon: 'fas fa-satellite-dish',
+	icon: 'ti ti-device-tv',
 } : null));
 </script>
 
diff --git a/packages/client/src/pages/channels.vue b/packages/client/src/pages/channels.vue
index 56ea98d15e..7c84629a0a 100644
--- a/packages/client/src/pages/channels.vue
+++ b/packages/client/src/pages/channels.vue
@@ -13,7 +13,7 @@
 			</MkPagination>
 		</div>
 		<div v-else-if="tab === 'owned'" class="_content grwlizim owned">
-			<MkButton class="new" @click="create()"><i class="fas fa-plus"></i></MkButton>
+			<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
 			<MkPagination v-slot="{items}" :pagination="ownedPagination">
 				<MkChannelPreview v-for="channel in items" :key="channel.id" class="_gap" :channel="channel"/>
 			</MkPagination>
@@ -53,7 +53,7 @@ function create() {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.create,
 	handler: create,
 }]);
@@ -65,15 +65,15 @@ const headerTabs = $computed(() => [{
 }, {
 	key: 'following',
 	title: i18n.ts._channel.following,
-	icon: 'fas fa-heart',
+	icon: 'ti ti-heart',
 }, {
 	key: 'owned',
 	title: i18n.ts._channel.owned,
-	icon: 'fas fa-edit',
+	icon: 'ti ti-edit',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.channel,
-	icon: 'fas fa-satellite-dish',
+	icon: 'ti ti-device-tv',
 })));
 </script>
diff --git a/packages/client/src/pages/clip.vue b/packages/client/src/pages/clip.vue
index 5b56651bdd..e0fbcb6bed 100644
--- a/packages/client/src/pages/clip.vue
+++ b/packages/client/src/pages/clip.vue
@@ -53,7 +53,7 @@ watch(() => props.clipId, async () => {
 provide('currentClipPage', $$(clip));
 
 const headerActions = $computed(() => clip && isOwned ? [{
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 	text: i18n.ts.edit,
 	handler: async (): Promise<void> => {
 		const { canceled, result } = await os.form(clip.name, {
@@ -83,7 +83,7 @@ const headerActions = $computed(() => clip && isOwned ? [{
 		});
 	},
 }, {
-	icon: 'fas fa-trash-alt',
+	icon: 'ti ti-trash',
 	text: i18n.ts.delete,
 	danger: true,
 	handler: async (): Promise<void> => {
@@ -101,7 +101,7 @@ const headerActions = $computed(() => clip && isOwned ? [{
 
 definePageMetadata(computed(() => clip ? {
 	title: clip.name,
-	icon: 'fas fa-paperclip',
+	icon: 'ti ti-paperclip',
 } : null));
 </script>
 
diff --git a/packages/client/src/pages/drive.vue b/packages/client/src/pages/drive.vue
index 088f0eacdc..04ade5c207 100644
--- a/packages/client/src/pages/drive.vue
+++ b/packages/client/src/pages/drive.vue
@@ -19,7 +19,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: folder ? folder.name : i18n.ts.drive,
-	icon: 'fas fa-cloud',
+	icon: 'ti ti-cloud',
 	hideHeader: true,
 })));
 </script>
diff --git a/packages/client/src/pages/emojis.emoji.vue b/packages/client/src/pages/emojis.emoji.vue
index b2801694db..04bf4ef167 100644
--- a/packages/client/src/pages/emojis.emoji.vue
+++ b/packages/client/src/pages/emojis.emoji.vue
@@ -24,7 +24,7 @@ function menu(ev) {
 		text: ':' + props.emoji.name + ':',
 	}, {
 		text: i18n.ts.copy,
-		icon: 'fas fa-copy',
+		icon: 'ti ti-copy',
 		action: () => {
 			copyToClipboard(`:${props.emoji.name}:`);
 			os.success();
diff --git a/packages/client/src/pages/explore.users.vue b/packages/client/src/pages/explore.users.vue
index e16e40b8ed..bfee0a6c07 100644
--- a/packages/client/src/pages/explore.users.vue
+++ b/packages/client/src/pages/explore.users.vue
@@ -7,26 +7,26 @@
 	<div v-if="origin === 'local'">
 		<template v-if="tag == null">
 			<MkFolder class="_gap" persist-key="explore-pinned-users">
-				<template #header><i class="fas fa-bookmark fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedUsers }}</template>
+				<template #header><i class="fas fa-bookmark ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedUsers }}</template>
 				<XUserList :pagination="pinnedUsers"/>
 			</MkFolder>
 			<MkFolder class="_gap" persist-key="explore-popular-users">
-				<template #header><i class="fas fa-chart-line fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
+				<template #header><i class="fas fa-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
 				<XUserList :pagination="popularUsers"/>
 			</MkFolder>
 			<MkFolder class="_gap" persist-key="explore-recently-updated-users">
-				<template #header><i class="fas fa-comment-alt fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
+				<template #header><i class="fas fa-comment-alt ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
 				<XUserList :pagination="recentlyUpdatedUsers"/>
 			</MkFolder>
 			<MkFolder class="_gap" persist-key="explore-recently-registered-users">
-				<template #header><i class="fas fa-plus fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyRegisteredUsers }}</template>
+				<template #header><i class="ti ti-plus ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyRegisteredUsers }}</template>
 				<XUserList :pagination="recentlyRegisteredUsers"/>
 			</MkFolder>
 		</template>
 	</div>
 	<div v-else>
 		<MkFolder ref="tagsEl" :foldable="true" :expanded="false" class="_gap">
-			<template #header><i class="fas fa-hashtag fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularTags }}</template>
+			<template #header><i class="ti ti-hash ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularTags }}</template>
 
 			<div class="vxjfqztj">
 				<MkA v-for="tag in tagsLocal" :key="'local:' + tag.tag" :to="`/explore/tags/${tag.tag}`" class="local">{{ tag.tag }}</MkA>
@@ -35,21 +35,21 @@
 		</MkFolder>
 
 		<MkFolder v-if="tag != null" :key="`${tag}`" class="_gap">
-			<template #header><i class="fas fa-hashtag fa-fw" style="margin-right: 0.5em;"></i>{{ tag }}</template>
+			<template #header><i class="ti ti-hash ti-fw" style="margin-right: 0.5em;"></i>{{ tag }}</template>
 			<XUserList :pagination="tagUsers"/>
 		</MkFolder>
 
 		<template v-if="tag == null">
 			<MkFolder class="_gap">
-				<template #header><i class="fas fa-chart-line fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
+				<template #header><i class="fas fa-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
 				<XUserList :pagination="popularUsersF"/>
 			</MkFolder>
 			<MkFolder class="_gap">
-				<template #header><i class="fas fa-comment-alt fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
+				<template #header><i class="fas fa-comment-alt ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
 				<XUserList :pagination="recentlyUpdatedUsersF"/>
 			</MkFolder>
 			<MkFolder class="_gap">
-				<template #header><i class="fas fa-rocket fa-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyDiscoveredUsers }}</template>
+				<template #header><i class="fas fa-rocket ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyDiscoveredUsers }}</template>
 				<XUserList :pagination="recentlyRegisteredUsersF"/>
 			</MkFolder>
 		</template>
diff --git a/packages/client/src/pages/explore.vue b/packages/client/src/pages/explore.vue
index 279960d139..6b0bcdaf62 100644
--- a/packages/client/src/pages/explore.vue
+++ b/packages/client/src/pages/explore.vue
@@ -12,7 +12,7 @@
 			<MkSpacer :content-max="1200">
 				<div>
 					<MkInput v-model="searchQuery" :debounce="true" type="search" class="_formBlock">
-						<template #prefix><i class="fas fa-search"></i></template>
+						<template #prefix><i class="ti ti-search"></i></template>
 						<template #label>{{ i18n.ts.searchUser }}</template>
 					</MkInput>
 					<MkRadios v-model="searchOrigin" class="_formBlock">
@@ -69,11 +69,11 @@ const headerActions = $computed(() => []);
 
 const headerTabs = $computed(() => [{
 	key: 'featured',
-	icon: 'fas fa-bolt',
+	icon: 'ti ti-bolt',
 	title: i18n.ts.featured,
 }, {
 	key: 'users',
-	icon: 'fas fa-users',
+	icon: 'ti ti-users',
 	title: i18n.ts.users,
 }, {
 	key: 'search',
@@ -82,6 +82,6 @@ const headerTabs = $computed(() => [{
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.explore,
-	icon: 'fas fa-hashtag',
+	icon: 'ti ti-hash',
 })));
 </script>
diff --git a/packages/client/src/pages/favorites.vue b/packages/client/src/pages/favorites.vue
index 32a1dbf592..ab47efec71 100644
--- a/packages/client/src/pages/favorites.vue
+++ b/packages/client/src/pages/favorites.vue
@@ -37,7 +37,7 @@ const pagingComponent = ref<InstanceType<typeof MkPagination>>();
 
 definePageMetadata({
 	title: i18n.ts.favorites,
-	icon: 'fas fa-star',
+	icon: 'ti ti-star',
 });
 </script>
 
diff --git a/packages/client/src/pages/follow-requests.vue b/packages/client/src/pages/follow-requests.vue
index 82d7164260..2bef35746e 100644
--- a/packages/client/src/pages/follow-requests.vue
+++ b/packages/client/src/pages/follow-requests.vue
@@ -22,8 +22,8 @@
 								<Mfm :text="req.follower.description" :is-note="false" :author="req.follower" :i="$i" :custom-emojis="req.follower.emojis" :plain="true" :nowrap="true"/>
 							</div>
 							<div class="actions">
-								<button class="_button" @click="accept(req.follower)"><i class="fas fa-check"></i></button>
-								<button class="_button" @click="reject(req.follower)"><i class="fas fa-times"></i></button>
+								<button class="_button" @click="accept(req.follower)"><i class="ti ti-check"></i></button>
+								<button class="_button" @click="reject(req.follower)"><i class="ti ti-x"></i></button>
 							</div>
 						</div>
 					</div>
@@ -67,7 +67,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.followRequests,
-	icon: 'fas fa-user-clock',
+	icon: 'ti ti-user-clock',
 })));
 </script>
 
diff --git a/packages/client/src/pages/gallery/edit.vue b/packages/client/src/pages/gallery/edit.vue
index 8f716d9eb3..c8111d7890 100644
--- a/packages/client/src/pages/gallery/edit.vue
+++ b/packages/client/src/pages/gallery/edit.vue
@@ -14,17 +14,17 @@
 			<div class="">
 				<div v-for="file in files" :key="file.id" class="wqugxsfx" :style="{ backgroundImage: file ? `url(${ file.thumbnailUrl })` : null }">
 					<div class="name">{{ file.name }}</div>
-					<button v-tooltip="i18n.ts.remove" class="remove _button" @click="remove(file)"><i class="fas fa-times"></i></button>
+					<button v-tooltip="i18n.ts.remove" class="remove _button" @click="remove(file)"><i class="ti ti-x"></i></button>
 				</div>
-				<FormButton primary @click="selectFile"><i class="fas fa-plus"></i> {{ i18n.ts.attachFile }}</FormButton>
+				<FormButton primary @click="selectFile"><i class="ti ti-plus"></i> {{ i18n.ts.attachFile }}</FormButton>
 			</div>
 
 			<FormSwitch v-model="isSensitive">{{ i18n.ts.markAsSensitive }}</FormSwitch>
 
-			<FormButton v-if="postId" primary @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton>
-			<FormButton v-else primary @click="save"><i class="fas fa-save"></i> {{ i18n.ts.publish }}</FormButton>
+			<FormButton v-if="postId" primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</FormButton>
+			<FormButton v-else primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.publish }}</FormButton>
 
-			<FormButton v-if="postId" danger @click="del"><i class="fas fa-trash-alt"></i> {{ i18n.ts.delete }}</FormButton>
+			<FormButton v-if="postId" danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</FormButton>
 		</FormSuspense>
 	</MkSpacer>
 </MkStickyContainer>
@@ -115,10 +115,10 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => props.postId ? {
 	title: i18n.ts.edit,
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 } : {
 	title: i18n.ts.postToGallery,
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 }));
 </script>
 
diff --git a/packages/client/src/pages/gallery/index.vue b/packages/client/src/pages/gallery/index.vue
index 598383217e..b04c1fad94 100644
--- a/packages/client/src/pages/gallery/index.vue
+++ b/packages/client/src/pages/gallery/index.vue
@@ -5,7 +5,7 @@
 		<div class="_root">
 			<div v-if="tab === 'explore'">
 				<MkFolder class="_gap">
-					<template #header><i class="fas fa-clock"></i>{{ i18n.ts.recentPosts }}</template>
+					<template #header><i class="ti ti-clock"></i>{{ i18n.ts.recentPosts }}</template>
 					<MkPagination v-slot="{items}" :pagination="recentPostsPagination" :disable-auto-load="true">
 						<div class="vfpdbgtk">
 							<MkGalleryPostPreview v-for="post in items" :key="post.id" :post="post" class="post"/>
@@ -29,7 +29,7 @@
 				</MkPagination>
 			</div>
 			<div v-else-if="tab === 'my'">
-				<MkA to="/gallery/new" class="_link" style="margin: 16px;"><i class="fas fa-plus"></i> {{ i18n.ts.postToGallery }}</MkA>
+				<MkA to="/gallery/new" class="_link" style="margin: 16px;"><i class="ti ti-plus"></i> {{ i18n.ts.postToGallery }}</MkA>
 				<MkPagination v-slot="{items}" :pagination="myPostsPagination">
 					<div class="vfpdbgtk">
 						<MkGalleryPostPreview v-for="post in items" :key="post.id" :post="post" class="post"/>
@@ -98,7 +98,7 @@ watch(() => props.tag, () => {
 });
 
 const headerActions = $computed(() => [{
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.create,
 	handler: () => {
 		router.push('/gallery/new');
@@ -108,20 +108,20 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'explore',
 	title: i18n.ts.gallery,
-	icon: 'fas fa-icons',
+	icon: 'ti ti-icons',
 }, {
 	key: 'liked',
 	title: i18n.ts._gallery.liked,
-	icon: 'fas fa-heart',
+	icon: 'ti ti-heart',
 }, {
 	key: 'my',
 	title: i18n.ts._gallery.my,
-	icon: 'fas fa-edit',
+	icon: 'ti ti-edit',
 }]);
 
 definePageMetadata({
 	title: i18n.ts.gallery,
-	icon: 'fas fa-icons',
+	icon: 'ti ti-icons',
 });
 </script>
 
diff --git a/packages/client/src/pages/gallery/post.vue b/packages/client/src/pages/gallery/post.vue
index 3804bcdcf5..7a125cfaab 100644
--- a/packages/client/src/pages/gallery/post.vue
+++ b/packages/client/src/pages/gallery/post.vue
@@ -14,17 +14,17 @@
 						<div class="title">{{ post.title }}</div>
 						<div class="description"><Mfm :text="post.description"/></div>
 						<div class="info">
-							<i class="fas fa-clock"></i> <MkTime :time="post.createdAt" mode="detail"/>
+							<i class="ti ti-clock"></i> <MkTime :time="post.createdAt" mode="detail"/>
 						</div>
 						<div class="actions">
 							<div class="like">
-								<MkButton v-if="post.isLiked" v-tooltip="i18n.ts._gallery.unlike" class="button" primary @click="unlike()"><i class="fas fa-heart"></i><span v-if="post.likedCount > 0" class="count">{{ post.likedCount }}</span></MkButton>
+								<MkButton v-if="post.isLiked" v-tooltip="i18n.ts._gallery.unlike" class="button" primary @click="unlike()"><i class="ti ti-heart"></i><span v-if="post.likedCount > 0" class="count">{{ post.likedCount }}</span></MkButton>
 								<MkButton v-else v-tooltip="i18n.ts._gallery.like" class="button" @click="like()"><i class="far fa-heart"></i><span v-if="post.likedCount > 0" class="count">{{ post.likedCount }}</span></MkButton>
 							</div>
 							<div class="other">
-								<button v-if="$i && $i.id === post.user.id" v-tooltip="i18n.ts.edit" v-click-anime class="_button" @click="edit"><i class="fas fa-pencil-alt fa-fw"></i></button>
-								<button v-tooltip="i18n.ts.shareWithNote" v-click-anime class="_button" @click="shareWithNote"><i class="fas fa-retweet fa-fw"></i></button>
-								<button v-tooltip="i18n.ts.share" v-click-anime class="_button" @click="share"><i class="fas fa-share-alt fa-fw"></i></button>
+								<button v-if="$i && $i.id === post.user.id" v-tooltip="i18n.ts.edit" v-click-anime class="_button" @click="edit"><i class="ti ti-pencil ti-fw"></i></button>
+								<button v-tooltip="i18n.ts.shareWithNote" v-click-anime class="_button" @click="shareWithNote"><i class="ti ti-repeat ti-fw"></i></button>
+								<button v-tooltip="i18n.ts.share" v-click-anime class="_button" @click="share"><i class="ti ti-share ti-fw"></i></button>
 							</div>
 						</div>
 						<div class="user">
@@ -38,7 +38,7 @@
 					</div>
 					<MkAd :prefer="['horizontal', 'horizontal-big']"/>
 					<MkContainer :max-height="300" :foldable="true" class="other">
-						<template #header><i class="fas fa-clock"></i> {{ i18n.ts.recentPosts }}</template>
+						<template #header><i class="ti ti-clock"></i> {{ i18n.ts.recentPosts }}</template>
 						<MkPagination v-slot="{items}" :pagination="otherPostsPagination">
 							<div class="sdrarzaf">
 								<MkGalleryPostPreview v-for="post in items" :key="post.id" :post="post" class="post"/>
@@ -139,7 +139,7 @@ function edit() {
 watch(() => props.postId, fetchPost, { immediate: true });
 
 const headerActions = $computed(() => [{
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 	text: i18n.ts.edit,
 	handler: edit,
 }]);
diff --git a/packages/client/src/pages/instance-info.vue b/packages/client/src/pages/instance-info.vue
index 6e13da0d68..92288f573d 100644
--- a/packages/client/src/pages/instance-info.vue
+++ b/packages/client/src/pages/instance-info.vue
@@ -28,7 +28,7 @@
 				<template #label>Moderation</template>
 				<FormSwitch v-model="suspended" class="_formBlock" @update:modelValue="toggleSuspend">{{ i18n.ts.stopActivityDelivery }}</FormSwitch>
 				<FormSwitch v-model="isBlocked" class="_formBlock" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</FormSwitch>
-				<MkButton @click="refreshMetadata"><i class="fas fa-refresh"></i> Refresh metadata</MkButton>
+				<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
 			</FormSection>
 
 			<FormSection>
@@ -195,7 +195,7 @@ fetch();
 
 const headerActions = $computed(() => [{
 	text: `https://${props.host}`,
-	icon: 'fas fa-external-link-alt',
+	icon: 'ti ti-external-link',
 	handler: () => {
 		window.open(`https://${props.host}`, '_blank');
 	},
@@ -204,24 +204,24 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'overview',
 	title: i18n.ts.overview,
-	icon: 'fas fa-info-circle',
+	icon: 'ti ti-info-circle',
 }, {
 	key: 'chart',
 	title: i18n.ts.charts,
-	icon: 'fas fa-chart-simple',
+	icon: 'ti ti-chart-line',
 }, {
 	key: 'users',
 	title: i18n.ts.users,
-	icon: 'fas fa-users',
+	icon: 'ti ti-users',
 }, {
 	key: 'raw',
 	title: 'Raw',
-	icon: 'fas fa-code',
+	icon: 'ti ti-code',
 }]);
 
 definePageMetadata({
 	title: props.host,
-	icon: 'fas fa-server',
+	icon: 'ti ti-server',
 });
 </script>
 
diff --git a/packages/client/src/pages/messaging/index.vue b/packages/client/src/pages/messaging/index.vue
index 56d852fe3d..b4cec5f5e9 100644
--- a/packages/client/src/pages/messaging/index.vue
+++ b/packages/client/src/pages/messaging/index.vue
@@ -3,7 +3,7 @@
 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
 	<MkSpacer :content-max="800">
 		<div v-size="{ max: [400] }" class="yweeujhr">
-			<MkButton primary class="start" @click="start"><i class="fas fa-plus"></i> {{ $ts.startMessaging }}</MkButton>
+			<MkButton primary class="start" @click="start"><i class="ti ti-plus"></i> {{ $ts.startMessaging }}</MkButton>
 
 			<div v-if="messages.length > 0" class="history">
 				<MkA
@@ -96,11 +96,11 @@ function onRead(ids) {
 function start(ev) {
 	os.popupMenu([{
 		text: i18n.ts.messagingWithUser,
-		icon: 'fas fa-user',
+		icon: 'ti ti-user',
 		action: () => { startUser(); },
 	}, {
 		text: i18n.ts.messagingWithGroup,
-		icon: 'fas fa-users',
+		icon: 'ti ti-users',
 		action: () => { startGroup(); },
 	}], ev.currentTarget ?? ev.target);
 }
@@ -158,7 +158,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.messaging,
-	icon: 'fas fa-comments',
+	icon: 'ti ti-messages',
 });
 </script>
 
diff --git a/packages/client/src/pages/messaging/messaging-room.form.vue b/packages/client/src/pages/messaging/messaging-room.form.vue
index 4589069df0..ca0ebf554e 100644
--- a/packages/client/src/pages/messaging/messaging-room.form.vue
+++ b/packages/client/src/pages/messaging/messaging-room.form.vue
@@ -15,10 +15,10 @@
 	<footer>
 		<div v-if="file" class="file" @click="file = null">{{ file.name }}</div>
 		<div class="buttons">
-			<button class="_button" @click="chooseFile"><i class="fas fa-photo-video"></i></button>
-			<button class="_button" @click="insertEmoji"><i class="fas fa-laugh-squint"></i></button>
+			<button class="_button" @click="chooseFile"><i class="ti ti-photo-plus"></i></button>
+			<button class="_button" @click="insertEmoji"><i class="ti ti-mood-happy"></i></button>
 			<button class="send _button" :disabled="!canSend || sending" :title="i18n.ts.send" @click="send">
-				<template v-if="!sending"><i class="fas fa-paper-plane"></i></template><template v-if="sending"><i class="fas fa-spinner fa-pulse fa-fw"></i></template>
+				<template v-if="!sending"><i class="ti ti-send"></i></template><template v-if="sending"><i class="fas fa-spinner fa-pulse ti-fw"></i></template>
 			</button>
 		</div>
 	</footer>
diff --git a/packages/client/src/pages/messaging/messaging-room.message.vue b/packages/client/src/pages/messaging/messaging-room.message.vue
index 2b5a9569a1..e7cf54a066 100644
--- a/packages/client/src/pages/messaging/messaging-room.message.vue
+++ b/packages/client/src/pages/messaging/messaging-room.message.vue
@@ -29,7 +29,7 @@
 				<span v-if="isMe && message.isRead" class="read">{{ $ts.messageRead }}</span>
 			</template>
 			<MkTime :time="message.createdAt"/>
-			<template v-if="message.is_edited"><i class="fas fa-pencil-alt"></i></template>
+			<template v-if="message.is_edited"><i class="ti ti-pencil"></i></template>
 		</footer>
 	</div>
 </div>
diff --git a/packages/client/src/pages/messaging/messaging-room.vue b/packages/client/src/pages/messaging/messaging-room.vue
index 37d4145ee8..b6eeb9260e 100644
--- a/packages/client/src/pages/messaging/messaging-room.vue
+++ b/packages/client/src/pages/messaging/messaging-room.vue
@@ -40,7 +40,7 @@
 			</div>
 			<transition :name="animation ? 'fade' : ''">
 				<div v-show="showIndicator" class="new-message">
-					<button class="_buttonPrimary" @click="onIndicatorClick"><i class="fas fa-fw fa-arrow-circle-down"></i>{{ i18n.ts.newMessageExists }}</button>
+					<button class="_buttonPrimary" @click="onIndicatorClick"><i class="fas ti-fw fa-arrow-circle-down"></i>{{ i18n.ts.newMessageExists }}</button>
 				</div>
 			</transition>
 			<XForm v-if="!fetching" ref="formEl" :user="user" :group="group" class="form"/>
@@ -300,7 +300,7 @@ definePageMetadata(computed(() => !fetching ? user ? {
 	avatar: user,
 } : {
 	title: group?.name,
-	icon: 'fas fa-users',
+	icon: 'ti ti-users',
 } : null));
 </script>
 
diff --git a/packages/client/src/pages/mfm-cheat-sheet.vue b/packages/client/src/pages/mfm-cheat-sheet.vue
index bd8ae4e0b6..7c85dfb7ad 100644
--- a/packages/client/src/pages/mfm-cheat-sheet.vue
+++ b/packages/client/src/pages/mfm-cheat-sheet.vue
@@ -351,7 +351,7 @@ let preview_plain = $ref('<plain>**bold** @mention #hashtag `code` $[x2 🍮]</p
 
 definePageMetadata({
 	title: i18n.ts._mfm.cheatSheet,
-	icon: 'fas fa-question-circle',
+	icon: 'ti ti-question-circle',
 });
 </script>
 
diff --git a/packages/client/src/pages/my-antennas/create.vue b/packages/client/src/pages/my-antennas/create.vue
index dc10bece81..005b036696 100644
--- a/packages/client/src/pages/my-antennas/create.vue
+++ b/packages/client/src/pages/my-antennas/create.vue
@@ -37,7 +37,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.manageAntennas,
-	icon: 'fas fa-satellite',
+	icon: 'ti ti-antenna',
 });
 </script>
 
diff --git a/packages/client/src/pages/my-antennas/edit.vue b/packages/client/src/pages/my-antennas/edit.vue
index 53f9b07db0..cb583faaeb 100644
--- a/packages/client/src/pages/my-antennas/edit.vue
+++ b/packages/client/src/pages/my-antennas/edit.vue
@@ -34,7 +34,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.manageAntennas,
-	icon: 'fas fa-satellite',
+	icon: 'ti ti-antenna',
 });
 </script>
 
diff --git a/packages/client/src/pages/my-antennas/editor.vue b/packages/client/src/pages/my-antennas/editor.vue
index 054053fbfb..a409a734b5 100644
--- a/packages/client/src/pages/my-antennas/editor.vue
+++ b/packages/client/src/pages/my-antennas/editor.vue
@@ -38,8 +38,8 @@
 		<MkSwitch v-model="notify" class="_formBlock">{{ i18n.ts.notifyAntenna }}</MkSwitch>
 	</div>
 	<div class="actions">
-		<MkButton inline primary @click="saveAntenna()"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
-		<MkButton v-if="antenna.id != null" inline danger @click="deleteAntenna()"><i class="fas fa-trash"></i> {{ i18n.ts.delete }}</MkButton>
+		<MkButton inline primary @click="saveAntenna()"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+		<MkButton v-if="antenna.id != null" inline danger @click="deleteAntenna()"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
 	</div>
 </div>
 </template>
diff --git a/packages/client/src/pages/my-antennas/index.vue b/packages/client/src/pages/my-antennas/index.vue
index dc73ba674e..9daf23f9b5 100644
--- a/packages/client/src/pages/my-antennas/index.vue
+++ b/packages/client/src/pages/my-antennas/index.vue
@@ -2,7 +2,7 @@
 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
 		<MkSpacer :content-max="700">
 	<div class="ieepwinx">
-		<MkButton :link="true" to="/my/antennas/create" primary class="add"><i class="fas fa-plus"></i> {{ i18n.ts.add }}</MkButton>
+		<MkButton :link="true" to="/my/antennas/create" primary class="add"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
 
 		<div class="">
 			<MkPagination v-slot="{items}" ref="list" :pagination="pagination">
@@ -33,7 +33,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.manageAntennas,
-	icon: 'fas fa-satellite',
+	icon: 'ti ti-antenna',
 });
 </script>
 
diff --git a/packages/client/src/pages/my-clips/index.vue b/packages/client/src/pages/my-clips/index.vue
index 68330d6db4..dd6b5b3a37 100644
--- a/packages/client/src/pages/my-clips/index.vue
+++ b/packages/client/src/pages/my-clips/index.vue
@@ -3,7 +3,7 @@
 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
 	<MkSpacer :content-max="700">
 		<div class="qtcaoidl">
-			<MkButton primary class="add" @click="create"><i class="fas fa-plus"></i> {{ i18n.ts.add }}</MkButton>
+			<MkButton primary class="add" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
 
 			<MkPagination v-slot="{items}" ref="pagingComponent" :pagination="pagination" class="list">
 				<MkA v-for="item in items" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _gap">
@@ -70,9 +70,9 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.clip,
-	icon: 'fas fa-paperclip',
+	icon: 'ti ti-paperclip',
 	action: {
-		icon: 'fas fa-plus',
+		icon: 'ti ti-plus',
 		handler: create,
 	},
 });
diff --git a/packages/client/src/pages/my-lists/index.vue b/packages/client/src/pages/my-lists/index.vue
index 9af7c0d105..3476436b27 100644
--- a/packages/client/src/pages/my-lists/index.vue
+++ b/packages/client/src/pages/my-lists/index.vue
@@ -3,7 +3,7 @@
 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
 	<MkSpacer :content-max="700">
 		<div class="qkcjvfiv">
-			<MkButton primary class="add" @click="create"><i class="fas fa-plus"></i> {{ i18n.ts.createList }}</MkButton>
+			<MkButton primary class="add" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.createList }}</MkButton>
 
 			<MkPagination v-slot="{items}" ref="pagingComponent" :pagination="pagination" class="lists _content">
 				<MkA v-for="list in items" :key="list.id" class="list _panel" :to="`/my/lists/${ list.id }`">
@@ -47,9 +47,9 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.manageLists,
-	icon: 'fas fa-list-ul',
+	icon: 'ti ti-list',
 	action: {
-		icon: 'fas fa-plus',
+		icon: 'ti ti-plus',
 		handler: create,
 	},
 });
diff --git a/packages/client/src/pages/my-lists/list.vue b/packages/client/src/pages/my-lists/list.vue
index d90453526e..f6234ffe44 100644
--- a/packages/client/src/pages/my-lists/list.vue
+++ b/packages/client/src/pages/my-lists/list.vue
@@ -25,7 +25,7 @@
 									<MkAcct :user="user" class="acct"/>
 								</div>
 								<div class="action">
-									<button class="_button" @click="removeUser(user)"><i class="fas fa-times"></i></button>
+									<button class="_button" @click="removeUser(user)"><i class="ti ti-x"></i></button>
 								</div>
 							</div>
 						</div>
@@ -122,7 +122,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => list ? {
 	title: list.name,
-	icon: 'fas fa-list-ul',
+	icon: 'ti ti-list',
 } : null));
 </script>
 
diff --git a/packages/client/src/pages/not-found.vue b/packages/client/src/pages/not-found.vue
index 253ecdb235..e58e44ef79 100644
--- a/packages/client/src/pages/not-found.vue
+++ b/packages/client/src/pages/not-found.vue
@@ -17,6 +17,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.notFound,
-	icon: 'fas fa-exclamation-triangle',
+	icon: 'ti ti-alert-triangle',
 });
 </script>
diff --git a/packages/client/src/pages/note.vue b/packages/client/src/pages/note.vue
index 6509cb306e..ba2bb91239 100644
--- a/packages/client/src/pages/note.vue
+++ b/packages/client/src/pages/note.vue
@@ -10,7 +10,7 @@
 					</div>
 
 					<div class="main _gap">
-						<MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><i class="fas fa-chevron-up"></i></MkButton>
+						<MkButton v-if="!showNext && hasNext" class="load next" @click="showNext = true"><i class="ti ti-chevron-up"></i></MkButton>
 						<div class="note _gap">
 							<MkRemoteCaution v-if="note.user.host != null" :href="note.url ?? note.uri"/>
 							<XNoteDetailed :key="note.id" v-model:note="note" class="note"/>
@@ -25,7 +25,7 @@
 								</div>
 							</MkA>
 						</div>
-						<MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><i class="fas fa-chevron-down"></i></MkButton>
+						<MkButton v-if="!showPrev && hasPrev" class="load prev" @click="showPrev = true"><i class="ti ti-chevron-down"></i></MkButton>
 					</div>
 
 					<div v-if="showPrev" class="_gap">
diff --git a/packages/client/src/pages/notifications.vue b/packages/client/src/pages/notifications.vue
index dd57060fda..7106951de2 100644
--- a/packages/client/src/pages/notifications.vue
+++ b/packages/client/src/pages/notifications.vue
@@ -50,7 +50,7 @@ function setFilter(ev) {
 		},
 	}));
 	const items = includeTypes != null ? [{
-		icon: 'fas fa-times',
+		icon: 'ti ti-x',
 		text: i18n.ts.clear,
 		action: () => {
 			includeTypes = null;
@@ -61,12 +61,12 @@ function setFilter(ev) {
 
 const headerActions = $computed(() => [tab === 'all' ? {
 	text: i18n.ts.filter,
-	icon: 'fas fa-filter',
+	icon: 'ti ti-filter',
 	highlighted: includeTypes != null,
 	handler: setFilter,
 } : undefined, tab === 'all' ? {
 	text: i18n.ts.markAllAsRead,
-	icon: 'fas fa-check',
+	icon: 'ti ti-check',
 	handler: () => {
 		os.apiWithDialog('notifications/mark-all-as-read');
 	},
@@ -81,15 +81,15 @@ const headerTabs = $computed(() => [{
 }, {
 	key: 'mentions',
 	title: i18n.ts.mentions,
-	icon: 'fas fa-at',
+	icon: 'ti ti-at',
 }, {
 	key: 'directNotes',
 	title: i18n.ts.directNotes,
-	icon: 'fas fa-envelope',
+	icon: 'ti ti-mail',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.notifications,
-	icon: 'fas fa-bell',
+	icon: 'ti ti-bell',
 })));
 </script>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.button.vue b/packages/client/src/pages/page-editor/els/page-editor.el.button.vue
index 4c2e0e4eb4..0438969afa 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.button.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.button.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.button }}</template>
+	<template #header><i class="ti ti-bolt"></i> {{ $ts._pages.blocks.button }}</template>
 
 	<section class="xfhsjczc">
 		<MkInput v-model="value.text"><template #label>{{ $ts._pages.blocks._button.text }}</template></MkInput>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue b/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue
index 1a2078448d..8625c26e78 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.counter.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.counter }}</template>
+	<template #header><i class="ti ti-bolt"></i> {{ $ts._pages.blocks.counter }}</template>
 
 	<section style="padding: 0 16px 0 16px;">
 		<MkInput v-model="value.name">
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.if.vue b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
index d763070b15..c93caeb9bd 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.if.vue
@@ -4,7 +4,7 @@
 	<template #header><i class="fas fa-question"></i> {{ $ts._pages.blocks.if }}</template>
 	<template #func>
 		<button class="_button" @click="add()">
-			<i class="fas fa-plus"></i>
+			<i class="ti ti-plus"></i>
 		</button>
 	</template>
 
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue
index 479a859e76..a8fb702329 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.number-input.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.numberInput }}</template>
+	<template #header><i class="ti ti-bolt"></i> {{ $ts._pages.blocks.numberInput }}</template>
 
 	<section style="padding: 0 16px 0 16px;">
 		<MkInput v-model="value.name">
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.post.vue b/packages/client/src/pages/page-editor/els/page-editor.el.post.vue
index f8c42c296b..39be01ab32 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.post.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.post.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-paper-plane"></i> {{ $ts._pages.blocks.post }}</template>
+	<template #header><i class="ti ti-send"></i> {{ $ts._pages.blocks.post }}</template>
 
 	<section style="padding: 16px;">
 		<MkTextarea v-model="value.text"><template #label>{{ $ts._pages.blocks._post.text }}</template></MkTextarea>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
index 4b28f120a9..754af477b6 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.radio-button.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.radioButton }}</template>
+	<template #header><i class="ti ti-bolt"></i> {{ $ts._pages.blocks.radioButton }}</template>
 
 	<section style="padding: 0 16px 16px 16px;">
 		<MkInput v-model="value.name"><template #prefix><i class="fas fa-magic"></i></template><template #label>{{ $ts._pages.blocks._radioButton.name }}</template></MkInput>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.section.vue b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
index 7276cc1e1b..c7b87c660b 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.section.vue
@@ -4,10 +4,10 @@
 	<template #header><i class="fas fa-sticky-note"></i> {{ value.title }}</template>
 	<template #func>
 		<button class="_button" @click="rename()">
-			<i class="fas fa-pencil-alt"></i>
+			<i class="ti ti-pencil"></i>
 		</button>
 		<button class="_button" @click="add()">
-			<i class="fas fa-plus"></i>
+			<i class="ti ti-plus"></i>
 		</button>
 	</template>
 
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue b/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue
index ded57cf304..c74b17cc2c 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.switch.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.switch }}</template>
+	<template #header><i class="ti ti-bolt"></i> {{ $ts._pages.blocks.switch }}</template>
 
 	<section class="kjuadyyj">
 		<MkInput v-model="value.name"><template #prefix><i class="fas fa-magic"></i></template><template #label>{{ $ts._pages.blocks._switch.name }}</template></MkInput>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue
index 1e269ae58c..99631c4dae 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.text-input.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.textInput }}</template>
+	<template #header><i class="ti ti-bolt"></i> {{ $ts._pages.blocks.textInput }}</template>
 
 	<section style="padding: 0 16px 0 16px;">
 		<MkInput v-model="value.name"><template #prefix><i class="fas fa-magic"></i></template><template #label>{{ $ts._pages.blocks._textInput.name }}</template></MkInput>
diff --git a/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue b/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue
index 1bb4aaa543..4b417e39a7 100644
--- a/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue
+++ b/packages/client/src/pages/page-editor/els/page-editor.el.textarea-input.vue
@@ -1,7 +1,7 @@
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="fas fa-bolt"></i> {{ $ts._pages.blocks.textareaInput }}</template>
+	<template #header><i class="ti ti-bolt"></i> {{ $ts._pages.blocks.textareaInput }}</template>
 
 	<section style="padding: 0 16px 16px 16px;">
 		<MkInput v-model="value.name"><template #prefix><i class="fas fa-magic"></i></template><template #label>{{ $ts._pages.blocks._textareaInput.name }}</template></MkInput>
diff --git a/packages/client/src/pages/page-editor/page-editor.container.vue b/packages/client/src/pages/page-editor/page-editor.container.vue
index 6927e55868..efc9aac2a7 100644
--- a/packages/client/src/pages/page-editor/page-editor.container.vue
+++ b/packages/client/src/pages/page-editor/page-editor.container.vue
@@ -5,14 +5,14 @@
 		<div class="buttons">
 			<slot name="func"></slot>
 			<button v-if="removable" class="_button" @click="remove()">
-				<i class="fas fa-trash-alt"></i>
+				<i class="ti ti-trash"></i>
 			</button>
 			<button v-if="draggable" class="drag-handle _button">
-				<i class="fas fa-bars"></i>
+				<i class="ti ti-menu-2"></i>
 			</button>
 			<button class="_button" @click="toggleContent(!showBody)">
-				<template v-if="showBody"><i class="fas fa-angle-up"></i></template>
-				<template v-else><i class="fas fa-angle-down"></i></template>
+				<template v-if="showBody"><i class="ti ti-chevron-up"></i></template>
+				<template v-else><i class="ti ti-chevron-down"></i></template>
 			</button>
 		</div>
 	</header>
diff --git a/packages/client/src/pages/page-editor/page-editor.script-block.vue b/packages/client/src/pages/page-editor/page-editor.script-block.vue
index ded9368b89..bb07adaae2 100644
--- a/packages/client/src/pages/page-editor/page-editor.script-block.vue
+++ b/packages/client/src/pages/page-editor/page-editor.script-block.vue
@@ -4,7 +4,7 @@
 	<template #header><i v-if="icon" :class="icon"></i> <template v-if="title">{{ title }} <span v-if="typeText" class="turmquns">({{ typeText }})</span></template><template v-else-if="typeText">{{ typeText }}</template></template>
 	<template #func>
 		<button class="_button" @click="changeType()">
-			<i class="fas fa-pencil-alt"></i>
+			<i class="ti ti-pencil"></i>
 		</button>
 	</template>
 
@@ -116,7 +116,7 @@ export default defineComponent({
 	computed: {
 		icon(): any {
 			if (this.modelValue.type === null) return null;
-			if (this.modelValue.type.startsWith('fn:')) return 'fas fa-plug';
+			if (this.modelValue.type.startsWith('fn:')) return 'ti ti-plug';
 			return blockDefs.find(x => x.type === this.modelValue.type).icon;
 		},
 		typeText(): any {
diff --git a/packages/client/src/pages/page-editor/page-editor.vue b/packages/client/src/pages/page-editor/page-editor.vue
index 591d13053a..1230119c63 100644
--- a/packages/client/src/pages/page-editor/page-editor.vue
+++ b/packages/client/src/pages/page-editor/page-editor.vue
@@ -3,10 +3,10 @@
 	<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
 	<MkSpacer :content-max="700">
 		<div class="jqqmcavi">
-			<MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="fas fa-external-link-square-alt"></i> {{ $ts._pages.viewPage }}</MkButton>
-			<MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
-			<MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="fas fa-copy"></i> {{ $ts.duplicate }}</MkButton>
-			<MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="fas fa-trash-alt"></i> {{ $ts.delete }}</MkButton>
+			<MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="ti ti-external-link"></i> {{ $ts._pages.viewPage }}</MkButton>
+			<MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="ti ti-device-floppy"></i> {{ $ts.save }}</MkButton>
+			<MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="ti ti-copy"></i> {{ $ts.duplicate }}</MkButton>
+			<MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="ti ti-trash"></i> {{ $ts.delete }}</MkButton>
 		</div>
 
 		<div v-if="tab === 'settings'">
@@ -35,10 +35,10 @@
 				<MkSwitch v-model="hideTitleWhenPinned" class="_formBlock">{{ $ts._pages.hideTitleWhenPinned }}</MkSwitch>
 
 				<div class="eyeCatch">
-					<MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><i class="fas fa-plus"></i> {{ $ts._pages.eyeCatchingImageSet }}</MkButton>
+					<MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><i class="ti ti-plus"></i> {{ $ts._pages.eyeCatchingImageSet }}</MkButton>
 					<div v-else-if="eyeCatchingImage">
 						<img :src="eyeCatchingImage.url" :alt="eyeCatchingImage.name" style="max-width: 100%;"/>
-						<MkButton v-if="!readonly" @click="removeEyeCatchingImage()"><i class="fas fa-trash-alt"></i> {{ $ts._pages.eyeCatchingImageRemove }}</MkButton>
+						<MkButton v-if="!readonly" @click="removeEyeCatchingImage()"><i class="ti ti-trash"></i> {{ $ts._pages.eyeCatchingImageRemove }}</MkButton>
 					</div>
 				</div>
 			</div>
@@ -48,7 +48,7 @@
 			<div>
 				<XBlocks v-model="content" class="content" :hpml="hpml"/>
 
-				<MkButton v-if="!readonly" @click="add()"><i class="fas fa-plus"></i></MkButton>
+				<MkButton v-if="!readonly" @click="add()"><i class="ti ti-plus"></i></MkButton>
 			</div>
 		</div>
 
@@ -68,7 +68,7 @@
 					</template>
 				</XDraggable>
 
-				<MkButton v-if="!readonly" class="add" @click="addVariable()"><i class="fas fa-plus"></i></MkButton>
+				<MkButton v-if="!readonly" class="add" @click="addVariable()"><i class="ti ti-plus"></i></MkButton>
 			</div>
 		</div>
 
@@ -412,7 +412,7 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'settings',
 	title: i18n.ts._pages.pageSetting,
-	icon: 'fas fa-cog',
+	icon: 'ti ti-settings',
 }, {
 	key: 'contents',
 	title: i18n.ts._pages.contents,
@@ -424,7 +424,7 @@ const headerTabs = $computed(() => [{
 }, {
 	key: 'script',
 	title: i18n.ts.script,
-	icon: 'fas fa-code',
+	icon: 'ti ti-code',
 }]);
 
 definePageMetadata(computed(() => {
@@ -437,7 +437,7 @@ definePageMetadata(computed(() => {
 	}
 	return {
 		title: title,
-		icon: 'fas fa-pencil-alt',
+		icon: 'ti ti-pencil',
 		};
 }));
 </script>
diff --git a/packages/client/src/pages/page.vue b/packages/client/src/pages/page.vue
index fb0e6a4914..5a37df64d3 100644
--- a/packages/client/src/pages/page.vue
+++ b/packages/client/src/pages/page.vue
@@ -18,12 +18,12 @@
 					</div>
 					<div class="actions">
 						<div class="like">
-							<MkButton v-if="page.isLiked" v-tooltip="i18n.ts._pages.unlike" class="button" primary @click="unlike()"><i class="fas fa-heart"></i><span v-if="page.likedCount > 0" class="count">{{ page.likedCount }}</span></MkButton>
+							<MkButton v-if="page.isLiked" v-tooltip="i18n.ts._pages.unlike" class="button" primary @click="unlike()"><i class="ti ti-heart"></i><span v-if="page.likedCount > 0" class="count">{{ page.likedCount }}</span></MkButton>
 							<MkButton v-else v-tooltip="i18n.ts._pages.like" class="button" @click="like()"><i class="far fa-heart"></i><span v-if="page.likedCount > 0" class="count">{{ page.likedCount }}</span></MkButton>
 						</div>
 						<div class="other">
-							<button v-tooltip="i18n.ts.shareWithNote" v-click-anime class="_button" @click="shareWithNote"><i class="fas fa-retweet fa-fw"></i></button>
-							<button v-tooltip="i18n.ts.share" v-click-anime class="_button" @click="share"><i class="fas fa-share-alt fa-fw"></i></button>
+							<button v-tooltip="i18n.ts.shareWithNote" v-click-anime class="_button" @click="shareWithNote"><i class="ti ti-repeat ti-fw"></i></button>
+							<button v-tooltip="i18n.ts.share" v-click-anime class="_button" @click="share"><i class="ti ti-share ti-fw"></i></button>
 						</div>
 					</div>
 					<div class="user">
@@ -49,7 +49,7 @@
 				</div>
 				<MkAd :prefer="['horizontal', 'horizontal-big']"/>
 				<MkContainer :max-height="300" :foldable="true" class="other">
-					<template #header><i class="fas fa-clock"></i> {{ i18n.ts.recentPosts }}</template>
+					<template #header><i class="ti ti-clock"></i> {{ i18n.ts.recentPosts }}</template>
 					<MkPagination v-slot="{items}" :pagination="otherPostsPagination">
 						<MkPagePreview v-for="page in items" :key="page.id" :page="page" class="_gap"/>
 					</MkPagination>
diff --git a/packages/client/src/pages/pages.vue b/packages/client/src/pages/pages.vue
index 02b05c57ba..53e65c82a4 100644
--- a/packages/client/src/pages/pages.vue
+++ b/packages/client/src/pages/pages.vue
@@ -9,7 +9,7 @@
 		</div>
 
 		<div v-else-if="tab === 'my'" class="rknalgpo my">
-			<MkButton class="new" @click="create()"><i class="fas fa-plus"></i></MkButton>
+			<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
 			<MkPagination v-slot="{items}" :pagination="myPagesPagination">
 				<MkPagePreview v-for="page in items" :key="page.id" class="ckltabjg" :page="page"/>
 			</MkPagination>
@@ -55,7 +55,7 @@ function create() {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'fas fa-plus',
+	icon: 'ti ti-plus',
 	text: i18n.ts.create,
 	handler: create,
 }]);
@@ -67,11 +67,11 @@ const headerTabs = $computed(() => [{
 }, {
 	key: 'my',
 	title: i18n.ts._pages.my,
-	icon: 'fas fa-edit',
+	icon: 'ti ti-edit',
 }, {
 	key: 'liked',
 	title: i18n.ts._pages.liked,
-	icon: 'fas fa-heart',
+	icon: 'ti ti-heart',
 }]);
 
 definePageMetadata(computed(() => ({
diff --git a/packages/client/src/pages/preview.vue b/packages/client/src/pages/preview.vue
index efbe53a523..354f686e46 100644
--- a/packages/client/src/pages/preview.vue
+++ b/packages/client/src/pages/preview.vue
@@ -16,7 +16,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.preview,
-	icon: 'fas fa-eye',
+	icon: 'ti ti-eye',
 })));
 </script>
 
diff --git a/packages/client/src/pages/registry.keys.vue b/packages/client/src/pages/registry.keys.vue
index ac586b4e72..f179fbe957 100644
--- a/packages/client/src/pages/registry.keys.vue
+++ b/packages/client/src/pages/registry.keys.vue
@@ -88,7 +88,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.registry,
-	icon: 'fas fa-cogs',
+	icon: 'ti ti-adjustments',
 });
 </script>
 
diff --git a/packages/client/src/pages/registry.value.vue b/packages/client/src/pages/registry.value.vue
index b6f3d73bb6..378420b1ba 100644
--- a/packages/client/src/pages/registry.value.vue
+++ b/packages/client/src/pages/registry.value.vue
@@ -24,14 +24,14 @@
 				<template #label>{{ i18n.ts.value }} (JSON)</template>
 			</FormTextarea>
 
-			<MkButton class="_formBlock" primary @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
+			<MkButton class="_formBlock" primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 
 			<MkKeyValue class="_formBlock">
 				<template #key>{{ i18n.ts.updatedAt }}</template>
 				<template #value><MkTime :time="value.updatedAt" mode="detail"/></template>
 			</MkKeyValue>
 
-			<MkButton danger @click="del"><i class="fas fa-trash"></i> {{ i18n.ts.delete }}</MkButton>
+			<MkButton danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
 		</template>
 	</MkSpacer>
 </MkStickyContainer>
@@ -115,7 +115,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.registry,
-	icon: 'fas fa-cogs',
+	icon: 'ti ti-adjustments',
 });
 </script>
 
diff --git a/packages/client/src/pages/registry.vue b/packages/client/src/pages/registry.vue
index 80a44d5589..a2c65294fc 100644
--- a/packages/client/src/pages/registry.vue
+++ b/packages/client/src/pages/registry.vue
@@ -66,7 +66,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.registry,
-	icon: 'fas fa-cogs',
+	icon: 'ti ti-adjustments',
 });
 </script>
 
diff --git a/packages/client/src/pages/reset-password.vue b/packages/client/src/pages/reset-password.vue
index 38f2cf289d..8ec15f6425 100644
--- a/packages/client/src/pages/reset-password.vue
+++ b/packages/client/src/pages/reset-password.vue
@@ -4,7 +4,7 @@
 	<MkSpacer v-if="token" :content-max="700" :margin-min="16" :margin-max="32">
 		<div class="_formRoot">
 			<FormInput v-model="password" type="password" class="_formBlock">
-				<template #prefix><i class="fas fa-lock"></i></template>
+				<template #prefix><i class="ti ti-lock"></i></template>
 				<template #label>{{ i18n.ts.newPassword }}</template>
 			</FormInput>
 		
@@ -50,7 +50,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.resetPassword,
-	icon: 'fas fa-lock',
+	icon: 'ti ti-lock',
 });
 </script>
 
diff --git a/packages/client/src/pages/scratchpad.vue b/packages/client/src/pages/scratchpad.vue
index 12b5d78b27..edb2d8e18c 100644
--- a/packages/client/src/pages/scratchpad.vue
+++ b/packages/client/src/pages/scratchpad.vue
@@ -2,7 +2,7 @@
 <div class="iltifgqe">
 	<div class="editor _panel _gap">
 		<PrismEditor v-model="code" class="_code code" :highlight="highlighter" :line-numbers="false"/>
-		<MkButton style="position: absolute; top: 8px; right: 8px;" primary @click="run()"><i class="fas fa-play"></i></MkButton>
+		<MkButton style="position: absolute; top: 8px; right: 8px;" primary @click="run()"><i class="ti ti-player-play"></i></MkButton>
 	</div>
 
 	<MkContainer :foldable="true" class="_gap">
@@ -112,7 +112,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.scratchpad,
-	icon: 'fas fa-terminal',
+	icon: 'ti ti-terminal-2',
 });
 </script>
 
diff --git a/packages/client/src/pages/search.vue b/packages/client/src/pages/search.vue
index fdcbb57e44..c080b763bb 100644
--- a/packages/client/src/pages/search.vue
+++ b/packages/client/src/pages/search.vue
@@ -33,6 +33,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.t('searchWith', { q: props.query }),
-	icon: 'fas fa-search',
+	icon: 'ti ti-search',
 })));
 </script>
diff --git a/packages/client/src/pages/settings/2fa.vue b/packages/client/src/pages/settings/2fa.vue
index 89d8178dc6..422b55e227 100644
--- a/packages/client/src/pages/settings/2fa.vue
+++ b/packages/client/src/pages/settings/2fa.vue
@@ -26,7 +26,7 @@
 			<ol v-if="registration && !registration.error">
 				<li v-if="registration.stage >= 0">
 					{{ i18n.ts.tapSecurityKey }}
-					<i v-if="registration.saving && registration.stage == 0" class="fas fa-spinner fa-pulse fa-fw"></i>
+					<i v-if="registration.saving && registration.stage == 0" class="fas fa-spinner fa-pulse ti-fw"></i>
 				</li>
 				<li v-if="registration.stage >= 1">
 					<MkForm :disabled="registration.stage != 1 || registration.saving">
@@ -34,7 +34,7 @@
 							<template #label>{{ i18n.ts.securityKeyName }}</template>
 						</MkInput>
 						<MkButton :disabled="keyName.length == 0" @click="registerKey">{{ i18n.ts.registerSecurityKey }}</MkButton>
-						<i v-if="registration.saving && registration.stage == 1" class="fas fa-spinner fa-pulse fa-fw"></i>
+						<i v-if="registration.saving && registration.stage == 1" class="fas fa-spinner fa-pulse ti-fw"></i>
 					</MkForm>
 				</li>
 			</ol>
diff --git a/packages/client/src/pages/settings/account-info.vue b/packages/client/src/pages/settings/account-info.vue
index 93e65d55b1..ccd99c162a 100644
--- a/packages/client/src/pages/settings/account-info.vue
+++ b/packages/client/src/pages/settings/account-info.vue
@@ -153,6 +153,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.accountInfo,
-	icon: 'fas fa-info-circle',
+	icon: 'ti ti-info-circle',
 });
 </script>
diff --git a/packages/client/src/pages/settings/accounts.vue b/packages/client/src/pages/settings/accounts.vue
index e16931a9ca..a2b7de81af 100644
--- a/packages/client/src/pages/settings/accounts.vue
+++ b/packages/client/src/pages/settings/accounts.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="_formRoot">
 	<FormSuspense :p="init">
-		<FormButton primary @click="addAccount"><i class="fas fa-plus"></i> {{ i18n.ts.addAccount }}</FormButton>
+		<FormButton primary @click="addAccount"><i class="ti ti-plus"></i> {{ i18n.ts.addAccount }}</FormButton>
 
 		<div v-for="account in accounts" :key="account.id" class="_panel _button lcjjdxlm" @click="menu(account, $event)">
 			<div class="avatar">
@@ -54,7 +54,7 @@ function menu(account, ev) {
 		action: () => switchAccount(account),
 	}, {
 		text: i18n.ts.remove,
-		icon: 'fas fa-trash-alt',
+		icon: 'ti ti-trash',
 		danger: true,
 		action: () => removeAccount(account),
 	}], ev.currentTarget ?? ev.target);
@@ -108,7 +108,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.accounts,
-	icon: 'fas fa-users',
+	icon: 'ti ti-users',
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/api.vue b/packages/client/src/pages/settings/api.vue
index 7165089e39..8d7291cd10 100644
--- a/packages/client/src/pages/settings/api.vue
+++ b/packages/client/src/pages/settings/api.vue
@@ -41,6 +41,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'API',
-	icon: 'fas fa-key',
+	icon: 'ti ti-api',
 });
 </script>
diff --git a/packages/client/src/pages/settings/apps.vue b/packages/client/src/pages/settings/apps.vue
index 8b345c8e9f..05abadff23 100644
--- a/packages/client/src/pages/settings/apps.vue
+++ b/packages/client/src/pages/settings/apps.vue
@@ -22,7 +22,7 @@
 						<div><MkTime :time="token.lastUsedAt"/></div>
 					</div>
 					<div class="actions">
-						<button class="_button" @click="revoke(token)"><i class="fas fa-trash-alt"></i></button>
+						<button class="_button" @click="revoke(token)"><i class="ti ti-trash"></i></button>
 					</div>
 					<details>
 						<summary>{{ i18n.ts.details }}</summary>
@@ -66,7 +66,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.installedApps,
-	icon: 'fas fa-plug',
+	icon: 'ti ti-plug',
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/custom-css.vue b/packages/client/src/pages/settings/custom-css.vue
index 2992906e6d..2caad22b7b 100644
--- a/packages/client/src/pages/settings/custom-css.vue
+++ b/packages/client/src/pages/settings/custom-css.vue
@@ -41,6 +41,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.customCss,
-	icon: 'fas fa-code',
+	icon: 'ti ti-code',
 });
 </script>
diff --git a/packages/client/src/pages/settings/deck.vue b/packages/client/src/pages/settings/deck.vue
index 1285a6641c..82cefe05d5 100644
--- a/packages/client/src/pages/settings/deck.vue
+++ b/packages/client/src/pages/settings/deck.vue
@@ -34,6 +34,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.deck,
-	icon: 'fas fa-columns',
+	icon: 'ti ti-columns',
 });
 </script>
diff --git a/packages/client/src/pages/settings/delete-account.vue b/packages/client/src/pages/settings/delete-account.vue
index 851a857fed..8a25ff39f0 100644
--- a/packages/client/src/pages/settings/delete-account.vue
+++ b/packages/client/src/pages/settings/delete-account.vue
@@ -47,6 +47,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts._accountDelete.accountDelete,
-	icon: 'fas fa-exclamation-triangle',
+	icon: 'ti ti-alert-triangle',
 });
 </script>
diff --git a/packages/client/src/pages/settings/drive.vue b/packages/client/src/pages/settings/drive.vue
index a10e2d9f7d..ed44509774 100644
--- a/packages/client/src/pages/settings/drive.vue
+++ b/packages/client/src/pages/settings/drive.vue
@@ -120,7 +120,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.drive,
-	icon: 'fas fa-cloud',
+	icon: 'ti ti-cloud',
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/email.vue b/packages/client/src/pages/settings/email.vue
index 1dae233a07..d4a6dc48e5 100644
--- a/packages/client/src/pages/settings/email.vue
+++ b/packages/client/src/pages/settings/email.vue
@@ -3,9 +3,9 @@
 	<FormSection>
 		<template #label>{{ i18n.ts.emailAddress }}</template>
 		<FormInput v-model="emailAddress" type="email" manual-save>
-			<template #prefix><i class="fas fa-envelope"></i></template>
+			<template #prefix><i class="ti ti-mail"></i></template>
 			<template v-if="$i.email && !$i.emailVerified" #caption>{{ i18n.ts.verificationEmailSent }}</template>
-			<template v-else-if="emailAddress === $i.email && $i.emailVerified" #caption><i class="fas fa-check" style="color: var(--success);"></i> {{ i18n.ts.emailVerified }}</template>
+			<template v-else-if="emailAddress === $i.email && $i.emailVerified" #caption><i class="ti ti-check" style="color: var(--success);"></i> {{ i18n.ts.emailVerified }}</template>
 		</FormInput>
 	</FormSection>
 
@@ -106,6 +106,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.email,
-	icon: 'fas fa-envelope',
+	icon: 'ti ti-mail',
 });
 </script>
diff --git a/packages/client/src/pages/settings/general.vue b/packages/client/src/pages/settings/general.vue
index 9072bcefc9..e4dbde0220 100644
--- a/packages/client/src/pages/settings/general.vue
+++ b/packages/client/src/pages/settings/general.vue
@@ -15,9 +15,9 @@
 	<FormRadios v-model="overridedDeviceKind" class="_formBlock">
 		<template #label>{{ i18n.ts.overridedDeviceKind }}</template>
 		<option :value="null">{{ i18n.ts.auto }}</option>
-		<option value="smartphone"><i class="fas fa-mobile-alt"/> {{ i18n.ts.smartphone }}</option>
-		<option value="tablet"><i class="fas fa-tablet-alt"/> {{ i18n.ts.tablet }}</option>
-		<option value="desktop"><i class="fas fa-desktop"/> {{ i18n.ts.desktop }}</option>
+		<option value="smartphone"><i class="ti ti-device-mobile"/> {{ i18n.ts.smartphone }}</option>
+		<option value="tablet"><i class="ti ti-device-tablet"/> {{ i18n.ts.tablet }}</option>
+		<option value="desktop"><i class="ti ti-device-desktop"/> {{ i18n.ts.desktop }}</option>
 	</FormRadios>
 
 	<FormSwitch v-model="showFixedPostForm" class="_formBlock">{{ i18n.ts.showFixedPostForm }}</FormSwitch>
@@ -88,7 +88,7 @@
 
 	<FormLink to="/settings/deck" class="_formBlock">{{ i18n.ts.deck }}</FormLink>
 
-	<FormLink to="/settings/custom-css" class="_formBlock"><template #icon><i class="fas fa-code"></i></template>{{ i18n.ts.customCss }}</FormLink>
+	<FormLink to="/settings/custom-css" class="_formBlock"><template #icon><i class="ti ti-code"></i></template>{{ i18n.ts.customCss }}</FormLink>
 </div>
 </template>
 
@@ -185,6 +185,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.general,
-	icon: 'fas fa-cogs',
+	icon: 'ti ti-adjustments',
 });
 </script>
diff --git a/packages/client/src/pages/settings/import-export.vue b/packages/client/src/pages/settings/import-export.vue
index d3d155894e..68460cf7ad 100644
--- a/packages/client/src/pages/settings/import-export.vue
+++ b/packages/client/src/pages/settings/import-export.vue
@@ -4,66 +4,66 @@
 		<template #label>{{ i18n.ts._exportOrImport.allNotes }}</template>
 		<FormFolder>
 			<template #label>{{ i18n.ts.export }}</template>
-			<template #icon><i class="fas fa-download"></i></template>
-			<MkButton primary :class="$style.button" inline @click="exportNotes()"><i class="fas fa-download"></i> {{ i18n.ts.export }}</MkButton>
+			<template #icon><i class="ti ti-download"></i></template>
+			<MkButton primary :class="$style.button" inline @click="exportNotes()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
 		</FormFolder>
 	</FormSection>
 	<FormSection>
 		<template #label>{{ i18n.ts._exportOrImport.followingList }}</template>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.export }}</template>
-			<template #icon><i class="fas fa-download"></i></template>
+			<template #icon><i class="ti ti-download"></i></template>
 			<FormSwitch v-model="excludeMutingUsers" class="_formBlock">
 				{{ i18n.ts._exportOrImport.excludeMutingUsers }}
 			</FormSwitch>
 			<FormSwitch v-model="excludeInactiveUsers" class="_formBlock">
 				{{ i18n.ts._exportOrImport.excludeInactiveUsers }}
 			</FormSwitch>
-			<MkButton primary :class="$style.button" inline @click="exportFollowing()"><i class="fas fa-download"></i> {{ i18n.ts.export }}</MkButton>
+			<MkButton primary :class="$style.button" inline @click="exportFollowing()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
 		</FormFolder>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.import }}</template>
-			<template #icon><i class="fas fa-upload"></i></template>
-			<MkButton primary :class="$style.button" inline @click="importFollowing($event)"><i class="fas fa-upload"></i> {{ i18n.ts.import }}</MkButton>
+			<template #icon><i class="ti ti-upload"></i></template>
+			<MkButton primary :class="$style.button" inline @click="importFollowing($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
 		</FormFolder>
 	</FormSection>
 	<FormSection>
 		<template #label>{{ i18n.ts._exportOrImport.userLists }}</template>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.export }}</template>
-			<template #icon><i class="fas fa-download"></i></template>
-			<MkButton primary :class="$style.button" inline @click="exportUserLists()"><i class="fas fa-download"></i> {{ i18n.ts.export }}</MkButton>
+			<template #icon><i class="ti ti-download"></i></template>
+			<MkButton primary :class="$style.button" inline @click="exportUserLists()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
 		</FormFolder>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.import }}</template>
-			<template #icon><i class="fas fa-upload"></i></template>
-			<MkButton primary :class="$style.button" inline @click="importUserLists($event)"><i class="fas fa-upload"></i> {{ i18n.ts.import }}</MkButton>
+			<template #icon><i class="ti ti-upload"></i></template>
+			<MkButton primary :class="$style.button" inline @click="importUserLists($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
 		</FormFolder>
 	</FormSection>
 	<FormSection>
 		<template #label>{{ i18n.ts._exportOrImport.muteList }}</template>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.export }}</template>
-			<template #icon><i class="fas fa-download"></i></template>
-			<MkButton primary :class="$style.button" inline @click="exportMuting()"><i class="fas fa-download"></i> {{ i18n.ts.export }}</MkButton>
+			<template #icon><i class="ti ti-download"></i></template>
+			<MkButton primary :class="$style.button" inline @click="exportMuting()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
 		</FormFolder>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.import }}</template>
-			<template #icon><i class="fas fa-upload"></i></template>
-			<MkButton primary :class="$style.button" inline @click="importMuting($event)"><i class="fas fa-upload"></i> {{ i18n.ts.import }}</MkButton>
+			<template #icon><i class="ti ti-upload"></i></template>
+			<MkButton primary :class="$style.button" inline @click="importMuting($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
 		</FormFolder>
 	</FormSection>
 	<FormSection>
 		<template #label>{{ i18n.ts._exportOrImport.blockingList }}</template>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.export }}</template>
-			<template #icon><i class="fas fa-download"></i></template>
-			<MkButton primary :class="$style.button" inline @click="exportBlocking()"><i class="fas fa-download"></i> {{ i18n.ts.export }}</MkButton>
+			<template #icon><i class="ti ti-download"></i></template>
+			<MkButton primary :class="$style.button" inline @click="exportBlocking()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
 		</FormFolder>
 		<FormFolder class="_formBlock">
 			<template #label>{{ i18n.ts.import }}</template>
-			<template #icon><i class="fas fa-upload"></i></template>
-			<MkButton primary :class="$style.button" inline @click="importBlocking($event)"><i class="fas fa-upload"></i> {{ i18n.ts.import }}</MkButton>
+			<template #icon><i class="ti ti-upload"></i></template>
+			<MkButton primary :class="$style.button" inline @click="importBlocking($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
 		</FormFolder>
 	</FormSection>
 </div>
@@ -113,7 +113,7 @@ const exportFollowing = () => {
 		excludeMuting: excludeMutingUsers.value,
 		excludeInactive: excludeInactiveUsers.value,
 	})
-	.then(onExportSuccess).catch(onError);
+		.then(onExportSuccess).catch(onError);
 };
 
 const exportBlocking = () => {
diff --git a/packages/client/src/pages/settings/index.vue b/packages/client/src/pages/settings/index.vue
index c38e1394f0..5c9d8a8efd 100644
--- a/packages/client/src/pages/settings/index.vue
+++ b/packages/client/src/pages/settings/index.vue
@@ -36,7 +36,7 @@ import * as os from '@/os';
 
 const indexInfo = {
 	title: i18n.ts.settings,
-	icon: 'fas fa-cog',
+	icon: 'ti ti-settings',
 	hideHeader: true,
 };
 const INFO = ref(indexInfo);
@@ -58,42 +58,42 @@ const ro = new ResizeObserver((entries, observer) => {
 const menuDef = computed(() => [{
 	title: i18n.ts.basicSettings,
 	items: [{
-		icon: 'fas fa-user',
+		icon: 'ti ti-user',
 		text: i18n.ts.profile,
 		to: '/settings/profile',
 		active: currentPage?.route.name === 'profile',
 	}, {
-		icon: 'fas fa-lock-open',
+		icon: 'ti ti-lock-open',
 		text: i18n.ts.privacy,
 		to: '/settings/privacy',
 		active: currentPage?.route.name === 'privacy',
 	}, {
-		icon: 'fas fa-laugh',
+		icon: 'ti ti-mood-happy',
 		text: i18n.ts.reaction,
 		to: '/settings/reaction',
 		active: currentPage?.route.name === 'reaction',
 	}, {
-		icon: 'fas fa-cloud',
+		icon: 'ti ti-cloud',
 		text: i18n.ts.drive,
 		to: '/settings/drive',
 		active: currentPage?.route.name === 'drive',
 	}, {
-		icon: 'fas fa-bell',
+		icon: 'ti ti-bell',
 		text: i18n.ts.notifications,
 		to: '/settings/notifications',
 		active: currentPage?.route.name === 'notifications',
 	}, {
-		icon: 'fas fa-envelope',
+		icon: 'ti ti-mail',
 		text: i18n.ts.email,
 		to: '/settings/email',
 		active: currentPage?.route.name === 'email',
 	}, {
-		icon: 'fas fa-share-alt',
+		icon: 'ti ti-share',
 		text: i18n.ts.integration,
 		to: '/settings/integration',
 		active: currentPage?.route.name === 'integration',
 	}, {
-		icon: 'fas fa-lock',
+		icon: 'ti ti-lock',
 		text: i18n.ts.security,
 		to: '/settings/security',
 		active: currentPage?.route.name === 'security',
@@ -101,32 +101,32 @@ const menuDef = computed(() => [{
 }, {
 	title: i18n.ts.clientSettings,
 	items: [{
-		icon: 'fas fa-cogs',
+		icon: 'ti ti-adjustments',
 		text: i18n.ts.general,
 		to: '/settings/general',
 		active: currentPage?.route.name === 'general',
 	}, {
-		icon: 'fas fa-palette',
+		icon: 'ti ti-palette',
 		text: i18n.ts.theme,
 		to: '/settings/theme',
 		active: currentPage?.route.name === 'theme',
 	}, {
-		icon: 'fas fa-bars',
+		icon: 'ti ti-menu-2',
 		text: i18n.ts.navbar,
 		to: '/settings/navbar',
 		active: currentPage?.route.name === 'navbar',
 	}, {
-		icon: 'fas fa-bars-progress',
+		icon: 'ti ti-equal-double',
 		text: i18n.ts.statusbar,
 		to: '/settings/statusbar',
 		active: currentPage?.route.name === 'statusbar',
 	}, {
-		icon: 'fas fa-music',
+		icon: 'ti ti-music',
 		text: i18n.ts.sounds,
 		to: '/settings/sounds',
 		active: currentPage?.route.name === 'sounds',
 	}, {
-		icon: 'fas fa-plug',
+		icon: 'ti ti-plug',
 		text: i18n.ts.plugins,
 		to: '/settings/plugin',
 		active: currentPage?.route.name === 'plugin',
@@ -134,50 +134,50 @@ const menuDef = computed(() => [{
 }, {
 	title: i18n.ts.otherSettings,
 	items: [{
-		icon: 'fas fa-boxes',
+		icon: 'ti ti-package',
 		text: i18n.ts.importAndExport,
 		to: '/settings/import-export',
 		active: currentPage?.route.name === 'import-export',
 	}, {
-		icon: 'fas fa-volume-mute',
+		icon: 'ti ti-planet-off',
 		text: i18n.ts.instanceMute,
 		to: '/settings/instance-mute',
 		active: currentPage?.route.name === 'instance-mute',
 	}, {
-		icon: 'fas fa-ban',
+		icon: 'ti ti-ban',
 		text: i18n.ts.muteAndBlock,
 		to: '/settings/mute-block',
 		active: currentPage?.route.name === 'mute-block',
 	}, {
-		icon: 'fas fa-comment-slash',
+		icon: 'ti ti-message-off',
 		text: i18n.ts.wordMute,
 		to: '/settings/word-mute',
 		active: currentPage?.route.name === 'word-mute',
 	}, {
-		icon: 'fas fa-key',
+		icon: 'ti ti-api',
 		text: 'API',
 		to: '/settings/api',
 		active: currentPage?.route.name === 'api',
 	}, {
-		icon: 'fas fa-bolt',
+		icon: 'ti ti-webhook',
 		text: 'Webhook',
 		to: '/settings/webhook',
 		active: currentPage?.route.name === 'webhook',
 	}, {
-		icon: 'fas fa-ellipsis-h',
+		icon: 'ti ti-dots',
 		text: i18n.ts.other,
 		to: '/settings/other',
 		active: currentPage?.route.name === 'other',
 	}],
 }, {
 	items: [{
-		icon: 'fas fa-floppy-disk',
+		icon: 'ti ti-device-floppy',
 		text: i18n.ts.preferencesBackups,
 		to: '/settings/preferences-backups',
 		active: currentPage?.route.name === 'preferences-backups',
 	}, {
 		type: 'button',
-		icon: 'fas fa-trash',
+		icon: 'ti ti-trash',
 		text: i18n.ts.clearCache,
 		action: () => {
 			localStorage.removeItem('locale');
@@ -186,7 +186,7 @@ const menuDef = computed(() => [{
 		},
 	}, {
 		type: 'button',
-		icon: 'fas fa-sign-in-alt fa-flip-horizontal',
+		icon: 'ti ti-logout',
 		text: i18n.ts.logout,
 		action: async () => {
 			const { canceled } = await os.confirm({
diff --git a/packages/client/src/pages/settings/instance-mute.vue b/packages/client/src/pages/settings/instance-mute.vue
index 5a0d48b82e..54504de188 100644
--- a/packages/client/src/pages/settings/instance-mute.vue
+++ b/packages/client/src/pages/settings/instance-mute.vue
@@ -5,7 +5,7 @@
 		<template #label>{{ i18n.ts._instanceMute.heading }}</template>
 		<template #caption>{{ i18n.ts._instanceMute.instanceMuteDescription }}<br>{{ i18n.ts._instanceMute.instanceMuteDescription2 }}</template>
 	</FormTextarea>
-	<MkButton primary :disabled="!changed" class="_formBlock" @click="save()"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton primary :disabled="!changed" class="_formBlock" @click="save()"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
@@ -48,6 +48,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.instanceMute,
-	icon: 'fas fa-volume-mute',
+	icon: 'ti ti-planet-off',
 });
 </script>
diff --git a/packages/client/src/pages/settings/integration.vue b/packages/client/src/pages/settings/integration.vue
index c8219519f8..f3595e897b 100644
--- a/packages/client/src/pages/settings/integration.vue
+++ b/packages/client/src/pages/settings/integration.vue
@@ -94,6 +94,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.integration,
-	icon: 'fas fa-share-alt',
+	icon: 'ti ti-share',
 });
 </script>
diff --git a/packages/client/src/pages/settings/mute-block.vue b/packages/client/src/pages/settings/mute-block.vue
index 3832933cf9..1cf33d34db 100644
--- a/packages/client/src/pages/settings/mute-block.vue
+++ b/packages/client/src/pages/settings/mute-block.vue
@@ -56,6 +56,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.muteAndBlock,
-	icon: 'fas fa-ban',
+	icon: 'ti ti-ban',
 });
 </script>
diff --git a/packages/client/src/pages/settings/navbar.vue b/packages/client/src/pages/settings/navbar.vue
index 6c501e9f2f..8825134dc9 100644
--- a/packages/client/src/pages/settings/navbar.vue
+++ b/packages/client/src/pages/settings/navbar.vue
@@ -82,6 +82,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.navbar,
-	icon: 'fas fa-list-ul',
+	icon: 'ti ti-list',
 });
 </script>
diff --git a/packages/client/src/pages/settings/notifications.vue b/packages/client/src/pages/settings/notifications.vue
index 77ec567da4..e24be99cb6 100644
--- a/packages/client/src/pages/settings/notifications.vue
+++ b/packages/client/src/pages/settings/notifications.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="_formRoot">
-	<FormLink class="_formBlock" @click="configure"><template #icon><i class="fas fa-cog"></i></template>{{ i18n.ts.notificationSetting }}</FormLink>
+	<FormLink class="_formBlock" @click="configure"><template #icon><i class="ti ti-settings"></i></template>{{ i18n.ts.notificationSetting }}</FormLink>
 	<FormSection>
 		<FormLink class="_formBlock" @click="readAllNotifications">{{ i18n.ts.markAsReadAllNotifications }}</FormLink>
 		<FormLink class="_formBlock" @click="readAllUnreadNotes">{{ i18n.ts.markAsReadAllUnreadNotes }}</FormLink>
@@ -85,6 +85,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.notifications,
-	icon: 'fas fa-bell',
+	icon: 'ti ti-bell',
 });
 </script>
diff --git a/packages/client/src/pages/settings/other.vue b/packages/client/src/pages/settings/other.vue
index 51dab04cfa..f8eb594740 100644
--- a/packages/client/src/pages/settings/other.vue
+++ b/packages/client/src/pages/settings/other.vue
@@ -10,9 +10,9 @@
 
 	<FormLink to="/settings/account-info" class="_formBlock">{{ i18n.ts.accountInfo }}</FormLink>
 
-	<FormLink to="/registry" class="_formBlock"><template #icon><i class="fas fa-cogs"></i></template>{{ i18n.ts.registry }}</FormLink>
+	<FormLink to="/registry" class="_formBlock"><template #icon><i class="ti ti-adjustments"></i></template>{{ i18n.ts.registry }}</FormLink>
 
-	<FormLink to="/settings/delete-account" class="_formBlock"><template #icon><i class="fas fa-exclamation-triangle"></i></template>{{ i18n.ts.closeAccount }}</FormLink>
+	<FormLink to="/settings/delete-account" class="_formBlock"><template #icon><i class="ti ti-alert-triangle"></i></template>{{ i18n.ts.closeAccount }}</FormLink>
 </div>
 </template>
 
@@ -42,6 +42,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.other,
-	icon: 'fas fa-ellipsis-h',
+	icon: 'ti ti-dots',
 });
 </script>
diff --git a/packages/client/src/pages/settings/plugin.install.vue b/packages/client/src/pages/settings/plugin.install.vue
index e259bbeb3a..550bba242e 100644
--- a/packages/client/src/pages/settings/plugin.install.vue
+++ b/packages/client/src/pages/settings/plugin.install.vue
@@ -7,7 +7,7 @@
 	</FormTextarea>
 
 	<div class="_formBlock">
-		<FormButton :disabled="code == null" primary inline @click="install"><i class="fas fa-check"></i> {{ i18n.ts.install }}</FormButton>
+		<FormButton :disabled="code == null" primary inline @click="install"><i class="ti ti-check"></i> {{ i18n.ts.install }}</FormButton>
 	</div>
 </div>
 </template>
@@ -119,6 +119,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts._plugin.install,
-	icon: 'fas fa-download',
+	icon: 'ti ti-download',
 });
 </script>
diff --git a/packages/client/src/pages/settings/plugin.vue b/packages/client/src/pages/settings/plugin.vue
index 8ce6fe4445..2e4d54ec5c 100644
--- a/packages/client/src/pages/settings/plugin.vue
+++ b/packages/client/src/pages/settings/plugin.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="_formRoot">
-	<FormLink to="/settings/plugin/install"><template #icon><i class="fas fa-download"></i></template>{{ i18n.ts._plugin.install }}</FormLink>
+	<FormLink to="/settings/plugin/install"><template #icon><i class="ti ti-download"></i></template>{{ i18n.ts._plugin.install }}</FormLink>
 
 	<FormSection>
 		<template #label>{{ i18n.ts.manage }}</template>
@@ -23,8 +23,8 @@
 			</MkKeyValue>
 
 			<div style="display: flex; gap: var(--margin); flex-wrap: wrap;">
-				<MkButton v-if="plugin.config" inline @click="config(plugin)"><i class="fas fa-cog"></i> {{ i18n.ts.settings }}</MkButton>
-				<MkButton inline danger @click="uninstall(plugin)"><i class="fas fa-trash-alt"></i> {{ i18n.ts.uninstall }}</MkButton>
+				<MkButton v-if="plugin.config" inline @click="config(plugin)"><i class="ti ti-settings"></i> {{ i18n.ts.settings }}</MkButton>
+				<MkButton inline danger @click="uninstall(plugin)"><i class="ti ti-trash"></i> {{ i18n.ts.uninstall }}</MkButton>
 			</div>
 		</div>
 	</FormSection>
@@ -89,7 +89,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.plugins,
-	icon: 'fas fa-plug',
+	icon: 'ti ti-plug',
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/preferences-backups.vue b/packages/client/src/pages/settings/preferences-backups.vue
index fac67185bc..379f65beff 100644
--- a/packages/client/src/pages/settings/preferences-backups.vue
+++ b/packages/client/src/pages/settings/preferences-backups.vue
@@ -376,25 +376,25 @@ function menu(ev: MouseEvent, profileId: string) {
 
 	return os.popupMenu([{
 		text: ts._preferencesBackups.apply,
-		icon: 'fas fa-circle-down',
+		icon: 'ti ti-check',
 		action: () => applyProfile(profileId),
 	}, {
 		type: 'a',
 		text: ts.download,
-		icon: 'fas fa-download',
+		icon: 'ti ti-download',
 		href: URL.createObjectURL(new Blob([JSON.stringify(profiles[profileId], null, 2)], { type: 'application/json' })),
 		download: `${profiles[profileId].name}.json`,
 	}, null, {
 		text: ts.rename,
-		icon: 'fas fa-i-cursor',
+		icon: 'ti ti-cursor-text',
 		action: () => rename(profileId),
 	}, {
 		text: ts._preferencesBackups.save,
-		icon: 'fas fa-floppy-disk',
+		icon: 'ti ti-device-floppy',
 		action: () => save(profileId),
 	}, null, {
 		text: ts._preferencesBackups.delete,
-		icon: 'fas fa-trash-can',
+		icon: 'ti ti-trash',
 		action: () => deleteProfile(profileId),
 		danger: true,
 	}], ev.currentTarget ?? ev.target);
@@ -416,7 +416,7 @@ onUnmounted(() => {
 
 definePageMetadata(computed(() => ({
 	title: ts.preferencesBackups,
-	icon: 'fas fa-floppy-disk',
+	icon: 'ti ti-device-floppy',
 	bg: 'var(--bg)',
 })));
 </script>
diff --git a/packages/client/src/pages/settings/privacy.vue b/packages/client/src/pages/settings/privacy.vue
index 45a0358a92..44ffae5446 100644
--- a/packages/client/src/pages/settings/privacy.vue
+++ b/packages/client/src/pages/settings/privacy.vue
@@ -95,6 +95,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.privacy,
-	icon: 'fas fa-lock-open',
+	icon: 'ti ti-lock-open',
 });
 </script>
diff --git a/packages/client/src/pages/settings/profile.vue b/packages/client/src/pages/settings/profile.vue
index aaf60c8d55..49e15456cf 100644
--- a/packages/client/src/pages/settings/profile.vue
+++ b/packages/client/src/pages/settings/profile.vue
@@ -46,8 +46,8 @@
 						<template #label>{{ i18n.ts._profile.metadataContent }} #{{ i + 1 }}</template>
 					</FormInput>
 				</FormSplit>
-				<MkButton :disabled="fields.length >= 16" inline style="margin-right: 8px;" @click="addField"><i class="fas fa-plus"></i> {{ i18n.ts.add }}</MkButton>
-				<MkButton inline primary @click="saveFields"><i class="fas fa-check"></i> {{ i18n.ts.save }}</MkButton>
+				<MkButton :disabled="fields.length >= 16" inline style="margin-right: 8px;" @click="addField"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
+				<MkButton inline primary @click="saveFields"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
 			</div>
 		</FormFolder>
 		<template #caption>{{ i18n.ts._profile.metadataDescription }}</template>
@@ -178,7 +178,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.profile,
-	icon: 'fas fa-user',
+	icon: 'ti ti-user',
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/reaction.vue b/packages/client/src/pages/settings/reaction.vue
index f8d57cbcd5..36e0718fbc 100644
--- a/packages/client/src/pages/settings/reaction.vue
+++ b/packages/client/src/pages/settings/reaction.vue
@@ -10,7 +10,7 @@
 					</button>
 				</template>
 				<template #footer>
-					<button class="_button add" @click="chooseEmoji"><i class="fas fa-plus"></i></button>
+					<button class="_button add" @click="chooseEmoji"><i class="ti ti-plus"></i></button>
 				</template>
 			</XDraggable>
 		</div>
@@ -46,7 +46,7 @@
 
 	<FormSection>
 		<div style="display: flex; gap: var(--margin); flex-wrap: wrap;">
-			<FormButton inline @click="preview"><i class="fas fa-eye"></i> {{ i18n.ts.preview }}</FormButton>
+			<FormButton inline @click="preview"><i class="ti ti-eye"></i> {{ i18n.ts.preview }}</FormButton>
 			<FormButton inline danger @click="setDefault"><i class="fas fa-undo"></i> {{ i18n.ts.default }}</FormButton>
 		</div>
 	</FormSection>
@@ -127,9 +127,9 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.reaction,
-	icon: 'fas fa-laugh',
+	icon: 'ti ti-mood-happy',
 	action: {
-		icon: 'fas fa-eye',
+		icon: 'ti ti-eye',
 		handler: preview,
 	},
 });
diff --git a/packages/client/src/pages/settings/security.vue b/packages/client/src/pages/settings/security.vue
index d109a4ba7c..b6fdd2356f 100644
--- a/packages/client/src/pages/settings/security.vue
+++ b/packages/client/src/pages/settings/security.vue
@@ -17,8 +17,8 @@
 				<div>
 					<div v-for="item in items" :key="item.id" v-panel class="timnmucd">
 						<header>
-							<i v-if="item.success" class="fas fa-check icon succ"></i>
-							<i v-else class="fas fa-times-circle icon fail"></i>
+							<i v-if="item.success" class="ti ti-check icon succ"></i>
+							<i v-else class="ti ti-circle-x icon fail"></i>
 							<code class="ip _monospace">{{ item.ip }}</code>
 							<MkTime :time="item.createdAt" class="time"/>
 						</header>
@@ -103,7 +103,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.security,
-	icon: 'fas fa-lock',
+	icon: 'ti ti-lock',
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/sounds.vue b/packages/client/src/pages/settings/sounds.vue
index 579b5fe829..1106f0c6bb 100644
--- a/packages/client/src/pages/settings/sounds.vue
+++ b/packages/client/src/pages/settings/sounds.vue
@@ -9,7 +9,7 @@
 		<FormLink v-for="type in Object.keys(sounds)" :key="type" style="margin-bottom: 8px;" @click="edit(type)">
 			{{ $t('_sfx.' + type) }}
 			<template #suffix>{{ sounds[type].type || i18n.ts.none }}</template>
-			<template #suffixIcon><i class="fas fa-chevron-down"></i></template>
+			<template #suffixIcon><i class="ti ti-chevron-down"></i></template>
 		</FormLink>
 	</FormSection>
 
@@ -135,6 +135,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.sounds,
-	icon: 'fas fa-music',
+	icon: 'ti ti-music',
 });
 </script>
diff --git a/packages/client/src/pages/settings/statusbar.vue b/packages/client/src/pages/settings/statusbar.vue
index 9dbf182142..86c69fa2c3 100644
--- a/packages/client/src/pages/settings/statusbar.vue
+++ b/packages/client/src/pages/settings/statusbar.vue
@@ -48,7 +48,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.statusbar,
-	icon: 'fas fa-list-ul',
+	icon: 'ti ti-list',
 	bg: 'var(--bg)',
 });
 </script>
diff --git a/packages/client/src/pages/settings/theme.install.vue b/packages/client/src/pages/settings/theme.install.vue
index 34f8384d87..52a436e18d 100644
--- a/packages/client/src/pages/settings/theme.install.vue
+++ b/packages/client/src/pages/settings/theme.install.vue
@@ -5,8 +5,8 @@
 	</FormTextarea>
 
 	<div class="_formBlock" style="display: flex; gap: var(--margin); flex-wrap: wrap;">
-		<FormButton :disabled="installThemeCode == null" inline @click="() => preview(installThemeCode)"><i class="fas fa-eye"></i> {{ i18n.ts.preview }}</FormButton>
-		<FormButton :disabled="installThemeCode == null" primary inline @click="() => install(installThemeCode)"><i class="fas fa-check"></i> {{ i18n.ts.install }}</FormButton>
+		<FormButton :disabled="installThemeCode == null" inline @click="() => preview(installThemeCode)"><i class="ti ti-eye"></i> {{ i18n.ts.preview }}</FormButton>
+		<FormButton :disabled="installThemeCode == null" primary inline @click="() => install(installThemeCode)"><i class="ti ti-check"></i> {{ i18n.ts.install }}</FormButton>
 	</div>
 </div>
 </template>
@@ -75,6 +75,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts._theme.install,
-	icon: 'fas fa-download',
+	icon: 'ti ti-download',
 });
 </script>
diff --git a/packages/client/src/pages/settings/theme.manage.vue b/packages/client/src/pages/settings/theme.manage.vue
index 25f92e6ed1..5b33b50319 100644
--- a/packages/client/src/pages/settings/theme.manage.vue
+++ b/packages/client/src/pages/settings/theme.manage.vue
@@ -20,7 +20,7 @@
 			<template #label>{{ i18n.ts._theme.code }}</template>
 			<template #caption><button class="_textButton" @click="copyThemeCode()">{{ i18n.ts.copy }}</button></template>
 		</FormTextarea>
-		<FormButton v-if="!builtinThemes.some(t => t.id == selectedTheme.id)" class="_formBlock" danger @click="uninstall()"><i class="fas fa-trash-alt"></i> {{ i18n.ts.uninstall }}</FormButton>
+		<FormButton v-if="!builtinThemes.some(t => t.id == selectedTheme.id)" class="_formBlock" danger @click="uninstall()"><i class="ti ti-trash"></i> {{ i18n.ts.uninstall }}</FormButton>
 	</template>
 </div>
 </template>
diff --git a/packages/client/src/pages/settings/theme.vue b/packages/client/src/pages/settings/theme.vue
index 42a91bcb59..f37c213b06 100644
--- a/packages/client/src/pages/settings/theme.vue
+++ b/packages/client/src/pages/settings/theme.vue
@@ -29,7 +29,7 @@
 	<div class="selects _formBlock">
 		<FormSelect v-model="lightThemeId" large class="select">
 			<template #label>{{ i18n.ts.themeForLightMode }}</template>
-			<template #prefix><i class="fas fa-sun"></i></template>
+			<template #prefix><i class="ti ti-sun"></i></template>
 			<option v-if="instanceLightTheme" :key="'instance:' + instanceLightTheme.id" :value="instanceLightTheme.id">{{ instanceLightTheme.name }}</option>
 			<optgroup v-if="installedLightThemes.length > 0" :label="i18n.ts._theme.installedThemes">
 				<option v-for="x in installedLightThemes" :key="'installed:' + x.id" :value="x.id">{{ x.name }}</option>
@@ -40,7 +40,7 @@
 		</FormSelect>
 		<FormSelect v-model="darkThemeId" large class="select">
 			<template #label>{{ i18n.ts.themeForDarkMode }}</template>
-			<template #prefix><i class="fas fa-moon"></i></template>
+			<template #prefix><i class="ti ti-moon"></i></template>
 			<option v-if="instanceDarkTheme" :key="'instance:' + instanceDarkTheme.id" :value="instanceDarkTheme.id">{{ instanceDarkTheme.name }}</option>
 			<optgroup v-if="installedDarkThemes.length > 0" :label="i18n.ts._theme.installedThemes">
 				<option v-for="x in installedDarkThemes" :key="'installed:' + x.id" :value="x.id">{{ x.name }}</option>
@@ -53,10 +53,10 @@
 
 	<FormSection>
 		<div class="_formLinksGrid">
-			<FormLink to="/settings/theme/manage"><template #icon><i class="fas fa-folder-open"></i></template>{{ i18n.ts._theme.manage }}<template #suffix>{{ themesCount }}</template></FormLink>
-			<FormLink to="https://assets.misskey.io/theme/list" external><template #icon><i class="fas fa-globe"></i></template>{{ i18n.ts._theme.explore }}</FormLink>
-			<FormLink to="/settings/theme/install"><template #icon><i class="fas fa-download"></i></template>{{ i18n.ts._theme.install }}</FormLink>
-			<FormLink to="/theme-editor"><template #icon><i class="fas fa-paint-roller"></i></template>{{ i18n.ts._theme.make }}</FormLink>
+			<FormLink to="/settings/theme/manage"><template #icon><i class="ti ti-tool"></i></template>{{ i18n.ts._theme.manage }}<template #suffix>{{ themesCount }}</template></FormLink>
+			<FormLink to="https://assets.misskey.io/theme/list" external><template #icon><i class="ti ti-world"></i></template>{{ i18n.ts._theme.explore }}</FormLink>
+			<FormLink to="/settings/theme/install"><template #icon><i class="ti ti-download"></i></template>{{ i18n.ts._theme.install }}</FormLink>
+			<FormLink to="/theme-editor"><template #icon><i class="ti ti-paint"></i></template>{{ i18n.ts._theme.make }}</FormLink>
 		</div>
 	</FormSection>
 
@@ -160,7 +160,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.theme,
-	icon: 'fas fa-palette',
+	icon: 'ti ti-palette',
 });
 </script>
 
diff --git a/packages/client/src/pages/settings/webhook.edit.vue b/packages/client/src/pages/settings/webhook.edit.vue
index 5d41f3d087..c8ec1ea586 100644
--- a/packages/client/src/pages/settings/webhook.edit.vue
+++ b/packages/client/src/pages/settings/webhook.edit.vue
@@ -9,7 +9,7 @@
 	</FormInput>
 
 	<FormInput v-model="secret" class="_formBlock">
-		<template #prefix><i class="fas fa-lock"></i></template>
+		<template #prefix><i class="ti ti-lock"></i></template>
 		<template #label>Secret</template>
 	</FormInput>
 
@@ -28,7 +28,7 @@
 	<FormSwitch v-model="active" class="_formBlock">Active</FormSwitch>
 
 	<div class="_formBlock" style="display: flex; gap: var(--margin); flex-wrap: wrap;">
-		<FormButton primary inline @click="save"><i class="fas fa-check"></i> {{ i18n.ts.save }}</FormButton>
+		<FormButton primary inline @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</FormButton>
 	</div>
 </div>
 </template>
@@ -90,6 +90,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'Edit webhook',
-	icon: 'fas fa-bolt',
+	icon: 'ti ti-webhook',
 });
 </script>
diff --git a/packages/client/src/pages/settings/webhook.new.vue b/packages/client/src/pages/settings/webhook.new.vue
index fcf1329ff6..00a547da69 100644
--- a/packages/client/src/pages/settings/webhook.new.vue
+++ b/packages/client/src/pages/settings/webhook.new.vue
@@ -9,7 +9,7 @@
 	</FormInput>
 
 	<FormInput v-model="secret" class="_formBlock">
-		<template #prefix><i class="fas fa-lock"></i></template>
+		<template #prefix><i class="ti ti-lock"></i></template>
 		<template #label>Secret</template>
 	</FormInput>
 
@@ -26,7 +26,7 @@
 	</FormSection>
 
 	<div class="_formBlock" style="display: flex; gap: var(--margin); flex-wrap: wrap;">
-		<FormButton primary inline @click="create"><i class="fas fa-check"></i> {{ i18n.ts.create }}</FormButton>
+		<FormButton primary inline @click="create"><i class="ti ti-check"></i> {{ i18n.ts.create }}</FormButton>
 	</div>
 </div>
 </template>
@@ -77,6 +77,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'Create new webhook',
-	icon: 'fas fa-bolt',
+	icon: 'ti ti-webhook',
 });
 </script>
diff --git a/packages/client/src/pages/settings/webhook.vue b/packages/client/src/pages/settings/webhook.vue
index 1a7e73940c..0e35be0f58 100644
--- a/packages/client/src/pages/settings/webhook.vue
+++ b/packages/client/src/pages/settings/webhook.vue
@@ -11,10 +11,10 @@
 			<template #default="{items}">
 				<FormLink v-for="webhook in items" :key="webhook.id" :to="`/settings/webhook/edit/${webhook.id}`" class="_formBlock">
 					<template #icon>
-						<i v-if="webhook.active === false" class="fas fa-circle-pause"></i>
+						<i v-if="webhook.active === false" class="ti ti-player-pause"></i>
 						<i v-else-if="webhook.latestStatus === null" class="far fa-circle"></i>
-						<i v-else-if="[200, 201, 204].includes(webhook.latestStatus)" class="fas fa-check" :style="{ color: 'var(--success)' }"></i>
-						<i v-else class="fas fa-triangle-exclamation" :style="{ color: 'var(--error)' }"></i>
+						<i v-else-if="[200, 201, 204].includes(webhook.latestStatus)" class="ti ti-check" :style="{ color: 'var(--success)' }"></i>
+						<i v-else class="ti ti-alert-triangle" :style="{ color: 'var(--error)' }"></i>
 					</template>
 					{{ webhook.name || webhook.url }}
 					<template #suffix>
@@ -48,6 +48,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'Webhook',
-	icon: 'fas fa-bolt',
+	icon: 'ti ti-webhook',
 });
 </script>
diff --git a/packages/client/src/pages/settings/word-mute.vue b/packages/client/src/pages/settings/word-mute.vue
index e297379568..6961d8151d 100644
--- a/packages/client/src/pages/settings/word-mute.vue
+++ b/packages/client/src/pages/settings/word-mute.vue
@@ -24,7 +24,7 @@
 			</MkKeyValue>
 		</div>
 	</div>
-	<MkButton primary inline :disabled="!changed" @click="save()"><i class="fas fa-save"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton primary inline :disabled="!changed" @click="save()"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
@@ -123,6 +123,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.wordMute,
-	icon: 'fas fa-comment-slash',
+	icon: 'ti ti-message-off',
 });
 </script>
diff --git a/packages/client/src/pages/share.vue b/packages/client/src/pages/share.vue
index 69d22ed632..a7e797eeab 100644
--- a/packages/client/src/pages/share.vue
+++ b/packages/client/src/pages/share.vue
@@ -158,7 +158,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.share,
-	icon: 'fas fa-share-alt',
+	icon: 'ti ti-share',
 });
 </script>
 
diff --git a/packages/client/src/pages/signup-complete.vue b/packages/client/src/pages/signup-complete.vue
index a97990c129..5459532310 100644
--- a/packages/client/src/pages/signup-complete.vue
+++ b/packages/client/src/pages/signup-complete.vue
@@ -32,7 +32,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.signup,
-	icon: 'fas fa-user',
+	icon: 'ti ti-user',
 });
 </script>
 
diff --git a/packages/client/src/pages/tag.vue b/packages/client/src/pages/tag.vue
index 5498c2999d..72775ed5c9 100644
--- a/packages/client/src/pages/tag.vue
+++ b/packages/client/src/pages/tag.vue
@@ -30,6 +30,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: props.tag,
-	icon: 'fas fa-hashtag',
+	icon: 'ti ti-hash',
 })));
 </script>
diff --git a/packages/client/src/pages/theme-editor.vue b/packages/client/src/pages/theme-editor.vue
index 7dfeee16ed..d8ff170ca2 100644
--- a/packages/client/src/pages/theme-editor.vue
+++ b/packages/client/src/pages/theme-editor.vue
@@ -42,7 +42,7 @@
 			</FormFolder>
 
 			<FormFolder :default-open="false" class="_formBlock">
-				<template #icon><i class="fas fa-code"></i></template>
+				<template #icon><i class="ti ti-code"></i></template>
 				<template #label>{{ i18n.ts.editCode }}</template>
 
 				<div class="_formRoot">
@@ -210,12 +210,12 @@ watch($$(theme), apply, { deep: true });
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'fas fa-eye',
+	icon: 'ti ti-eye',
 	text: i18n.ts.preview,
 	handler: showPreview,
 }, {
 	asFullButton: true,
-	icon: 'fas fa-check',
+	icon: 'ti ti-check',
 	text: i18n.ts.saveAs,
 	handler: saveAs,
 }]);
@@ -224,7 +224,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.themeEditor,
-	icon: 'fas fa-palette',
+	icon: 'ti ti-palette',
 });
 </script>
 
diff --git a/packages/client/src/pages/timeline.tutorial.vue b/packages/client/src/pages/timeline.tutorial.vue
index 9683cc22a5..ae7b098b90 100644
--- a/packages/client/src/pages/timeline.tutorial.vue
+++ b/packages/client/src/pages/timeline.tutorial.vue
@@ -1,14 +1,14 @@
 <template>
 <div class="_card">
 	<div :class="$style.title" class="_title">
-		<div :class="$style.titleText"><i class="fas fa-info-circle"></i> {{ i18n.ts._tutorial.title }}</div>
+		<div :class="$style.titleText"><i class="ti ti-info-circle"></i> {{ i18n.ts._tutorial.title }}</div>
 		<div :class="$style.step">
 			<button class="_button" :class="$style.stepArrow" :disabled="tutorial === 0" @click="tutorial--">
-				<i class="fas fa-chevron-left"></i>
+				<i class="ti ti-chevron-left"></i>
 			</button>
 			<span :class="$style.stepNumber">{{ tutorial + 1 }} / {{ tutorialsNumber }}</span>
 			<button class="_button" :class="$style.stepArrow" :disabled="tutorial === tutorialsNumber - 1" @click="tutorial++">
-				<i class="fas fa-chevron-right"></i>
+				<i class="ti ti-chevron-right"></i>
 			</button>
 		</div>
 	</div>
@@ -71,7 +71,7 @@
 			<MkButton :class="$style.footerItem" :primary="false" @click="tutorial = -1">{{ i18n.ts.noThankYou }}</MkButton>
 		</template>
 		<template v-else>
-			<MkButton :class="$style.footerItem" primary @click="tutorial++"><i class="fas fa-check"></i> {{ i18n.ts.next }}</MkButton>
+			<MkButton :class="$style.footerItem" primary @click="tutorial++"><i class="ti ti-check"></i> {{ i18n.ts.next }}</MkButton>
 		</template>
 	</div>
 </div>
diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue
index 9d42997025..1c9e389367 100644
--- a/packages/client/src/pages/timeline.vue
+++ b/packages/client/src/pages/timeline.vue
@@ -114,35 +114,35 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'home',
 	title: i18n.ts._timelines.home,
-	icon: 'fas fa-home',
+	icon: 'ti ti-home',
 	iconOnly: true,
 }, ...(isLocalTimelineAvailable ? [{
 	key: 'local',
 	title: i18n.ts._timelines.local,
-	icon: 'fas fa-comments',
+	icon: 'ti ti-messages',
 	iconOnly: true,
 }, {
 	key: 'social',
 	title: i18n.ts._timelines.social,
-	icon: 'fas fa-share-alt',
+	icon: 'ti ti-share',
 	iconOnly: true,
 }] : []), ...(isGlobalTimelineAvailable ? [{
 	key: 'global',
 	title: i18n.ts._timelines.global,
-	icon: 'fas fa-globe',
+	icon: 'ti ti-world',
 	iconOnly: true,
 }] : []), {
-	icon: 'fas fa-list-ul',
+	icon: 'ti ti-list',
 	title: i18n.ts.lists,
 	iconOnly: true,
 	onClick: chooseList,
 }, {
-	icon: 'fas fa-satellite',
+	icon: 'ti ti-antenna',
 	title: i18n.ts.antennas,
 	iconOnly: true,
 	onClick: chooseAntenna,
 }, {
-	icon: 'fas fa-satellite-dish',
+	icon: 'ti ti-device-tv',
 	title: i18n.ts.channel,
 	iconOnly: true,
 	onClick: chooseChannel,
@@ -150,7 +150,7 @@ const headerTabs = $computed(() => [{
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.timeline,
-	icon: src === 'local' ? 'fas fa-comments' : src === 'social' ? 'fas fa-share-alt' : src === 'global' ? 'fas fa-globe' : 'fas fa-home',
+	icon: src === 'local' ? 'ti ti-messages' : src === 'social' ? 'ti ti-share' : src === 'global' ? 'ti ti-world' : 'ti ti-home',
 })));
 </script>
 
diff --git a/packages/client/src/pages/user-info.vue b/packages/client/src/pages/user-info.vue
index d376f11c58..adb8350516 100644
--- a/packages/client/src/pages/user-info.vue
+++ b/packages/client/src/pages/user-info.vue
@@ -58,7 +58,7 @@
 					<div class="_formBlock">
 						<MkKeyValue v-if="user.host" oneline style="margin: 1em 0;">
 							<template #key>{{ i18n.ts.instanceInfo }}</template>
-							<template #value><MkA :to="`/instance-info/${user.host}`" class="_link">{{ user.host }} <i class="fas fa-angle-right"></i></MkA></template>
+							<template #value><MkA :to="`/instance-info/${user.host}`" class="_link">{{ user.host }} <i class="ti ti-chevron-right"></i></MkA></template>
 						</MkKeyValue>
 						<MkKeyValue v-else oneline style="margin: 1em 0;">
 							<template #key>{{ i18n.ts.instanceInfo }}</template>
@@ -74,7 +74,7 @@
 						</MkKeyValue>
 					</div>
 
-					<FormButton v-if="user.host != null" class="_formBlock" @click="updateRemoteUser"><i class="fas fa-sync"></i> {{ i18n.ts.updateRemoteUser }}</FormButton>
+					<FormButton v-if="user.host != null" class="_formBlock" @click="updateRemoteUser"><i class="ti ti-refresh"></i> {{ i18n.ts.updateRemoteUser }}</FormButton>
 
 					<FormFolder class="_formBlock">
 						<template #label>Raw</template>
@@ -90,7 +90,7 @@
 				<FormSwitch v-model="suspended" class="_formBlock" @update:modelValue="toggleSuspend">{{ i18n.ts.suspend }}</FormSwitch>
 				{{ i18n.ts.reflectMayTakeTime }}
 				<div class="_formBlock">
-					<FormButton v-if="user.host == null && iAmModerator" inline style="margin-right: 8px;" @click="resetPassword"><i class="fas fa-key"></i> {{ i18n.ts.resetPassword }}</FormButton>
+					<FormButton v-if="user.host == null && iAmModerator" inline style="margin-right: 8px;" @click="resetPassword"><i class="ti ti-key"></i> {{ i18n.ts.resetPassword }}</FormButton>
 					<FormButton v-if="$i.isAdmin" inline danger @click="deleteAccount">{{ i18n.ts.deleteAccount }}</FormButton>
 				</div>
 				<FormTextarea v-model="moderationNote" manual-save class="_formBlock">
@@ -364,24 +364,24 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'overview',
 	title: i18n.ts.overview,
-	icon: 'fas fa-info-circle',
+	icon: 'ti ti-info-circle',
 }, iAmModerator ? {
 	key: 'moderation',
 	title: i18n.ts.moderation,
-	icon: 'fas fa-shield-halved',
+	icon: 'ti ti-user-exclamation',
 } : null, {
 	key: 'chart',
 	title: i18n.ts.charts,
-	icon: 'fas fa-chart-simple',
+	icon: 'ti ti-chart-line',
 }, {
 	key: 'raw',
 	title: 'Raw',
-	icon: 'fas fa-code',
+	icon: 'ti ti-code',
 }].filter(x => x != null));
 
 definePageMetadata(computed(() => ({
 	title: user ? acct(user) : i18n.ts.userInfo,
-	icon: 'fas fa-info-circle',
+	icon: 'ti ti-info-circle',
 })));
 </script>
 
diff --git a/packages/client/src/pages/user-list-timeline.vue b/packages/client/src/pages/user-list-timeline.vue
index 4a534e47ba..aa5c078ab4 100644
--- a/packages/client/src/pages/user-list-timeline.vue
+++ b/packages/client/src/pages/user-list-timeline.vue
@@ -69,7 +69,7 @@ const headerActions = $computed(() => list ? [{
 	text: i18n.ts.jumpToSpecifiedDate,
 	handler: timetravel,
 }, {
-	icon: 'fas fa-cog',
+	icon: 'ti ti-settings',
 	text: i18n.ts.settings,
 	handler: settings,
 }] : []);
@@ -78,7 +78,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => list ? {
 	title: list.name,
-	icon: 'fas fa-list-ul',
+	icon: 'ti ti-list',
 } : null));
 </script>
 
diff --git a/packages/client/src/pages/user/followers.vue b/packages/client/src/pages/user/followers.vue
index b61b48329a..17c2843381 100644
--- a/packages/client/src/pages/user/followers.vue
+++ b/packages/client/src/pages/user/followers.vue
@@ -49,7 +49,7 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => user ? {
-	icon: 'fas fa-user',
+	icon: 'ti ti-user',
 	title: user.name ? `${user.name} (@${user.username})` : `@${user.username}`,
 	subtitle: i18n.ts.followers,
 	userName: user,
diff --git a/packages/client/src/pages/user/following.vue b/packages/client/src/pages/user/following.vue
index a23977b425..03892ec03d 100644
--- a/packages/client/src/pages/user/following.vue
+++ b/packages/client/src/pages/user/following.vue
@@ -49,7 +49,7 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => user ? {
-	icon: 'fas fa-user',
+	icon: 'ti ti-user',
 	title: user.name ? `${user.name} (@${user.username})` : `@${user.username}`,
 	subtitle: i18n.ts.following,
 	userName: user,
diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue
index 352db4616e..d3859a2612 100644
--- a/packages/client/src/pages/user/home.vue
+++ b/packages/client/src/pages/user/home.vue
@@ -3,8 +3,8 @@
 	<div ref="rootEl" v-size="{ max: [500] }" class="ftskorzw" :class="{ wide: !narrow }">
 		<div class="main">
 			<!-- TODO -->
-			<!-- <div class="punished" v-if="user.isSuspended"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i> {{ i18n.ts.userSuspended }}</div> -->
-			<!-- <div class="punished" v-if="user.isSilenced"><i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i> {{ i18n.ts.userSilenced }}</div> -->
+			<!-- <div class="punished" v-if="user.isSuspended"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i> {{ i18n.ts.userSuspended }}</div> -->
+			<!-- <div class="punished" v-if="user.isSilenced"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i> {{ i18n.ts.userSilenced }}</div> -->
 
 			<div class="profile">
 				<MkRemoteCaution v-if="user.host != null" :href="user.url" class="warn"/>
@@ -19,13 +19,13 @@
 								<span class="username"><MkAcct :user="user" :detail="true"/></span>
 								<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--badge);"><i class="fas fa-bookmark"></i></span>
 								<span v-if="!user.isAdmin && user.isModerator" :title="i18n.ts.isModerator" style="color: var(--badge);"><i class="far fa-bookmark"></i></span>
-								<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="fas fa-lock"></i></span>
+								<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="ti ti-lock"></i></span>
 								<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="fas fa-robot"></i></span>
 							</div>
 						</div>
 						<span v-if="$i && $i.id != user.id && user.isFollowed" class="followed">{{ i18n.ts.followsYou }}</span>
 						<div v-if="$i" class="actions">
-							<button class="menu _button" @click="menu"><i class="fas fa-ellipsis-h"></i></button>
+							<button class="menu _button" @click="menu"><i class="ti ti-dots"></i></button>
 							<MkFollowButton v-if="$i.id != user.id" :user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/>
 						</div>
 					</div>
@@ -36,7 +36,7 @@
 							<span class="username"><MkAcct :user="user" :detail="true"/></span>
 							<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--badge);"><i class="fas fa-bookmark"></i></span>
 							<span v-if="!user.isAdmin && user.isModerator" :title="i18n.ts.isModerator" style="color: var(--badge);"><i class="far fa-bookmark"></i></span>
-							<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="fas fa-lock"></i></span>
+							<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="ti ti-lock"></i></span>
 							<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="fas fa-robot"></i></span>
 						</div>
 					</div>
@@ -46,15 +46,15 @@
 					</div>
 					<div class="fields system">
 						<dl v-if="user.location" class="field">
-							<dt class="name"><i class="fas fa-map-marker fa-fw"></i> {{ i18n.ts.location }}</dt>
+							<dt class="name"><i class="fas fa-map-marker ti-fw"></i> {{ i18n.ts.location }}</dt>
 							<dd class="value">{{ user.location }}</dd>
 						</dl>
 						<dl v-if="user.birthday" class="field">
-							<dt class="name"><i class="fas fa-birthday-cake fa-fw"></i> {{ i18n.ts.birthday }}</dt>
+							<dt class="name"><i class="fas fa-birthday-cake ti-fw"></i> {{ i18n.ts.birthday }}</dt>
 							<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ $t('yearsOld', { age }) }})</dd>
 						</dl>
 						<dl class="field">
-							<dt class="name"><i class="fas fa-calendar-alt fa-fw"></i> {{ i18n.ts.registeredDate }}</dt>
+							<dt class="name"><i class="fas fa-calendar-alt ti-fw"></i> {{ i18n.ts.registeredDate }}</dt>
 							<dd class="value">{{ new Date(user.createdAt).toLocaleString() }} (<MkTime :time="user.createdAt"/>)</dd>
 						</dl>
 					</div>
diff --git a/packages/client/src/pages/user/index.activity.vue b/packages/client/src/pages/user/index.activity.vue
index 630a2cea7d..523072d2e6 100644
--- a/packages/client/src/pages/user/index.activity.vue
+++ b/packages/client/src/pages/user/index.activity.vue
@@ -1,9 +1,9 @@
 <template>
 <MkContainer>
-	<template #header><i class="fas fa-chart-simple" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template>
+	<template #header><i class="ti ti-chart-line" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template>
 	<template #func>
 		<button class="_button" @click="showMenu">
-			<i class="fas fa-ellipsis-h"></i>
+			<i class="ti ti-dots"></i>
 		</button>
 	</template>
 
diff --git a/packages/client/src/pages/user/index.vue b/packages/client/src/pages/user/index.vue
index 7e635f8b2e..48f2955283 100644
--- a/packages/client/src/pages/user/index.vue
+++ b/packages/client/src/pages/user/index.vue
@@ -69,15 +69,15 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => user ? [{
 	key: 'home',
 	title: i18n.ts.overview,
-	icon: 'fas fa-home',
+	icon: 'ti ti-home',
 }, ...($i && ($i.id === user.id)) || user.publicReactions ? [{
 	key: 'reactions',
 	title: i18n.ts.reaction,
-	icon: 'fas fa-laugh',
+	icon: 'ti ti-mood-happy',
 }] : [], {
 	key: 'clips',
 	title: i18n.ts.clips,
-	icon: 'fas fa-paperclip',
+	icon: 'ti ti-paperclip',
 }, {
 	key: 'pages',
 	title: i18n.ts.pages,
@@ -85,11 +85,11 @@ const headerTabs = $computed(() => user ? [{
 }, {
 	key: 'gallery',
 	title: i18n.ts.gallery,
-	icon: 'fas fa-icons',
+	icon: 'ti ti-icons',
 }] : null);
 
 definePageMetadata(computed(() => user ? {
-	icon: 'fas fa-user',
+	icon: 'ti ti-user',
 	title: user.name ? `${user.name} (@${user.username})` : `@${user.username}`,
 	subtitle: `@${getAcct(user)}`,
 	userName: user,
diff --git a/packages/client/src/pages/welcome.entrance.a.vue b/packages/client/src/pages/welcome.entrance.a.vue
index 827162a0c0..bfa54d39f2 100644
--- a/packages/client/src/pages/welcome.entrance.a.vue
+++ b/packages/client/src/pages/welcome.entrance.a.vue
@@ -15,7 +15,7 @@
 		</div>
 		<div class="main">
 			<img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
-			<button class="_button _acrylic menu" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
+			<button class="_button _acrylic menu" @click="showMenu"><i class="ti ti-dots"></i></button>
 			<div class="fg">
 				<h1>
 					<!-- 背景色によってはロゴが見えなくなるのでとりあえず無効に -->
@@ -107,19 +107,19 @@ function signup() {
 function showMenu(ev) {
 	os.popupMenu([{
 		text: i18n.ts.instanceInfo,
-		icon: 'fas fa-info-circle',
+		icon: 'ti ti-info-circle',
 		action: () => {
 			os.pageWindow('/about');
 		},
 	}, {
 		text: i18n.ts.aboutMisskey,
-		icon: 'fas fa-info-circle',
+		icon: 'ti ti-info-circle',
 		action: () => {
 			os.pageWindow('/about-misskey');
 		},
 	}, null, {
 		text: i18n.ts.help,
-		icon: 'fas fa-question-circle',
+		icon: 'ti ti-question-circle',
 		action: () => {
 			window.open('https://misskey-hub.net/help.md', '_blank');
 		},
diff --git a/packages/client/src/pages/welcome.entrance.b.vue b/packages/client/src/pages/welcome.entrance.b.vue
index 4bf117590a..53a6dd3469 100644
--- a/packages/client/src/pages/welcome.entrance.b.vue
+++ b/packages/client/src/pages/welcome.entrance.b.vue
@@ -104,19 +104,19 @@ export default defineComponent({
 		showMenu(ev) {
 			os.popupMenu([{
 				text: this.$t('aboutX', { x: instanceName }),
-				icon: 'fas fa-info-circle',
+				icon: 'ti ti-info-circle',
 				action: () => {
 					os.pageWindow('/about');
 				}
 			}, {
 				text: this.$ts.aboutMisskey,
-				icon: 'fas fa-info-circle',
+				icon: 'ti ti-info-circle',
 				action: () => {
 					os.pageWindow('/about-misskey');
 				}
 			}, null, {
 				text: this.$ts.help,
-				icon: 'fas fa-question-circle',
+				icon: 'ti ti-question-circle',
 				action: () => {
 					window.open(`https://misskey-hub.net/help.md`, '_blank');
 				}
diff --git a/packages/client/src/pages/welcome.entrance.c.vue b/packages/client/src/pages/welcome.entrance.c.vue
index a590834a4c..bae3f2ed9d 100644
--- a/packages/client/src/pages/welcome.entrance.c.vue
+++ b/packages/client/src/pages/welcome.entrance.c.vue
@@ -41,7 +41,7 @@
 							<template #n><b>{{ onlineUsersCount }}</b></template>
 						</I18n>
 					</div>
-					<button class="_button _acrylic menu" @click="showMenu"><i class="fas fa-ellipsis-h"></i></button>
+					<button class="_button _acrylic menu" @click="showMenu"><i class="ti ti-dots"></i></button>
 				</div>
 			</div>
 			<nav class="nav">
@@ -124,19 +124,19 @@ export default defineComponent({
 		showMenu(ev) {
 			os.popupMenu([{
 				text: this.$t('aboutX', { x: instanceName }),
-				icon: 'fas fa-info-circle',
+				icon: 'ti ti-info-circle',
 				action: () => {
 					os.pageWindow('/about');
 				}
 			}, {
 				text: this.$ts.aboutMisskey,
-				icon: 'fas fa-info-circle',
+				icon: 'ti ti-info-circle',
 				action: () => {
 					os.pageWindow('/about-misskey');
 				}
 			}, null, {
 				text: this.$ts.help,
-				icon: 'fas fa-question-circle',
+				icon: 'ti ti-question-circle',
 				action: () => {
 					window.open(`https://misskey-hub.net/help.md`, '_blank');
 				}
diff --git a/packages/client/src/pages/welcome.setup.vue b/packages/client/src/pages/welcome.setup.vue
index d25651e2a3..2729d30d4b 100644
--- a/packages/client/src/pages/welcome.setup.vue
+++ b/packages/client/src/pages/welcome.setup.vue
@@ -10,7 +10,7 @@
 		</MkInput>
 		<MkInput v-model="password" type="password" data-cy-admin-password class="_formBlock">
 			<template #label>{{ $ts.password }}</template>
-			<template #prefix><i class="fas fa-lock"></i></template>
+			<template #prefix><i class="ti ti-lock"></i></template>
 		</MkInput>
 		<div class="bottom _formBlock">
 			<MkButton gradate type="submit" :disabled="submitting" data-cy-admin-ok>
diff --git a/packages/client/src/pages/welcome.timeline.vue b/packages/client/src/pages/welcome.timeline.vue
index e19ebac3ed..f45a15448d 100644
--- a/packages/client/src/pages/welcome.timeline.vue
+++ b/packages/client/src/pages/welcome.timeline.vue
@@ -4,7 +4,7 @@
 		<div v-for="note in notes" class="note">
 			<div class="content _panel">
 				<div class="body">
-					<MkA v-if="note.replyId" class="reply" :to="`/notes/${note.replyId}`"><i class="fas fa-reply"></i></MkA>
+					<MkA v-if="note.replyId" class="reply" :to="`/notes/${note.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
 					<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" :custom-emojis="note.emojis"/>
 					<MkA v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
 				</div>
diff --git a/packages/client/src/scripts/get-note-menu.ts b/packages/client/src/scripts/get-note-menu.ts
index 4826cd70fd..c9663d32e5 100644
--- a/packages/client/src/scripts/get-note-menu.ts
+++ b/packages/client/src/scripts/get-note-menu.ts
@@ -93,7 +93,7 @@ export function getNoteMenu(props: {
 	async function clip(): Promise<void> {
 		const clips = await os.api('clips/list');
 		os.popupMenu([{
-			icon: 'fas fa-plus',
+			icon: 'ti ti-plus',
 			text: i18n.ts.createNew,
 			action: async () => {
 				const { canceled, result } = await os.form(i18n.ts.createNewClip, {
@@ -196,70 +196,70 @@ export function getNoteMenu(props: {
 		menu = [
 			...(
 				props.currentClipPage?.value.userId === $i.id ? [{
-					icon: 'fas fa-circle-minus',
+					icon: 'ti ti-backspace',
 					text: i18n.ts.unclip,
 					danger: true,
 					action: unclip,
 				}, null] : []
 			), {
-				icon: 'fas fa-external-link-alt',
+				icon: 'ti ti-external-link',
 				text: i18n.ts.details,
 				action: notedetails,
 			}, {
-				icon: 'fas fa-copy',
+				icon: 'ti ti-copy',
 				text: i18n.ts.copyContent,
 				action: copyContent,
 			}, {
-				icon: 'fas fa-link',
+				icon: 'ti ti-link',
 				text: i18n.ts.copyLink,
 				action: copyLink,
 			}, (appearNote.url || appearNote.uri) ? {
-				icon: 'fas fa-external-link-square-alt',
+				icon: 'ti ti-external-link',
 				text: i18n.ts.showOnRemote,
 				action: () => {
 					window.open(appearNote.url || appearNote.uri, '_blank');
 				},
 			} : undefined,
 			{
-				icon: 'fas fa-share-alt',
+				icon: 'ti ti-share',
 				text: i18n.ts.share,
 				action: share,
 			},
 			instance.translatorAvailable ? {
-				icon: 'fas fa-language',
+				icon: 'ti ti-language-hiragana',
 				text: i18n.ts.translate,
 				action: translate,
 			} : undefined,
 			null,
 			statePromise.then(state => state.isFavorited ? {
-				icon: 'fas fa-star',
+				icon: 'ti ti-star',
 				text: i18n.ts.unfavorite,
 				action: () => toggleFavorite(false),
 			} : {
-				icon: 'fas fa-star',
+				icon: 'ti ti-star',
 				text: i18n.ts.favorite,
 				action: () => toggleFavorite(true),
 			}),
 			{
-				icon: 'fas fa-paperclip',
+				icon: 'ti ti-paperclip',
 				text: i18n.ts.clip,
 				action: () => clip(),
 			},
 			statePromise.then(state => state.isMutedThread ? {
-				icon: 'fas fa-comment-slash',
+				icon: 'ti ti-message-off',
 				text: i18n.ts.unmuteThread,
 				action: () => toggleThreadMute(false),
 			} : {
-				icon: 'fas fa-comment-slash',
+				icon: 'ti ti-message-off',
 				text: i18n.ts.muteThread,
 				action: () => toggleThreadMute(true),
 			}),
 			appearNote.userId === $i.id ? ($i.pinnedNoteIds || []).includes(appearNote.id) ? {
-				icon: 'fas fa-thumbtack',
+				icon: 'ti ti-pin',
 				text: i18n.ts.unpin,
 				action: () => togglePin(false),
 			} : {
-				icon: 'fas fa-thumbtack',
+				icon: 'ti ti-pin',
 				text: i18n.ts.pin,
 				action: () => togglePin(true),
 			} : undefined,
@@ -276,7 +276,7 @@ export function getNoteMenu(props: {
 			...(appearNote.userId !== $i.id ? [
 				null,
 				{
-					icon: 'fas fa-exclamation-circle',
+					icon: 'ti ti-exclamation-circle',
 					text: i18n.ts.reportAbuse,
 					action: () => {
 						const u = appearNote.url || appearNote.uri || `${url}/notes/${appearNote.id}`;
@@ -291,12 +291,12 @@ export function getNoteMenu(props: {
 			...(appearNote.userId === $i.id || $i.isModerator || $i.isAdmin ? [
 				null,
 				appearNote.userId === $i.id ? {
-					icon: 'fas fa-edit',
+					icon: 'ti ti-edit',
 					text: i18n.ts.deleteAndEdit,
 					action: delEdit,
 				} : undefined,
 				{
-					icon: 'fas fa-trash-alt',
+					icon: 'ti ti-trash',
 					text: i18n.ts.delete,
 					danger: true,
 					action: del,
@@ -306,19 +306,19 @@ export function getNoteMenu(props: {
 			.filter(x => x !== undefined);
 	} else {
 		menu = [{
-			icon: 'fas fa-external-link-alt',
+			icon: 'ti ti-external-link',
 			text: i18n.ts.detailed,
 			action: openDetail,
 		}, {
-			icon: 'fas fa-copy',
+			icon: 'ti ti-copy',
 			text: i18n.ts.copyContent,
 			action: copyContent,
 		}, {
-			icon: 'fas fa-link',
+			icon: 'ti ti-link',
 			text: i18n.ts.copyLink,
 			action: copyLink,
 		}, (appearNote.url || appearNote.uri) ? {
-			icon: 'fas fa-external-link-square-alt',
+			icon: 'ti ti-external-link',
 			text: i18n.ts.showOnRemote,
 			action: () => {
 				window.open(appearNote.url || appearNote.uri, '_blank');
@@ -329,7 +329,7 @@ export function getNoteMenu(props: {
 
 	if (noteActions.length > 0) {
 		menu = menu.concat([null, ...noteActions.map(action => ({
-			icon: 'fas fa-plug',
+			icon: 'ti ti-plug',
 			text: action.title,
 			action: () => {
 				action.handler(appearNote);
diff --git a/packages/client/src/scripts/get-user-menu.ts b/packages/client/src/scripts/get-user-menu.ts
index 4a5a2d42f0..23f0e11f5b 100644
--- a/packages/client/src/scripts/get-user-menu.ts
+++ b/packages/client/src/scripts/get-user-menu.ts
@@ -153,70 +153,70 @@ export function getUserMenu(user, router: Router = mainRouter) {
 	}
 
 	let menu = [{
-		icon: 'fas fa-at',
+		icon: 'ti ti-at',
 		text: i18n.ts.copyUsername,
 		action: () => {
 			copyToClipboard(`@${user.username}@${user.host || host}`);
 		},
 	}, {
-		icon: 'fas fa-info-circle',
+		icon: 'ti ti-info-circle',
 		text: i18n.ts.info,
 		action: () => {
 			router.push(`/user-info/${user.id}`);
 		},
 	}, {
-		icon: 'fas fa-envelope',
+		icon: 'ti ti-mail',
 		text: i18n.ts.sendMessage,
 		action: () => {
 			os.post({ specified: user });
 		},
 	}, meId !== user.id ? {
 		type: 'link',
-		icon: 'fas fa-comments',
+		icon: 'ti ti-messages',
 		text: i18n.ts.startMessaging,
 		to: '/my/messaging/' + Acct.toString(user),
 	} : undefined, null, {
-		icon: 'fas fa-list-ul',
+		icon: 'ti ti-list',
 		text: i18n.ts.addToList,
 		action: pushList,
 	}, meId !== user.id ? {
-		icon: 'fas fa-users',
+		icon: 'ti ti-users',
 		text: i18n.ts.inviteToGroup,
 		action: inviteGroup,
 	} : undefined] as any;
 
 	if ($i && meId !== user.id) {
 		menu = menu.concat([null, {
-			icon: user.isMuted ? 'fas fa-eye' : 'fas fa-eye-slash',
+			icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off',
 			text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute,
 			action: toggleMute,
 		}, {
-			icon: 'fas fa-ban',
+			icon: 'ti ti-ban',
 			text: user.isBlocking ? i18n.ts.unblock : i18n.ts.block,
 			action: toggleBlock,
 		}]);
 
 		if (user.isFollowed) {
 			menu = menu.concat([{
-				icon: 'fas fa-unlink',
+				icon: 'ti ti-link-off',
 				text: i18n.ts.breakFollow,
 				action: invalidateFollow,
 			}]);
 		}
 
 		menu = menu.concat([null, {
-			icon: 'fas fa-exclamation-circle',
+			icon: 'ti ti-exclamation-circle',
 			text: i18n.ts.reportAbuse,
 			action: reportAbuse,
 		}]);
 
 		if (iAmModerator) {
 			menu = menu.concat([null, {
-				icon: 'fas fa-microphone-slash',
+				icon: 'ti ti-microphone-2-off',
 				text: user.isSilenced ? i18n.ts.unsilence : i18n.ts.silence,
 				action: toggleSilence,
 			}, {
-				icon: 'fas fa-snowflake',
+				icon: 'ti ti-snowflake',
 				text: user.isSuspended ? i18n.ts.unsuspend : i18n.ts.suspend,
 				action: toggleSuspend,
 			}]);
@@ -225,7 +225,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
 
 	if ($i && meId === user.id) {
 		menu = menu.concat([null, {
-			icon: 'fas fa-pencil-alt',
+			icon: 'ti ti-pencil',
 			text: i18n.ts.editProfile,
 			action: () => {
 				router.push('/settings/profile');
@@ -235,7 +235,7 @@ export function getUserMenu(user, router: Router = mainRouter) {
 
 	if (userActions.length > 0) {
 		menu = menu.concat([null, ...userActions.map(action => ({
-			icon: 'fas fa-plug',
+			icon: 'ti ti-plug',
 			text: action.title,
 			action: () => {
 				action.handler(user);
diff --git a/packages/client/src/scripts/hpml/index.ts b/packages/client/src/scripts/hpml/index.ts
index 7cf88d5961..4e5aadfbd3 100644
--- a/packages/client/src/scripts/hpml/index.ts
+++ b/packages/client/src/scripts/hpml/index.ts
@@ -14,7 +14,7 @@ export type Fn = {
 export type Type = 'string' | 'number' | 'boolean' | 'stringArray' | null;
 
 export const literalDefs: Record<string, { out: any; category: string; icon: any; }> = {
-	text: { out: 'string', category: 'value', icon: 'fas fa-quote-right', },
+	text: { out: 'string', category: 'value', icon: 'ti ti-quote', },
 	multiLineText: { out: 'string', category: 'value', icon: 'fas fa-align-left', },
 	textList: { out: 'stringArray', category: 'value', icon: 'fas fa-list', },
 	number: { out: 'number', category: 'value', icon: 'fas fa-sort-numeric-up', },
diff --git a/packages/client/src/scripts/hpml/lib.ts b/packages/client/src/scripts/hpml/lib.ts
index cab467a920..b684876a7f 100644
--- a/packages/client/src/scripts/hpml/lib.ts
+++ b/packages/client/src/scripts/hpml/lib.ts
@@ -130,14 +130,14 @@ export function initAiLib(hpml: Hpml) {
 }
 
 export const funcDefs: Record<string, { in: any[]; out: any; category: string; icon: any; }> = {
-	if: { in: ['boolean', 0, 0], out: 0, category: 'flow', icon: 'fas fa-share-alt' },
+	if: { in: ['boolean', 0, 0], out: 0, category: 'flow', icon: 'ti ti-share' },
 	for: { in: ['number', 'function'], out: null, category: 'flow', icon: 'fas fa-recycle' },
 	not: { in: ['boolean'], out: 'boolean', category: 'logical', icon: 'fas fa-flag' },
 	or: { in: ['boolean', 'boolean'], out: 'boolean', category: 'logical', icon: 'fas fa-flag' },
 	and: { in: ['boolean', 'boolean'], out: 'boolean', category: 'logical', icon: 'fas fa-flag' },
-	add: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'fas fa-plus' },
-	subtract: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'fas fa-minus' },
-	multiply: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'fas fa-times' },
+	add: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'ti ti-plus' },
+	subtract: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'ti ti-minus' },
+	multiply: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'ti ti-x' },
 	divide: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'fas fa-divide' },
 	mod: { in: ['number', 'number'], out: 'number', category: 'operation', icon: 'fas fa-divide' },
 	round: { in: ['number'], out: 'number', category: 'operation', icon: 'fas fa-calculator' },
@@ -147,11 +147,11 @@ export const funcDefs: Record<string, { in: any[]; out: any; category: string; i
 	lt: { in: ['number', 'number'], out: 'boolean', category: 'comparison', icon: 'fas fa-less-than' },
 	gtEq: { in: ['number', 'number'], out: 'boolean', category: 'comparison', icon: 'fas fa-greater-than-equal' },
 	ltEq: { in: ['number', 'number'], out: 'boolean', category: 'comparison', icon: 'fas fa-less-than-equal' },
-	strLen: { in: ['string'], out: 'number', category: 'text', icon: 'fas fa-quote-right' },
-	strPick: { in: ['string', 'number'], out: 'string', category: 'text', icon: 'fas fa-quote-right' },
-	strReplace: { in: ['string', 'string', 'string'], out: 'string', category: 'text', icon: 'fas fa-quote-right' },
-	strReverse: { in: ['string'], out: 'string', category: 'text', icon: 'fas fa-quote-right' },
-	join: { in: ['stringArray', 'string'], out: 'string', category: 'text', icon: 'fas fa-quote-right' },
+	strLen: { in: ['string'], out: 'number', category: 'text', icon: 'ti ti-quote' },
+	strPick: { in: ['string', 'number'], out: 'string', category: 'text', icon: 'ti ti-quote' },
+	strReplace: { in: ['string', 'string', 'string'], out: 'string', category: 'text', icon: 'ti ti-quote' },
+	strReverse: { in: ['string'], out: 'string', category: 'text', icon: 'ti ti-quote' },
+	join: { in: ['stringArray', 'string'], out: 'string', category: 'text', icon: 'ti ti-quote' },
 	stringToNumber: { in: ['string'], out: 'number', category: 'convert', icon: 'fas fa-exchange-alt' },
 	numberToString: { in: ['number'], out: 'string', category: 'convert', icon: 'fas fa-exchange-alt' },
 	splitStrByLine: { in: ['string'], out: 'stringArray', category: 'convert', icon: 'fas fa-exchange-alt' },
diff --git a/packages/client/src/scripts/select-file.ts b/packages/client/src/scripts/select-file.ts
index 17e31d96f1..ec5f8f65e9 100644
--- a/packages/client/src/scripts/select-file.ts
+++ b/packages/client/src/scripts/select-file.ts
@@ -80,15 +80,15 @@ function select(src: any, label: string | null, multiple: boolean): Promise<Driv
 			ref: keepOriginal,
 		}, {
 			text: i18n.ts.upload,
-			icon: 'fas fa-upload',
+			icon: 'ti ti-upload',
 			action: chooseFileFromPc,
 		}, {
 			text: i18n.ts.fromDrive,
-			icon: 'fas fa-cloud',
+			icon: 'ti ti-cloud',
 			action: chooseFileFromDrive,
 		}, {
 			text: i18n.ts.fromUrl,
-			icon: 'fas fa-link',
+			icon: 'ti ti-link',
 			action: chooseFileFromUrl,
 		}], src);
 	});
diff --git a/packages/client/src/style.scss b/packages/client/src/style.scss
index 0b61d46f10..50b7e5c3e5 100644
--- a/packages/client/src/style.scss
+++ b/packages/client/src/style.scss
@@ -119,6 +119,25 @@ hr {
 	background: var(--divider);
 }
 
+.ti {
+	font-size: 130%;
+	vertical-align: text-bottom;
+}
+
+.ti-fw {
+	display: inline-block;
+	width: 1em;
+	text-align: center;
+}
+
+._indicatorCircle {
+	display: inline-block;
+	width: 1em;
+	height: 1em;
+	border-radius: 100%;
+	background: currentColor;
+}
+
 ._noSelect {
 	user-select: none;
 	-webkit-user-select: none;
diff --git a/packages/client/src/ui/_common_/navbar-for-mobile.vue b/packages/client/src/ui/_common_/navbar-for-mobile.vue
index de000447ad..50b28de063 100644
--- a/packages/client/src/ui/_common_/navbar-for-mobile.vue
+++ b/packages/client/src/ui/_common_/navbar-for-mobile.vue
@@ -9,30 +9,30 @@
 		</div>
 		<div class="middle">
 			<MkA v-click-anime class="item index" active-class="active" to="/" exact>
-				<i class="icon fas fa-home fa-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
+				<i class="icon ti ti-home ti-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
 			</MkA>
 			<template v-for="item in menu">
 				<div v-if="item === '-'" class="divider"></div>
 				<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime class="item _button" :class="[item, { active: navbarItemDef[item].active }]" active-class="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
-					<i class="icon fa-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ i18n.ts[navbarItemDef[item].title] }}</span>
-					<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="icon fas fa-circle"></i></span>
+					<i class="icon ti-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ i18n.ts[navbarItemDef[item].title] }}</span>
+					<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="icon _indicatorCircle"></i></span>
 				</component>
 			</template>
 			<div class="divider"></div>
 			<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime class="item" active-class="active" to="/admin">
-				<i class="icon fas fa-door-open fa-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
+				<i class="icon ti ti-dashboard ti-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
 			</MkA>
 			<button v-click-anime class="item _button" @click="more">
-				<i class="icon fa fa-ellipsis-h fa-fw"></i><span class="text">{{ i18n.ts.more }}</span>
-				<span v-if="otherMenuItemIndicated" class="indicator"><i class="icon fas fa-circle"></i></span>
+				<i class="icon ti ti-grid-dots ti-fw"></i><span class="text">{{ i18n.ts.more }}</span>
+				<span v-if="otherMenuItemIndicated" class="indicator"><i class="icon _indicatorCircle"></i></span>
 			</button>
 			<MkA v-click-anime class="item" active-class="active" to="/settings">
-				<i class="icon fas fa-cog fa-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
+				<i class="icon ti ti-settings ti-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
 			</MkA>
 		</div>
 		<div class="bottom">
 			<button class="item _button post" data-cy-open-post-form @click="os.post">
-				<i class="icon fas fa-pencil-alt fa-fw"></i><span class="text">{{ i18n.ts.note }}</span>
+				<i class="icon ti ti-pencil ti-fw"></i><span class="text">{{ i18n.ts.note }}</span>
 			</button>
 			<button v-click-anime class="item _button account" @click="openAccountMenu">
 				<MkAvatar :user="$i" class="avatar"/><MkAcct class="text" :user="$i"/>
@@ -75,40 +75,40 @@ function openInstanceMenu(ev: MouseEvent) {
 	}, {
 		type: 'link',
 		text: i18n.ts.instanceInfo,
-		icon: 'fas fa-info-circle',
+		icon: 'ti ti-info-circle',
 		to: '/about',
 	}, {
 		type: 'link',
 		text: i18n.ts.customEmojis,
-		icon: 'fas fa-laugh',
+		icon: 'ti ti-mood-happy',
 		to: '/about#emojis',
 	}, {
 		type: 'link',
 		text: i18n.ts.federation,
-		icon: 'fas fa-globe',
+		icon: 'ti ti-whirl',
 		to: '/about#federation',
 	}, null, {
 		type: 'parent',
 		text: i18n.ts.help,
-		icon: 'fas fa-question-circle',
+		icon: 'ti ti-question-circle',
 		children: [{
 			type: 'link',
 			to: '/mfm-cheat-sheet',
 			text: i18n.ts._mfm.cheatSheet,
-			icon: 'fas fa-code',
+			icon: 'ti ti-code',
 		}, {
 			type: 'link',
 			to: '/scratchpad',
 			text: i18n.ts.scratchpad,
-			icon: 'fas fa-terminal',
+			icon: 'ti ti-terminal-2',
 		}, {
 			type: 'link',
 			to: '/api-console',
 			text: 'API Console',
-			icon: 'fas fa-terminal',
+			icon: 'ti ti-terminal-2',
 		}, null, {
 			text: i18n.ts.document,
-			icon: 'fas fa-question-circle',
+			icon: 'ti ti-question-circle',
 			action: () => {
 				window.open('https://misskey-hub.net/help.html', '_blank');
 			},
diff --git a/packages/client/src/ui/_common_/navbar.vue b/packages/client/src/ui/_common_/navbar.vue
index 20622b083a..b82da15f13 100644
--- a/packages/client/src/ui/_common_/navbar.vue
+++ b/packages/client/src/ui/_common_/navbar.vue
@@ -9,7 +9,7 @@
 		</div>
 		<div class="middle">
 			<MkA v-click-anime v-tooltip.noDelay.right="i18n.ts.timeline" class="item index" active-class="active" to="/" exact>
-				<i class="icon fas fa-home fa-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
+				<i class="icon ti ti-home ti-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
 			</MkA>
 			<template v-for="item in menu">
 				<div v-if="item === '-'" class="divider"></div>
@@ -24,25 +24,25 @@
 					:to="navbarItemDef[item].to"
 					v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}"
 				>
-					<i class="icon fa-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ i18n.ts[navbarItemDef[item].title] }}</span>
-					<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="icon fas fa-circle"></i></span>
+					<i class="icon ti-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ i18n.ts[navbarItemDef[item].title] }}</span>
+					<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="icon _indicatorCircle"></i></span>
 				</component>
 			</template>
 			<div class="divider"></div>
 			<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip.noDelay.right="i18n.ts.controlPanel" class="item" active-class="active" to="/admin">
-				<i class="icon fas fa-door-open fa-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
+				<i class="icon ti ti-dashboard ti-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
 			</MkA>
 			<button v-click-anime class="item _button" @click="more">
-				<i class="icon fa fa-ellipsis-h fa-fw"></i><span class="text">{{ i18n.ts.more }}</span>
-				<span v-if="otherMenuItemIndicated" class="indicator"><i class="icon fas fa-circle"></i></span>
+				<i class="icon ti ti-grid-dots ti-fw"></i><span class="text">{{ i18n.ts.more }}</span>
+				<span v-if="otherMenuItemIndicated" class="indicator"><i class="icon _indicatorCircle"></i></span>
 			</button>
 			<MkA v-click-anime v-tooltip.noDelay.right="i18n.ts.settings" class="item" active-class="active" to="/settings">
-				<i class="icon fas fa-cog fa-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
+				<i class="icon ti ti-settings ti-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
 			</MkA>
 		</div>
 		<div class="bottom">
 			<button v-tooltip.noDelay.right="i18n.ts.note" class="item _button post" data-cy-open-post-form @click="os.post">
-				<i class="icon fas fa-pencil-alt fa-fw"></i><span class="text">{{ i18n.ts.note }}</span>
+				<i class="icon ti ti-pencil ti-fw"></i><span class="text">{{ i18n.ts.note }}</span>
 			</button>
 			<button v-click-anime v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="item _button account" @click="openAccountMenu">
 				<MkAvatar :user="$i" class="avatar"/><MkAcct class="text" :user="$i"/>
@@ -98,40 +98,40 @@ function openInstanceMenu(ev: MouseEvent) {
 	}, {
 		type: 'link',
 		text: i18n.ts.instanceInfo,
-		icon: 'fas fa-info-circle',
+		icon: 'ti ti-info-circle',
 		to: '/about',
 	}, {
 		type: 'link',
 		text: i18n.ts.customEmojis,
-		icon: 'fas fa-laugh',
+		icon: 'ti ti-mood-happy',
 		to: '/about#emojis',
 	}, {
 		type: 'link',
 		text: i18n.ts.federation,
-		icon: 'fas fa-globe',
+		icon: 'ti ti-whirl',
 		to: '/about#federation',
 	}, null, {
 		type: 'parent',
 		text: i18n.ts.help,
-		icon: 'fas fa-question-circle',
+		icon: 'ti ti-question-circle',
 		children: [{
 			type: 'link',
 			to: '/mfm-cheat-sheet',
 			text: i18n.ts._mfm.cheatSheet,
-			icon: 'fas fa-code',
+			icon: 'ti ti-code',
 		}, {
 			type: 'link',
 			to: '/scratchpad',
 			text: i18n.ts.scratchpad,
-			icon: 'fas fa-terminal',
+			icon: 'ti ti-terminal-2',
 		}, {
 			type: 'link',
 			to: '/api-console',
 			text: 'API Console',
-			icon: 'fas fa-terminal',
+			icon: 'ti ti-terminal-2',
 		}, null, {
 			text: i18n.ts.document,
-			icon: 'fas fa-question-circle',
+			icon: 'ti ti-question-circle',
 			action: () => {
 				window.open('https://misskey-hub.net/help.html', '_blank');
 			},
diff --git a/packages/client/src/ui/classic.header.vue b/packages/client/src/ui/classic.header.vue
index 306d32c597..46d79e6355 100644
--- a/packages/client/src/ui/classic.header.vue
+++ b/packages/client/src/ui/classic.header.vue
@@ -3,34 +3,34 @@
 	<div class="body">
 		<div class="left">
 			<MkA v-click-anime v-tooltip="$ts.timeline" class="item index" active-class="active" to="/" exact>
-				<i class="fas fa-home fa-fw"></i>
+				<i class="ti ti-home ti-fw"></i>
 			</MkA>
 			<template v-for="item in menu">
 				<div v-if="item === '-'" class="divider"></div>
 				<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime v-tooltip="$ts[navbarItemDef[item].title]" class="item _button" :class="item" active-class="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
-					<i class="fa-fw" :class="navbarItemDef[item].icon"></i>
-					<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="fas fa-circle"></i></span>
+					<i class="ti-fw" :class="navbarItemDef[item].icon"></i>
+					<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="_indicatorCircle"></i></span>
 				</component>
 			</template>
 			<div class="divider"></div>
 			<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip="$ts.controlPanel" class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null">
-				<i class="fas fa-door-open fa-fw"></i>
+				<i class="ti ti-dashboard ti-fw"></i>
 			</MkA>
 			<button v-click-anime class="item _button" @click="more">
-				<i class="fas fa-ellipsis-h fa-fw"></i>
-				<span v-if="otherNavItemIndicated" class="indicator"><i class="fas fa-circle"></i></span>
+				<i class="ti ti-dots ti-fw"></i>
+				<span v-if="otherNavItemIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
 			</button>
 		</div>
 		<div class="right">
 			<MkA v-click-anime v-tooltip="$ts.settings" class="item" active-class="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null">
-				<i class="fas fa-cog fa-fw"></i>
+				<i class="ti ti-settings ti-fw"></i>
 			</MkA>
 			<button v-click-anime class="item _button account" @click="openAccountMenu">
 				<MkAvatar :user="$i" class="avatar"/><MkAcct class="acct" :user="$i"/>
 			</button>
 			<div class="post" @click="post">
 				<MkButton class="button" gradate full rounded>
-					<i class="fas fa-pencil-alt fa-fw"></i>
+					<i class="ti ti-pencil ti-fw"></i>
 				</MkButton>
 			</div>
 		</div>
diff --git a/packages/client/src/ui/classic.sidebar.vue b/packages/client/src/ui/classic.sidebar.vue
index 7479c1c9c6..dac09ea703 100644
--- a/packages/client/src/ui/classic.sidebar.vue
+++ b/packages/client/src/ui/classic.sidebar.vue
@@ -5,30 +5,30 @@
 	</button>
 	<div class="post" data-cy-open-post-form @click="post">
 		<MkButton class="button" gradate full rounded>
-			<i class="fas fa-pencil-alt fa-fw"></i><span v-if="!iconOnly" class="text">{{ $ts.note }}</span>
+			<i class="ti ti-pencil ti-fw"></i><span v-if="!iconOnly" class="text">{{ $ts.note }}</span>
 		</MkButton>
 	</div>
 	<div class="divider"></div>
 	<MkA v-click-anime class="item index" active-class="active" to="/" exact>
-		<i class="fas fa-home fa-fw"></i><span class="text">{{ $ts.timeline }}</span>
+		<i class="ti ti-home ti-fw"></i><span class="text">{{ $ts.timeline }}</span>
 	</MkA>
 	<template v-for="item in menu">
 		<div v-if="item === '-'" class="divider"></div>
 		<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime class="item _button" :class="item" active-class="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
-			<i class="fa-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ $ts[navbarItemDef[item].title] }}</span>
-			<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="fas fa-circle"></i></span>
+			<i class="ti-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ $ts[navbarItemDef[item].title] }}</span>
+			<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="_indicatorCircle"></i></span>
 		</component>
 	</template>
 	<div class="divider"></div>
 	<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime class="item" active-class="active" to="/admin" :behavior="settingsWindowed ? 'modalWindow' : null">
-		<i class="fas fa-door-open fa-fw"></i><span class="text">{{ $ts.controlPanel }}</span>
+		<i class="ti ti-dashboard ti-fw"></i><span class="text">{{ $ts.controlPanel }}</span>
 	</MkA>
 	<button v-click-anime class="item _button" @click="more">
-		<i class="fas fa-ellipsis-h fa-fw"></i><span class="text">{{ $ts.more }}</span>
-		<span v-if="otherNavItemIndicated" class="indicator"><i class="fas fa-circle"></i></span>
+		<i class="ti ti-dots ti-fw"></i><span class="text">{{ $ts.more }}</span>
+		<span v-if="otherNavItemIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
 	</button>
 	<MkA v-click-anime class="item" active-class="active" to="/settings" :behavior="settingsWindowed ? 'modalWindow' : null">
-		<i class="fas fa-cog fa-fw"></i><span class="text">{{ $ts.settings }}</span>
+		<i class="ti ti-settings ti-fw"></i><span class="text">{{ $ts.settings }}</span>
 	</MkA>
 	<div class="divider"></div>
 	<div class="about">
diff --git a/packages/client/src/ui/classic.vue b/packages/client/src/ui/classic.vue
index cf82142fe0..0e726c11ed 100644
--- a/packages/client/src/ui/classic.vue
+++ b/packages/client/src/ui/classic.vue
@@ -110,7 +110,7 @@ function onContextmenu(ev: MouseEvent) {
 			fullView = !fullView;
 		},
 	}, {
-		icon: 'fas fa-window-maximize',
+		icon: 'ti ti-window-maximize',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(path);
diff --git a/packages/client/src/ui/classic.widgets.vue b/packages/client/src/ui/classic.widgets.vue
index ca8e3f4dbc..ca919b168a 100644
--- a/packages/client/src/ui/classic.widgets.vue
+++ b/packages/client/src/ui/classic.widgets.vue
@@ -3,8 +3,8 @@
 	<XWidgets class="widgets" :edit="editMode" :widgets="$store.reactiveState.widgets.value.filter(w => w.place === place)" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="editMode = false"/>
 	<MkAd class="a" :prefer="['square']"/>
 
-	<button v-if="editMode" class="_textButton edit" style="font-size: 0.9em;" @click="editMode = false"><i class="fas fa-check"></i> {{ $ts.editWidgetsExit }}</button>
-	<button v-else class="_textButton edit" style="font-size: 0.9em;" @click="editMode = true"><i class="fas fa-pencil-alt"></i> {{ $ts.editWidgets }}</button>
+	<button v-if="editMode" class="_textButton edit" style="font-size: 0.9em;" @click="editMode = false"><i class="ti ti-check"></i> {{ $ts.editWidgetsExit }}</button>
+	<button v-else class="_textButton edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ti ti-pencil"></i> {{ $ts.editWidgets }}</button>
 </div>
 </template>
 
diff --git a/packages/client/src/ui/deck.vue b/packages/client/src/ui/deck.vue
index 224ad7ee1a..f3415cfd09 100644
--- a/packages/client/src/ui/deck.vue
+++ b/packages/client/src/ui/deck.vue
@@ -34,24 +34,24 @@
 			</div>
 			<div class="sideMenu">
 				<div class="top">
-					<button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${deckStore.state.profile}`" class="_button button" @click="changeProfile"><i class="fas fa-caret-down"></i></button>
-					<button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" class="_button button" @click="deleteProfile"><i class="fas fa-trash-can"></i></button>
+					<button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${deckStore.state.profile}`" class="_button button" @click="changeProfile"><i class="ti ti-caret-down"></i></button>
+					<button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" class="_button button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
 				</div>
 				<div class="middle">
-					<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" class="_button button" @click="addColumn"><i class="fas fa-plus"></i></button>
+					<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" class="_button button" @click="addColumn"><i class="ti ti-plus"></i></button>
 				</div>
 				<div class="bottom">
-					<button v-tooltip.noDelay.left="i18n.ts.settings" class="_button button settings" @click="showSettings"><i class="fas fa-cog"></i></button>
+					<button v-tooltip.noDelay.left="i18n.ts.settings" class="_button button settings" @click="showSettings"><i class="ti ti-settings"></i></button>
 				</div>
 			</div>
 		</div>
 	</div>
 
 	<div v-if="isMobile" class="buttons">
-		<button class="button nav _button" @click="drawerMenuShowing = true"><i class="fas fa-bars"></i><span v-if="menuIndicated" class="indicator"><i class="fas fa-circle"></i></span></button>
-		<button class="button home _button" @click="mainRouter.push('/')"><i class="fas fa-home"></i></button>
-		<button class="button notifications _button" @click="mainRouter.push('/my/notifications')"><i class="fas fa-bell"></i><span v-if="$i?.hasUnreadNotification" class="indicator"><i class="fas fa-circle"></i></span></button>
-		<button class="button post _button" @click="os.post()"><i class="fas fa-pencil-alt"></i></button>
+		<button class="button nav _button" @click="drawerMenuShowing = true"><i class="ti ti-menu-2"></i><span v-if="menuIndicated" class="indicator"><i class="_indicatorCircle"></i></span></button>
+		<button class="button home _button" @click="mainRouter.push('/')"><i class="ti ti-home"></i></button>
+		<button class="button notifications _button" @click="mainRouter.push('/my/notifications')"><i class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" class="indicator"><i class="_indicatorCircle"></i></span></button>
+		<button class="button post _button" @click="os.post()"><i class="ti ti-pencil"></i></button>
 	</div>
 
 	<transition :name="$store.state.animation ? 'menu-back' : ''">
@@ -194,7 +194,7 @@ function changeProfile(ev: MouseEvent) {
 			},
 		}))), null, {
 			text: i18n.ts._deck.newProfile,
-			icon: 'fas fa-plus',
+			icon: 'ti ti-plus',
 			action: async () => {
 				const { canceled, result: name } = await os.inputText({
 					title: i18n.ts._deck.profile,
diff --git a/packages/client/src/ui/deck/antenna-column.vue b/packages/client/src/ui/deck/antenna-column.vue
index df9539617c..ba14530662 100644
--- a/packages/client/src/ui/deck/antenna-column.vue
+++ b/packages/client/src/ui/deck/antenna-column.vue
@@ -1,7 +1,7 @@
 <template>
 <XColumn :menu="menu" :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)">
 	<template #header>
-		<i class="fas fa-satellite"></i><span style="margin-left: 8px;">{{ column.name }}</span>
+		<i class="ti ti-antenna"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<XTimeline v-if="column.antennaId" ref="timeline" src="antenna" :antenna="column.antennaId" @after="() => emit('loaded')"/>
@@ -50,7 +50,7 @@ async function setAntenna() {
 }
 
 const menu = [{
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 	text: i18n.ts.selectAntenna,
 	action: setAntenna,
 }];
diff --git a/packages/client/src/ui/deck/column.vue b/packages/client/src/ui/deck/column.vue
index d16c23d100..b50879dbc8 100644
--- a/packages/client/src/ui/deck/column.vue
+++ b/packages/client/src/ui/deck/column.vue
@@ -16,14 +16,14 @@
 		@contextmenu.prevent.stop="onContextmenu"
 	>
 		<button v-if="isStacked && !isMainColumn" class="toggleActive _button" @click="toggleActive">
-			<template v-if="active"><i class="fas fa-angle-up"></i></template>
-			<template v-else><i class="fas fa-angle-down"></i></template>
+			<template v-if="active"><i class="ti ti-chevron-up"></i></template>
+			<template v-else><i class="ti ti-chevron-down"></i></template>
 		</button>
 		<div class="action">
 			<slot name="action"></slot>
 		</div>
 		<span class="header"><slot name="header"></slot></span>
-		<button v-tooltip="i18n.ts.settings" class="menu _button" @click.stop="showSettingsMenu"><i class="fas fa-ellipsis"></i></button>
+		<button v-tooltip="i18n.ts.settings" class="menu _button" @click.stop="showSettingsMenu"><i class="ti ti-dots"></i></button>
 	</header>
 	<div v-show="active" ref="body">
 		<slot></slot>
@@ -105,7 +105,7 @@ function toggleActive() {
 
 function getMenu() {
 	let items = [{
-		icon: 'fas fa-cog',
+		icon: 'ti ti-settings',
 		text: i18n.ts._deck.configureColumn,
 		action: async () => {
 			const { canceled, result } = await os.form(props.column.name, {
@@ -131,46 +131,46 @@ function getMenu() {
 	}, {
 		type: 'parent',
 		text: i18n.ts.move + '...',
-		icon: 'fas fa-arrows-up-down-left-right',
+		icon: 'ti ti-arrows-move',
 		children: [{
-			icon: 'fas fa-arrow-left',
+			icon: 'ti ti-arrow-left',
 			text: i18n.ts._deck.swapLeft,
 			action: () => {
 				swapLeftColumn(props.column.id);
 			},
 		}, {
-			icon: 'fas fa-arrow-right',
+			icon: 'ti ti-arrow-right',
 			text: i18n.ts._deck.swapRight,
 			action: () => {
 				swapRightColumn(props.column.id);
 			},
 		}, props.isStacked ? {
-			icon: 'fas fa-arrow-up',
+			icon: 'ti ti-arrow-up',
 			text: i18n.ts._deck.swapUp,
 			action: () => {
 				swapUpColumn(props.column.id);
 			},
 		} : undefined, props.isStacked ? {
-			icon: 'fas fa-arrow-down',
+			icon: 'ti ti-arrow-down',
 			text: i18n.ts._deck.swapDown,
 			action: () => {
 				swapDownColumn(props.column.id);
 			},
 		} : undefined],
 	}, {
-		icon: 'fas fa-window-restore',
+		icon: 'ti ti-stack-2',
 		text: i18n.ts._deck.stackLeft,
 		action: () => {
 			stackLeftColumn(props.column.id);
 		},
 	}, props.isStacked ? {
-		icon: 'fas fa-window-maximize',
+		icon: 'ti ti-window-maximize',
 		text: i18n.ts._deck.popRight,
 		action: () => {
 			popRightColumn(props.column.id);
 		},
 	} : undefined, null, {
-		icon: 'fas fa-trash-alt',
+		icon: 'ti ti-trash',
 		text: i18n.ts.remove,
 		danger: true,
 		action: () => {
diff --git a/packages/client/src/ui/deck/direct-column.vue b/packages/client/src/ui/deck/direct-column.vue
index 104f781b35..c60c5707f1 100644
--- a/packages/client/src/ui/deck/direct-column.vue
+++ b/packages/client/src/ui/deck/direct-column.vue
@@ -1,6 +1,6 @@
 <template>
 <XColumn :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)">
-	<template #header><i class="fas fa-envelope" style="margin-right: 8px;"></i>{{ column.name }}</template>
+	<template #header><i class="ti ti-mail" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
 	<XNotes :pagination="pagination"/>
 </XColumn>
diff --git a/packages/client/src/ui/deck/list-column.vue b/packages/client/src/ui/deck/list-column.vue
index 8fdf19cabb..d9f3f7b4e7 100644
--- a/packages/client/src/ui/deck/list-column.vue
+++ b/packages/client/src/ui/deck/list-column.vue
@@ -1,7 +1,7 @@
 <template>
 <XColumn :menu="menu" :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)">
 	<template #header>
-		<i class="fas fa-list-ul"></i><span style="margin-left: 8px;">{{ column.name }}</span>
+		<i class="ti ti-list"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<XTimeline v-if="column.listId" ref="timeline" src="list" :list="column.listId" @after="() => emit('loaded')"/>
@@ -48,7 +48,7 @@ async function setList() {
 }
 
 const menu = [{
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 	text: i18n.ts.selectList,
 	action: setList,
 }];
diff --git a/packages/client/src/ui/deck/main-column.vue b/packages/client/src/ui/deck/main-column.vue
index 9a5fd43af7..0c66172397 100644
--- a/packages/client/src/ui/deck/main-column.vue
+++ b/packages/client/src/ui/deck/main-column.vue
@@ -58,7 +58,7 @@ function onContextmenu(ev: MouseEvent) {
 		type: 'label',
 		text: path,
 	}, {
-		icon: 'fas fa-window-maximize',
+		icon: 'ti ti-window-maximize',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(path);
diff --git a/packages/client/src/ui/deck/mentions-column.vue b/packages/client/src/ui/deck/mentions-column.vue
index 18055215d2..16962956a0 100644
--- a/packages/client/src/ui/deck/mentions-column.vue
+++ b/packages/client/src/ui/deck/mentions-column.vue
@@ -1,6 +1,6 @@
 <template>
 <XColumn :column="column" :is-stacked="isStacked" @parent-focus="$event => emit('parent-focus', $event)">
-	<template #header><i class="fas fa-at" style="margin-right: 8px;"></i>{{ column.name }}</template>
+	<template #header><i class="ti ti-at" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
 	<XNotes :pagination="pagination"/>
 </XColumn>
diff --git a/packages/client/src/ui/deck/notifications-column.vue b/packages/client/src/ui/deck/notifications-column.vue
index e77b849ef4..9d133035fe 100644
--- a/packages/client/src/ui/deck/notifications-column.vue
+++ b/packages/client/src/ui/deck/notifications-column.vue
@@ -1,6 +1,6 @@
 <template>
 <XColumn :column="column" :is-stacked="isStacked" :menu="menu" @parent-focus="$event => emit('parent-focus', $event)">
-	<template #header><i class="fas fa-bell" style="margin-right: 8px;"></i>{{ column.name }}</template>
+	<template #header><i class="ti ti-bell" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
 	<XNotifications :include-types="column.includingTypes"/>
 </XColumn>
@@ -37,7 +37,7 @@ function func() {
 }
 
 const menu = [{
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 	text: i18n.ts.notificationSetting,
 	action: func,
 }];
diff --git a/packages/client/src/ui/deck/tl-column.vue b/packages/client/src/ui/deck/tl-column.vue
index e64ed852b2..49b29145ff 100644
--- a/packages/client/src/ui/deck/tl-column.vue
+++ b/packages/client/src/ui/deck/tl-column.vue
@@ -1,16 +1,16 @@
 <template>
 <XColumn :menu="menu" :column="column" :is-stacked="isStacked" :indicated="indicated" @change-active-state="onChangeActiveState" @parent-focus="$event => emit('parent-focus', $event)">
 	<template #header>
-		<i v-if="column.tl === 'home'" class="fas fa-home"></i>
-		<i v-else-if="column.tl === 'local'" class="fas fa-comments"></i>
-		<i v-else-if="column.tl === 'social'" class="fas fa-share-alt"></i>
-		<i v-else-if="column.tl === 'global'" class="fas fa-globe"></i>
+		<i v-if="column.tl === 'home'" class="ti ti-home"></i>
+		<i v-else-if="column.tl === 'local'" class="ti ti-messages"></i>
+		<i v-else-if="column.tl === 'social'" class="ti ti-share"></i>
+		<i v-else-if="column.tl === 'global'" class="ti ti-world"></i>
 		<span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<div v-if="disabled" class="iwaalbte">
 		<p>
-			<i class="fas fa-minus-circle"></i>
+			<i class="ti ti-minus-circle"></i>
 			{{ $t('disabled-timeline.title') }}
 		</p>
 		<p class="desc">{{ $t('disabled-timeline.description') }}</p>
@@ -98,7 +98,7 @@ function onChangeActiveState(state) {
 }
 
 const menu = [{
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 	text: i18n.ts.timeline,
 	action: setType,
 }];
diff --git a/packages/client/src/ui/deck/widgets-column.vue b/packages/client/src/ui/deck/widgets-column.vue
index 2c97009b3b..b5f49761fd 100644
--- a/packages/client/src/ui/deck/widgets-column.vue
+++ b/packages/client/src/ui/deck/widgets-column.vue
@@ -48,7 +48,7 @@ function func() {
 }
 
 const menu = [{
-	icon: 'fas fa-pencil-alt',
+	icon: 'ti ti-pencil',
 	text: i18n.ts.editWidgets,
 	action: func,
 }];
diff --git a/packages/client/src/ui/universal.vue b/packages/client/src/ui/universal.vue
index 7029f798f1..778ad53568 100644
--- a/packages/client/src/ui/universal.vue
+++ b/packages/client/src/ui/universal.vue
@@ -16,14 +16,14 @@
 		<XWidgets @mounted="attachSticky"/>
 	</div>
 
-	<button v-if="!isDesktop && !isMobile" class="widgetButton _button" @click="widgetsShowing = true"><i class="fas fa-layer-group"></i></button>
+	<button v-if="!isDesktop && !isMobile" class="widgetButton _button" @click="widgetsShowing = true"><i class="ti ti-layout-list"></i></button>
 
 	<div v-if="isMobile" class="buttons">
-		<button class="button nav _button" @click="drawerMenuShowing = true"><i class="fas fa-bars"></i><span v-if="menuIndicated" class="indicator"><i class="fas fa-circle"></i></span></button>
-		<button class="button home _button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')"><i class="fas fa-home"></i></button>
-		<button class="button notifications _button" @click="mainRouter.push('/my/notifications')"><i class="fas fa-bell"></i><span v-if="$i?.hasUnreadNotification" class="indicator"><i class="fas fa-circle"></i></span></button>
-		<button class="button widget _button" @click="widgetsShowing = true"><i class="fas fa-layer-group"></i></button>
-		<button class="button post _button" @click="os.post()"><i class="fas fa-pencil-alt"></i></button>
+		<button class="button nav _button" @click="drawerMenuShowing = true"><i class="ti ti-menu-2"></i><span v-if="menuIndicated" class="indicator"><i class="_indicatorCircle"></i></span></button>
+		<button class="button home _button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')"><i class="ti ti-home"></i></button>
+		<button class="button notifications _button" @click="mainRouter.push('/my/notifications')"><i class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" class="indicator"><i class="_indicatorCircle"></i></span></button>
+		<button class="button widget _button" @click="widgetsShowing = true"><i class="ti ti-layout-list"></i></button>
+		<button class="button post _button" @click="os.post()"><i class="ti ti-pencil"></i></button>
 	</div>
 
 	<transition :name="$store.state.animation ? 'menuDrawer-back' : ''">
@@ -149,7 +149,7 @@ const onContextmenu = (ev) => {
 		type: 'label',
 		text: path,
 	}, {
-		icon: 'fas fa-window-maximize',
+		icon: 'ti ti-window-maximize',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(path);
diff --git a/packages/client/src/ui/universal.widgets.vue b/packages/client/src/ui/universal.widgets.vue
index 179f8a6baa..33fb492836 100644
--- a/packages/client/src/ui/universal.widgets.vue
+++ b/packages/client/src/ui/universal.widgets.vue
@@ -2,8 +2,8 @@
 <div class="efzpzdvf">
 	<XWidgets :edit="editMode" :widgets="defaultStore.reactiveState.widgets.value" @add-widget="addWidget" @remove-widget="removeWidget" @update-widget="updateWidget" @update-widgets="updateWidgets" @exit="editMode = false"/>
 
-	<button v-if="editMode" class="_textButton" style="font-size: 0.9em;" @click="editMode = false"><i class="fas fa-check"></i> {{ i18n.ts.editWidgetsExit }}</button>
-	<button v-else class="_textButton mk-widget-edit" style="font-size: 0.9em;" @click="editMode = true"><i class="fas fa-pencil-alt"></i> {{ i18n.ts.editWidgets }}</button>
+	<button v-if="editMode" class="_textButton" style="font-size: 0.9em;" @click="editMode = false"><i class="ti ti-check"></i> {{ i18n.ts.editWidgetsExit }}</button>
+	<button v-else class="_textButton mk-widget-edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ti ti-pencil"></i> {{ i18n.ts.editWidgets }}</button>
 </div>
 </template>
 
diff --git a/packages/client/src/ui/visitor/b.vue b/packages/client/src/ui/visitor/b.vue
index 3c308cfe5b..275008a8f8 100644
--- a/packages/client/src/ui/visitor/b.vue
+++ b/packages/client/src/ui/visitor/b.vue
@@ -32,10 +32,10 @@
 
 	<transition :name="$store.state.animation ? 'tray' : ''">
 		<div v-if="showMenu" class="menu">
-			<MkA to="/" class="link" active-class="active"><i class="fas fa-home icon"></i>{{ $ts.home }}</MkA>
-			<MkA to="/explore" class="link" active-class="active"><i class="fas fa-hashtag icon"></i>{{ $ts.explore }}</MkA>
+			<MkA to="/" class="link" active-class="active"><i class="ti ti-home icon"></i>{{ $ts.home }}</MkA>
+			<MkA to="/explore" class="link" active-class="active"><i class="ti ti-hash icon"></i>{{ $ts.explore }}</MkA>
 			<MkA to="/featured" class="link" active-class="active"><i class="fas fa-fire-alt icon"></i>{{ $ts.featured }}</MkA>
-			<MkA to="/channels" class="link" active-class="active"><i class="fas fa-satellite-dish icon"></i>{{ $ts.channel }}</MkA>
+			<MkA to="/channels" class="link" active-class="active"><i class="ti ti-device-tv icon"></i>{{ $ts.channel }}</MkA>
 			<div class="action">
 				<button class="_buttonPrimary" @click="signup()">{{ $ts.signup }}</button>
 				<button class="_button" @click="signin()">{{ $ts.login }}</button>
diff --git a/packages/client/src/ui/visitor/header.vue b/packages/client/src/ui/visitor/header.vue
index e2b9034851..7300b12a75 100644
--- a/packages/client/src/ui/visitor/header.vue
+++ b/packages/client/src/ui/visitor/header.vue
@@ -2,10 +2,10 @@
 <div class="sqxihjet">
 	<div v-if="narrow === false" class="wide">
 		<div class="content">
-			<MkA to="/" class="link" active-class="active"><i class="fas fa-home icon"></i>{{ $ts.home }}</MkA>
-			<MkA to="/explore" class="link" active-class="active"><i class="fas fa-hashtag icon"></i>{{ $ts.explore }}</MkA>
+			<MkA to="/" class="link" active-class="active"><i class="ti ti-home icon"></i>{{ $ts.home }}</MkA>
+			<MkA to="/explore" class="link" active-class="active"><i class="ti ti-hash icon"></i>{{ $ts.explore }}</MkA>
 			<MkA to="/featured" class="link" active-class="active"><i class="fas fa-fire-alt icon"></i>{{ $ts.featured }}</MkA>
-			<MkA to="/channels" class="link" active-class="active"><i class="fas fa-satellite-dish icon"></i>{{ $ts.channel }}</MkA>
+			<MkA to="/channels" class="link" active-class="active"><i class="ti ti-device-tv icon"></i>{{ $ts.channel }}</MkA>
 			<div v-if="info" class="page active link">
 				<div class="title">
 					<i v-if="info.icon" class="icon" :class="info.icon"></i>
@@ -16,7 +16,7 @@
 				<button v-if="info.action" class="_button action" @click.stop="info.action.handler"><!-- TODO --></button>
 			</div>
 			<div class="right">
-				<button class="_button search" @click="search()"><i class="fas fa-search icon"></i><span>{{ $ts.search }}</span></button>
+				<button class="_button search" @click="search()"><i class="ti ti-search icon"></i><span>{{ $ts.search }}</span></button>
 				<button class="_buttonPrimary signup" @click="signup()">{{ $ts.signup }}</button>
 				<button class="_button login" @click="signin()">{{ $ts.login }}</button>
 			</div>
@@ -24,7 +24,7 @@
 	</div>
 	<div v-else-if="narrow === true" class="narrow">
 		<button class="menu _button" @click="$parent.showMenu = true">
-			<i class="fas fa-bars icon"></i>
+			<i class="ti ti-menu-2 icon"></i>
 		</button>
 		<div v-if="info" class="title">
 			<i v-if="info.icon" class="icon" :class="info.icon"></i>
@@ -49,7 +49,7 @@ import { search } from '@/scripts/search';
 export default defineComponent({
 	props: {
 		info: {
-			required: true
+			required: true,
 		},
 	},
 
@@ -67,18 +67,18 @@ export default defineComponent({
 	methods: {
 		signin() {
 			os.popup(XSigninDialog, {
-				autoSet: true
+				autoSet: true,
 			}, {}, 'closed');
 		},
 
 		signup() {
 			os.popup(XSignupDialog, {
-				autoSet: true
+				autoSet: true,
 			}, {}, 'closed');
 		},
 
-		search
-	}
+		search,
+	},
 });
 </script>
 
diff --git a/packages/client/src/widgets/activity.vue b/packages/client/src/widgets/activity.vue
index acca21bff6..238a05ca09 100644
--- a/packages/client/src/widgets/activity.vue
+++ b/packages/client/src/widgets/activity.vue
@@ -1,7 +1,7 @@
 <template>
 <MkContainer :show-header="widgetProps.showHeader" :naked="widgetProps.transparent" class="mkw-activity">
-	<template #header><i class="fas fa-chart-simple"></i>{{ i18n.ts._widgets.activity }}</template>
-	<template #func><button class="_button" @click="toggleView()"><i class="fas fa-sort"></i></button></template>
+	<template #header><i class="ti ti-chart-line"></i>{{ i18n.ts._widgets.activity }}</template>
+	<template #func><button class="_button" @click="toggleView()"><i class="ti ti-selector"></i></button></template>
 
 	<div>
 		<MkLoading v-if="fetching"/>
diff --git a/packages/client/src/widgets/aiscript.vue b/packages/client/src/widgets/aiscript.vue
index cb6d29cd99..4009edb8b8 100644
--- a/packages/client/src/widgets/aiscript.vue
+++ b/packages/client/src/widgets/aiscript.vue
@@ -1,6 +1,6 @@
 <template>
 <MkContainer :show-header="widgetProps.showHeader" class="mkw-aiscript">
-	<template #header><i class="fas fa-terminal"></i>{{ i18n.ts._widgets.aiscript }}</template>
+	<template #header><i class="ti ti-terminal-2"></i>{{ i18n.ts._widgets.aiscript }}</template>
 
 	<div class="uylguesu _monospace">
 		<textarea v-model="widgetProps.script" placeholder="(1 + 1)"></textarea>
diff --git a/packages/client/src/widgets/federation.vue b/packages/client/src/widgets/federation.vue
index d0f81c1356..3374783b0c 100644
--- a/packages/client/src/widgets/federation.vue
+++ b/packages/client/src/widgets/federation.vue
@@ -1,6 +1,6 @@
 <template>
 <MkContainer :show-header="widgetProps.showHeader" :foldable="foldable" :scrollable="scrollable" class="mkw-federation">
-	<template #header><i class="fas fa-globe"></i>{{ i18n.ts._widgets.federation }}</template>
+	<template #header><i class="ti ti-whirl"></i>{{ i18n.ts._widgets.federation }}</template>
 
 	<div class="wbrkwalb">
 		<MkLoading v-if="fetching"/>
diff --git a/packages/client/src/widgets/job-queue.vue b/packages/client/src/widgets/job-queue.vue
index 363d1b3ea0..9f19c51825 100644
--- a/packages/client/src/widgets/job-queue.vue
+++ b/packages/client/src/widgets/job-queue.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="mkw-jobQueue _monospace" :class="{ _panel: !widgetProps.transparent }">
 	<div class="inbox">
-		<div class="label">Inbox queue<i v-if="current.inbox.waiting > 0" class="fas fa-exclamation-triangle icon"></i></div>
+		<div class="label">Inbox queue<i v-if="current.inbox.waiting > 0" class="ti ti-alert-triangle icon"></i></div>
 		<div class="values">
 			<div>
 				<div>Process</div>
@@ -22,7 +22,7 @@
 		</div>
 	</div>
 	<div class="deliver">
-		<div class="label">Deliver queue<i v-if="current.deliver.waiting > 0" class="fas fa-exclamation-triangle icon"></i></div>
+		<div class="label">Deliver queue<i v-if="current.deliver.waiting > 0" class="ti ti-alert-triangle icon"></i></div>
 		<div class="values">
 			<div>
 				<div>Process</div>
diff --git a/packages/client/src/widgets/notifications.vue b/packages/client/src/widgets/notifications.vue
index 2729c310a0..e697209444 100644
--- a/packages/client/src/widgets/notifications.vue
+++ b/packages/client/src/widgets/notifications.vue
@@ -1,7 +1,7 @@
 <template>
 <MkContainer :style="`height: ${widgetProps.height}px;`" :show-header="widgetProps.showHeader" :scrollable="true" class="mkw-notifications">
-	<template #header><i class="fas fa-bell"></i>{{ i18n.ts.notifications }}</template>
-	<template #func><button class="_button" @click="configureNotification()"><i class="fas fa-cog"></i></button></template>
+	<template #header><i class="ti ti-bell"></i>{{ i18n.ts.notifications }}</template>
+	<template #func><button class="_button" @click="configureNotification()"><i class="ti ti-settings"></i></button></template>
 
 	<div>
 		<XNotifications :include-types="widgetProps.includingTypes"/>
diff --git a/packages/client/src/widgets/rss-ticker.vue b/packages/client/src/widgets/rss-ticker.vue
index 82a2f59ae9..44c21d1836 100644
--- a/packages/client/src/widgets/rss-ticker.vue
+++ b/packages/client/src/widgets/rss-ticker.vue
@@ -1,7 +1,7 @@
 <template>
 <MkContainer :naked="widgetProps.transparent" :show-header="widgetProps.showHeader" class="mkw-rss-ticker">
-	<template #header><i class="fas fa-rss-square"></i>RSS</template>
-	<template #func><button class="_button" @click="configure"><i class="fas fa-cog"></i></button></template>
+	<template #header><i class="ti ti-rss"></i>RSS</template>
+	<template #func><button class="_button" @click="configure"><i class="ti ti-settings"></i></button></template>
 
 	<div class="ekmkgxbk">
 		<MkLoading v-if="fetching"/>
diff --git a/packages/client/src/widgets/rss.vue b/packages/client/src/widgets/rss.vue
index f392a8249a..c0338c8e47 100644
--- a/packages/client/src/widgets/rss.vue
+++ b/packages/client/src/widgets/rss.vue
@@ -1,7 +1,7 @@
 <template>
 <MkContainer :show-header="widgetProps.showHeader" class="mkw-rss">
-	<template #header><i class="fas fa-rss-square"></i>RSS</template>
-	<template #func><button class="_button" @click="configure"><i class="fas fa-cog"></i></button></template>
+	<template #header><i class="ti ti-rss"></i>RSS</template>
+	<template #func><button class="_button" @click="configure"><i class="ti ti-settings"></i></button></template>
 
 	<div class="ekmkgxbj">
 		<MkLoading v-if="fetching"/>
diff --git a/packages/client/src/widgets/server-metric/cpu.vue b/packages/client/src/widgets/server-metric/cpu.vue
index baf802cb8f..e7b2226d1f 100644
--- a/packages/client/src/widgets/server-metric/cpu.vue
+++ b/packages/client/src/widgets/server-metric/cpu.vue
@@ -2,7 +2,7 @@
 <div class="vrvdvrys">
 	<XPie class="pie" :value="usage"/>
 	<div>
-		<p><i class="fas fa-microchip"></i>CPU</p>
+		<p><i class="ti ti-cpu"></i>CPU</p>
 		<p>{{ meta.cpu.cores }} Logical cores</p>
 		<p>{{ meta.cpu.model }}</p>
 	</div>
diff --git a/packages/client/src/widgets/server-metric/disk.vue b/packages/client/src/widgets/server-metric/disk.vue
index 052991b554..3d22d05383 100644
--- a/packages/client/src/widgets/server-metric/disk.vue
+++ b/packages/client/src/widgets/server-metric/disk.vue
@@ -2,7 +2,7 @@
 <div class="zbwaqsat">
 	<XPie class="pie" :value="usage"/>
 	<div>
-		<p><i class="fas fa-hdd"></i>Disk</p>
+		<p><i class="ti ti-database"></i>Disk</p>
 		<p>Total: {{ bytes(total, 1) }}</p>
 		<p>Free: {{ bytes(available, 1) }}</p>
 		<p>Used: {{ bytes(used, 1) }}</p>
diff --git a/packages/client/src/widgets/server-metric/index.vue b/packages/client/src/widgets/server-metric/index.vue
index cf4accfa2c..bc3fca6fc1 100644
--- a/packages/client/src/widgets/server-metric/index.vue
+++ b/packages/client/src/widgets/server-metric/index.vue
@@ -1,7 +1,7 @@
 <template>
 <MkContainer :show-header="widgetProps.showHeader" :naked="widgetProps.transparent">
-	<template #header><i class="fas fa-server"></i>{{ i18n.ts._widgets.serverMetric }}</template>
-	<template #func><button class="_button" @click="toggleView()"><i class="fas fa-sort"></i></button></template>
+	<template #header><i class="ti ti-server"></i>{{ i18n.ts._widgets.serverMetric }}</template>
+	<template #func><button class="_button" @click="toggleView()"><i class="ti ti-selector"></i></button></template>
 
 	<div v-if="meta" class="mkw-serverMetric">
 		<XCpuMemory v-if="widgetProps.view === 0" :connection="connection" :meta="meta"/>
diff --git a/packages/client/src/widgets/timeline.vue b/packages/client/src/widgets/timeline.vue
index 718162667d..b22d3e445b 100644
--- a/packages/client/src/widgets/timeline.vue
+++ b/packages/client/src/widgets/timeline.vue
@@ -2,14 +2,14 @@
 <MkContainer :show-header="widgetProps.showHeader" :style="`height: ${widgetProps.height}px;`" :scrollable="true" class="mkw-timeline">
 	<template #header>
 		<button class="_button" @click="choose">
-			<i v-if="widgetProps.src === 'home'" class="fas fa-home"></i>
-			<i v-else-if="widgetProps.src === 'local'" class="fas fa-comments"></i>
-			<i v-else-if="widgetProps.src === 'social'" class="fas fa-share-alt"></i>
-			<i v-else-if="widgetProps.src === 'global'" class="fas fa-globe"></i>
-			<i v-else-if="widgetProps.src === 'list'" class="fas fa-list-ul"></i>
-			<i v-else-if="widgetProps.src === 'antenna'" class="fas fa-satellite"></i>
+			<i v-if="widgetProps.src === 'home'" class="ti ti-home"></i>
+			<i v-else-if="widgetProps.src === 'local'" class="ti ti-messages"></i>
+			<i v-else-if="widgetProps.src === 'social'" class="ti ti-share"></i>
+			<i v-else-if="widgetProps.src === 'global'" class="ti ti-world"></i>
+			<i v-else-if="widgetProps.src === 'list'" class="ti ti-list"></i>
+			<i v-else-if="widgetProps.src === 'antenna'" class="ti ti-antenna"></i>
 			<span style="margin-left: 8px;">{{ widgetProps.src === 'list' ? widgetProps.list.name : widgetProps.src === 'antenna' ? widgetProps.antenna.name : $t('_timelines.' + widgetProps.src) }}</span>
-			<i :class="menuOpened ? 'fas fa-angle-up' : 'fas fa-angle-down'" style="margin-left: 8px;"></i>
+			<i :class="menuOpened ? 'ti ti-chevron-up' : 'ti ti-chevron-down'" style="margin-left: 8px;"></i>
 		</button>
 	</template>
 
@@ -86,7 +86,7 @@ const choose = async (ev) => {
 	]);
 	const antennaItems = antennas.map(antenna => ({
 		text: antenna.name,
-		icon: 'fas fa-satellite',
+		icon: 'ti ti-antenna',
 		action: () => {
 			widgetProps.antenna = antenna;
 			setSrc('antenna');
@@ -94,7 +94,7 @@ const choose = async (ev) => {
 	}));
 	const listItems = lists.map(list => ({
 		text: list.name,
-		icon: 'fas fa-list-ul',
+		icon: 'ti ti-list',
 		action: () => {
 			widgetProps.list = list;
 			setSrc('list');
@@ -102,19 +102,19 @@ const choose = async (ev) => {
 	}));
 	os.popupMenu([{
 		text: i18n.ts._timelines.home,
-		icon: 'fas fa-home',
+		icon: 'ti ti-home',
 		action: () => { setSrc('home'); }
 	}, {
 		text: i18n.ts._timelines.local,
-		icon: 'fas fa-comments',
+		icon: 'ti ti-messages',
 		action: () => { setSrc('local'); }
 	}, {
 		text: i18n.ts._timelines.social,
-		icon: 'fas fa-share-alt',
+		icon: 'ti ti-share',
 		action: () => { setSrc('social'); }
 	}, {
 		text: i18n.ts._timelines.global,
-		icon: 'fas fa-globe',
+		icon: 'ti ti-world',
 		action: () => { setSrc('global'); }
 	}, antennaItems.length > 0 ? null : undefined, ...antennaItems, listItems.length > 0 ? null : undefined, ...listItems], ev.currentTarget ?? ev.target).then(() => {
 		menuOpened.value = false;
diff --git a/packages/client/src/widgets/trends.vue b/packages/client/src/widgets/trends.vue
index a783c04215..02eec0431e 100644
--- a/packages/client/src/widgets/trends.vue
+++ b/packages/client/src/widgets/trends.vue
@@ -1,6 +1,6 @@
 <template>
 <MkContainer :show-header="widgetProps.showHeader" class="mkw-trends">
-	<template #header><i class="fas fa-hashtag"></i>{{ i18n.ts._widgets.trends }}</template>
+	<template #header><i class="ti ti-hash"></i>{{ i18n.ts._widgets.trends }}</template>
 
 	<div class="wbrkwala">
 		<MkLoading v-if="fetching"/>
diff --git a/yarn.lock b/yarn.lock
index ac5b67c9f2..e2d2dea8f8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -973,13 +973,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@fortawesome/fontawesome-free@npm:6.1.2":
-  version: 6.1.2
-  resolution: "@fortawesome/fontawesome-free@npm:6.1.2"
-  checksum: 0d3c9d60ffbb9c1fa4041051eff6542adc1fc29653501399d0235c077a2195a35f286d979da42fe021f73649032f9eeae2c9a0511eaacda2896559155d40a0fc
-  languageName: node
-  linkType: hard
-
 "@gar/promisify@npm:^1.1.3":
   version: 1.1.3
   resolution: "@gar/promisify@npm:1.1.3"
@@ -1986,6 +1979,21 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@tabler/icons@npm:^1.117.0":
+  version: 1.117.0
+  resolution: "@tabler/icons@npm:1.117.0"
+  peerDependencies:
+    react: ^16.x || 17.x || 18.x
+    react-dom: ^16.x || 17.x || 18.x
+  peerDependenciesMeta:
+    react:
+      optional: true
+    react-dom:
+      optional: true
+  checksum: bdb18d36bd554bef86b50d59bd659f951a7cd7bab7a7b8155d573d2a584e5fba04e44fa7e2e4c998a0869619de6fc0a922424d4486ddc9273bee3c8ae65ccf12
+  languageName: node
+  linkType: hard
+
 "@tensorflow/tfjs-backend-cpu@npm:4.1.0":
   version: 4.1.0
   resolution: "@tensorflow/tfjs-backend-cpu@npm:4.1.0"
@@ -5101,11 +5109,11 @@ __metadata:
   resolution: "client@workspace:packages/client"
   dependencies:
     "@discordapp/twemoji": 14.0.2
-    "@fortawesome/fontawesome-free": 6.1.2
     "@rollup/plugin-alias": 4.0.2
     "@rollup/plugin-json": 6.0.0
     "@rollup/pluginutils": 5.0.2
     "@syuilo/aiscript": 0.11.1
+    "@tabler/icons": ^1.117.0
     "@types/escape-regexp": 0.0.1
     "@types/glob": 8.0.0
     "@types/gulp": 4.0.10