diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js
index 48939ef7a0..570b15da03 100644
--- a/packages/backend/src/server/web/boot.js
+++ b/packages/backend/src/server/web/boot.js
@@ -228,7 +228,7 @@
 		}
 
 		button {
-			border-radius: 999px;
+			border-radius: 4px;
 			padding: 0px 12px 0px 12px;
 			border: none;
 			cursor: pointer;
@@ -296,7 +296,7 @@
 			margin-bottom: 2rem;
 			padding: 0.5rem 1rem;
 			width: 40rem;
-			border-radius: 10px;
+			border-radius: 5px;
 			justify-content: center;
 			margin: auto;
 		}
diff --git a/packages/backend/src/server/web/error.css b/packages/backend/src/server/web/error.css
index ea3056bdaf..8bad3d843e 100644
--- a/packages/backend/src/server/web/error.css
+++ b/packages/backend/src/server/web/error.css
@@ -24,7 +24,7 @@ html {
 }
 
 button {
-    border-radius: 999px;
+    border-radius: 4px;
     padding: 0px 12px 0px 12px;
     border: none;
     cursor: pointer;
@@ -93,7 +93,7 @@ code {
     background: #333;
     padding: 0.5rem 1rem;
     max-width: 40rem;
-    border-radius: 10px;
+    border-radius: 5px;
     justify-content: center;
     margin: auto;
     white-space: pre-wrap;
diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug
index 5119a19ca6..af0352357c 100644
--- a/packages/backend/src/server/web/views/base.pug
+++ b/packages/backend/src/server/web/views/base.pug
@@ -39,7 +39,7 @@ html
 		link(rel='prefetch' href=infoImageUrl)
 		link(rel='prefetch' href=notFoundImageUrl)
 		//- https://github.com/misskey-dev/misskey/issues/9842
-		link(rel='stylesheet' href='/assets/phosphor-icons/regular/style.css')
+		link(rel='stylesheet' href='/assets/phosphor-icons/bold/style.css')
 		link(rel='modulepreload' href=`/vite/${clientEntry.file}`)
 
 		if !config.clientManifestExists
diff --git a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts
index a7b8cbb037..3640b656b4 100644
--- a/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts
+++ b/packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts
@@ -63,7 +63,7 @@ import { M as MkContainer } from './MkContainer-!~{03M}~.js';
 import { b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode } from './vue-!~{002}~.js';
 import './photoswipe-!~{003}~.js';
 
-const _hoisted_1 = /* @__PURE__ */ createBaseVNode("i", { class: "ti ti-photo" }, null, -1);
+const _hoisted_1 = /* @__PURE__ */ createBaseVNode("i", { class: "ph-image-square ph-bold ph-lg" }, null, -1);
 const _sfc_main = /* @__PURE__ */ defineComponent({
   __name: "index.photos",
   props: {
@@ -179,7 +179,7 @@ import {M as MkContainer} from './MkContainer-!~{03M}~.js';
 import {b as defineComponent, a as ref, e as onMounted, z as resolveComponent, g as openBlock, h as createBlock, i as withCtx, K as createTextVNode, E as toDisplayString, u as unref, l as createBaseVNode, q as normalizeClass, B as createCommentVNode, k as createElementBlock, F as Fragment, C as renderList, A as createVNode} from './vue-!~{002}~.js';
 import './photoswipe-!~{003}~.js';
 const _hoisted_1 = createBaseVNode("i", {
-  class: "ti ti-photo"
+  class: "ph-image-square ph-bold ph-lg"
 }, null, -1);
 const _sfc_main = defineComponent({
   __name: "index.photos",
@@ -348,7 +348,7 @@ const _sfc_main = defineComponent({
             class: $style["date-1"]
           }, [
             h("i", {
-              class: \`ti ti-chevron-up \${$style["date-1-icon"]}\`
+              class: \`ph-caret-up ph-bold ph-lg \${$style["date-1-icon"]}\`
             }),
             getDateText(item.createdAt)
           ]),
@@ -357,7 +357,7 @@ const _sfc_main = defineComponent({
           }, [
             getDateText(props.items[i + 1].createdAt),
             h("i", {
-              class: \`ti ti-chevron-down \${$style["date-2-icon"]}\`
+              class: \`ph-caret-down ph-bold ph-lg \${$style["date-2-icon"]}\`
             })
           ])
         ]));
@@ -514,11 +514,11 @@ const _sfc_main = defineComponent({
         }, [h("span", {
           class: $style["date-1"]
         }, [h("i", {
-          class: \`ti ti-chevron-up \${$style["date-1-icon"]}\`
+          class: \`ph-caret-up ph-bold ph-lg \${$style["date-1-icon"]}\`
         }), getDateText(item.createdAt)]), h("span", {
           class: $style["date-2"]
         }, [getDateText(props.items[i + 1].createdAt), h("i", {
-          class: \`ti ti-chevron-down \${$style["date-2-icon"]}\`
+          class: \`ph-caret-down ph-bold ph-lg \${$style["date-2-icon"]}\`
         })])]));
         return [el, separator];
       } else {
diff --git a/packages/frontend/src/account.ts b/packages/frontend/src/account.ts
index c17be6fc62..f19cad331b 100644
--- a/packages/frontend/src/account.ts
+++ b/packages/frontend/src/account.ts
@@ -286,7 +286,7 @@ export async function openAccountMenu(opts: {
 			avatar: $i,
 		}, null, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, {
 			type: 'parent' as const,
-			icon: 'ti ti-plus',
+			icon: 'ph-plus ph-bold ph-lg',
 			text: i18n.ts.addAccount,
 			children: [{
 				text: i18n.ts.existingAccount,
@@ -297,12 +297,12 @@ export async function openAccountMenu(opts: {
 			}],
 		}, {
 			type: 'link' as const,
-			icon: 'ti ti-users',
+			icon: 'ph-users ph-bold ph-lg',
 			text: i18n.ts.manageAccounts,
 			to: '/settings/accounts',
 		}, {
 			type: 'button' as const,
-			icon: 'ti ti-power',
+			icon: 'ph-power ph-bold ph-lg',
 			text: i18n.ts.logout,
 			action: () => { signout(); },
 		}]], ev.currentTarget ?? ev.target, {
diff --git a/packages/frontend/src/components/MkAbuseReport.vue b/packages/frontend/src/components/MkAbuseReport.vue
index 66114b8734..1ef8a205e2 100644
--- a/packages/frontend/src/components/MkAbuseReport.vue
+++ b/packages/frontend/src/components/MkAbuseReport.vue
@@ -84,7 +84,7 @@ function resolve() {
 			box-sizing: border-box;
 			align-items: center;
 			padding: 14px;
-			border-radius: 8px;
+			border-radius: 5px;
 			--c: rgb(255 196 0 / 15%);
 			background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
 			background-size: 16px 16px;
diff --git a/packages/frontend/src/components/MkAbuseReportWindow.vue b/packages/frontend/src/components/MkAbuseReportWindow.vue
index 7814681ea2..6819630b74 100644
--- a/packages/frontend/src/components/MkAbuseReportWindow.vue
+++ b/packages/frontend/src/components/MkAbuseReportWindow.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <MkWindow ref="uiWindow" :initialWidth="400" :initialHeight="500" :canResize="true" @closed="emit('closed')">
 	<template #header>
-		<i class="ti ti-exclamation-circle" style="margin-right: 0.5em;"></i>
+		<i class="ph-warning-circle ph-bold ph-lg" style="margin-right: 0.5em;"></i>
 		<I18n :src="i18n.ts.reportAbuseOf" tag="span">
 			<template #name>
 				<b><MkAcct :user="user"/></b>
diff --git a/packages/frontend/src/components/MkAccountMoved.vue b/packages/frontend/src/components/MkAccountMoved.vue
index 155d9fe3a9..6c66adc691 100644
--- a/packages/frontend/src/components/MkAccountMoved.vue
+++ b/packages/frontend/src/components/MkAccountMoved.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div v-if="user" :class="$style.root">
-	<i class="ti ti-plane-departure" style="margin-right: 8px;"></i>
+	<i class="ph-plane-takeoff ph-bold ph-lg" style="margin-right: 8px;"></i>
 	{{ i18n.ts.accountMoved }}
 	<MkMention :class="$style.link" :username="user.username" :host="user.host ?? localHost"/>
 </div>
diff --git a/packages/frontend/src/components/MkAnnouncementDialog.vue b/packages/frontend/src/components/MkAnnouncementDialog.vue
index aaac3dd29b..4c6e3e693a 100644
--- a/packages/frontend/src/components/MkAnnouncementDialog.vue
+++ b/packages/frontend/src/components/MkAnnouncementDialog.vue
@@ -8,10 +8,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div ref="rootEl" :class="$style.root">
 		<div :class="$style.header">
 			<span :class="$style.icon">
-				<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
-				<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
-				<i v-else-if="announcement.icon === 'error'" class="ti ti-circle-x" style="color: var(--error);"></i>
-				<i v-else-if="announcement.icon === 'success'" class="ti ti-check" style="color: var(--success);"></i>
+				<i v-if="announcement.icon === 'info'" class="ph-info ph-bold ph-lg"></i>
+				<i v-else-if="announcement.icon === 'warning'" class="ph-warning-circle ph-bold ph-lg" style="color: var(--warn);"></i>
+				<i v-else-if="announcement.icon === 'error'" class="ph-seal-warning ph-bold ph-lg" style="color: var(--error);"></i>
+				<i v-else-if="announcement.icon === 'success'" class="ph-check-circle ph-bold ph-lg" style="color: var(--success);"></i>
 			</span>
 			<span :class="$style.title">{{ announcement.title }}</span>
 		</div>
diff --git a/packages/frontend/src/components/MkAsUi.vue b/packages/frontend/src/components/MkAsUi.vue
index 099baf0d72..3eb020c50e 100644
--- a/packages/frontend/src/components/MkAsUi.vue
+++ b/packages/frontend/src/components/MkAsUi.vue
@@ -125,6 +125,6 @@ function openPostForm() {
 
 .postForm {
 	background: var(--bg);
-	border-radius: 8px;
+	border-radius: 5px;
 }
 </style>
diff --git a/packages/frontend/src/components/MkButton.vue b/packages/frontend/src/components/MkButton.vue
index bcd58ae516..3801d6b5d4 100644
--- a/packages/frontend/src/components/MkButton.vue
+++ b/packages/frontend/src/components/MkButton.vue
@@ -154,7 +154,7 @@ function onMousedown(evt: MouseEvent): void {
 	}
 
 	&.rounded {
-		border-radius: 999px;
+		border-radius: 4px;
 	}
 
 	&.primary {
@@ -264,7 +264,7 @@ function onMousedown(evt: MouseEvent): void {
 	left: 0;
 	width: 100%;
 	height: 100%;
-	border-radius: 6px;
+	border-radius: 5px;
 	overflow: clip;
 	pointer-events: none;
 }
diff --git a/packages/frontend/src/components/MkChannelFollowButton.vue b/packages/frontend/src/components/MkChannelFollowButton.vue
index 41b02a7e3f..13c0dd65dd 100644
--- a/packages/frontend/src/components/MkChannelFollowButton.vue
+++ b/packages/frontend/src/components/MkChannelFollowButton.vue
@@ -12,10 +12,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 >
 	<template v-if="!wait">
 		<template v-if="isFollowing">
-			<span v-if="full" :class="$style.text">{{ i18n.ts.unfollow }}</span><i class="ti ti-minus"></i>
+			<span v-if="full" :class="$style.text">{{ i18n.ts.unfollow }}</span><i class="ph-minus ph-bold ph-lg"></i>
 		</template>
 		<template v-else>
-			<span v-if="full" :class="$style.text">{{ i18n.ts.follow }}</span><i class="ti ti-plus"></i>
+			<span v-if="full" :class="$style.text">{{ i18n.ts.follow }}</span><i class="ph-plus ph-bold ph-lg"></i>
 		</template>
 	</template>
 	<template v-else>
diff --git a/packages/frontend/src/components/MkChannelPreview.vue b/packages/frontend/src/components/MkChannelPreview.vue
index 4512f2dd60..6429258f4a 100644
--- a/packages/frontend/src/components/MkChannelPreview.vue
+++ b/packages/frontend/src/components/MkChannelPreview.vue
@@ -7,11 +7,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 <MkA :to="`/channels/${channel.id}`" class="eftoefju _panel" tabindex="-1">
 	<div class="banner" :style="bannerStyle">
 		<div class="fade"></div>
-		<div class="name"><i class="ti ti-device-tv"></i> {{ channel.name }}</div>
+		<div class="name"><i class="ph-television ph-bold ph-lg"></i> {{ channel.name }}</div>
 		<div v-if="channel.isSensitive" class="sensitiveIndicator">{{ i18n.ts.sensitive }}</div>
 		<div class="status">
 			<div>
-				<i class="ti ti-users ti-fw"></i>
+				<i class="ph-users ph-bold ph-lg"></i>
 				<I18n :src="i18n.ts._channel.usersCount" tag="span" style="margin-left: 4px;">
 					<template #n>
 						<b>{{ channel.usersCount }}</b>
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</I18n>
 			</div>
 			<div>
-				<i class="ti ti-pencil ti-fw"></i>
+				<i class="ph-pencil ph-bold ph-lg"></i>
 				<I18n :src="i18n.ts._channel.notesCount" tag="span" style="margin-left: 4px;">
 					<template #n>
 						<b>{{ channel.notesCount }}</b>
@@ -100,7 +100,7 @@ const bannerStyle = computed(() => {
 			padding: 8px 12px;
 			font-size: 80%;
 			background: rgba(0, 0, 0, 0.7);
-			border-radius: 6px;
+			border-radius: 5px;
 			color: #fff;
 		}
 
@@ -111,7 +111,7 @@ const bannerStyle = computed(() => {
 			left: 16px;
 			background: rgba(0, 0, 0, 0.7);
 			color: var(--warn);
-			border-radius: 6px;
+			border-radius: 5px;
 			font-weight: bold;
 			font-size: 1em;
 			padding: 4px 7px;
diff --git a/packages/frontend/src/components/MkChartLegend.vue b/packages/frontend/src/components/MkChartLegend.vue
index d321114cba..2e83d59b59 100644
--- a/packages/frontend/src/components/MkChartLegend.vue
+++ b/packages/frontend/src/components/MkChartLegend.vue
@@ -55,7 +55,7 @@ defineExpose({
 			font-size: 85%;
 			padding: 4px 12px 4px 8px;
 			border: solid 1px var(--divider);
-			border-radius: 999px;
+			border-radius: 4px;
 
 			&:hover {
 				border-color: var(--inputBorderHover);
diff --git a/packages/frontend/src/components/MkClickerGame.vue b/packages/frontend/src/components/MkClickerGame.vue
index 1c3920962e..71914c6886 100644
--- a/packages/frontend/src/components/MkClickerGame.vue
+++ b/packages/frontend/src/components/MkClickerGame.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div>
 	<div v-if="game.ready" :class="$style.game">
 		<div :class="$style.cps" class="">{{ number(cps) }}cps</div>
-		<div :class="$style.count" class=""><i class="ti ti-cookie" style="font-size: 70%;"></i> {{ number(cookies) }}</div>
+		<div :class="$style.count" class=""><i class="ph-cookie ph-bold ph-lg" style="font-size: 70%;"></i> {{ number(cookies) }}</div>
 		<button v-click-anime class="_button" @click="onClick">
 			<img src="/client-assets/cookie.png" :class="$style.img">
 		</button>
diff --git a/packages/frontend/src/components/MkColorInput.vue b/packages/frontend/src/components/MkColorInput.vue
index 983a35103c..4ebfec5b51 100644
--- a/packages/frontend/src/components/MkColorInput.vue
+++ b/packages/frontend/src/components/MkColorInput.vue
@@ -102,7 +102,7 @@ const onInput = (ev: KeyboardEvent) => {
 	color: var(--fg);
 	background: var(--panel);
 	border: solid 1px var(--panel);
-	border-radius: 6px;
+	border-radius: 5px;
 	outline: none;
 	box-shadow: none;
 	box-sizing: border-box;
diff --git a/packages/frontend/src/components/MkContainer.vue b/packages/frontend/src/components/MkContainer.vue
index 659f3a909e..f703db5eb3 100644
--- a/packages/frontend/src/components/MkContainer.vue
+++ b/packages/frontend/src/components/MkContainer.vue
@@ -13,8 +13,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.headerSub">
 			<slot name="func" :buttonStyleClass="$style.headerButton"></slot>
 			<button v-if="foldable" :class="$style.headerButton" class="_button" @click="() => showBody = !showBody">
-				<template v-if="showBody"><i class="ti ti-chevron-up"></i></template>
-				<template v-else><i class="ti ti-chevron-down"></i></template>
+				<template v-if="showBody"><i class="ph-caret-up ph-bold ph-lg"></i></template>
+				<template v-else><i class="ph-caret-down ph-bold ph-lg"></i></template>
 			</button>
 		</div>
 	</header>
@@ -223,7 +223,7 @@ onUnmounted(() => {
 				background: var(--panel);
 				padding: 6px 10px;
 				font-size: 0.8em;
-				border-radius: 999px;
+				border-radius: 4px;
 				box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
 			}
 
diff --git a/packages/frontend/src/components/MkDateSeparatedList.vue b/packages/frontend/src/components/MkDateSeparatedList.vue
index 66d4b542be..e9236b38a1 100644
--- a/packages/frontend/src/components/MkDateSeparatedList.vue
+++ b/packages/frontend/src/components/MkDateSeparatedList.vue
@@ -75,7 +75,7 @@ export default defineComponent({
 						class: $style['date-1'],
 					}, [
 						h('i', {
-							class: `ti ti-chevron-up ${$style['date-1-icon']}`,
+							class: `ph-caret-up ph-bold ph-lg ${$style['date-1-icon']}`,
 						}),
 						getDateText(item.createdAt),
 					]),
@@ -84,7 +84,7 @@ export default defineComponent({
 					}, [
 						getDateText(props.items[i + 1].createdAt),
 						h('i', {
-							class: `ti ti-chevron-down ${$style['date-2-icon']}`,
+							class: `ph-caret-down ph-bold ph-lg ${$style['date-2-icon']}`,
 						}),
 					]),
 				]));
diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue
index a83c18c0b3..118852d717 100644
--- a/packages/frontend/src/components/MkDialog.vue
+++ b/packages/frontend/src/components/MkDialog.vue
@@ -18,17 +18,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 				[$style.type_info]: type === 'info',
 			}]"
 		>
-			<i v-if="type === 'success'" :class="$style.iconInner" class="ti ti-check"></i>
-			<i v-else-if="type === 'error'" :class="$style.iconInner" class="ti ti-circle-x"></i>
-			<i v-else-if="type === 'warning'" :class="$style.iconInner" class="ti ti-alert-triangle"></i>
-			<i v-else-if="type === 'info'" :class="$style.iconInner" class="ti ti-info-circle"></i>
-			<i v-else-if="type === 'question'" :class="$style.iconInner" class="ti ti-help-circle"></i>
+			<i v-if="type === 'success'" :class="$style.iconInner" class="ph-check ph-bold ph-lg"></i>
+			<i v-else-if="type === 'error'" :class="$style.iconInner" class="ph-x-circle ph-bold ph-lg"></i>
+			<i v-else-if="type === 'warning'" :class="$style.iconInner" class="ph-warning ph-bold ph-lg"></i>
+			<i v-else-if="type === 'info'" :class="$style.iconInner" class="ph-info ph-bold ph-lg"></i>
+			<i v-else-if="type === 'question'" :class="$style.iconInner" class="ph-question ph-bold ph-lg"></i>
 			<MkLoading v-else-if="type === 'waiting'" :class="$style.iconInner" :em="true"/>
 		</div>
 		<header v-if="title" :class="$style.title"><Mfm :text="title"/></header>
 		<div v-if="text" :class="$style.text"><Mfm :text="text"/></div>
 		<MkInput v-if="input" v-model="inputValue" autofocus :type="input.type || 'text'" :placeholder="input.placeholder || undefined" :autocomplete="input.autocomplete" @keydown="onInputKeydown">
-			<template v-if="input.type === 'password'" #prefix><i class="ti ti-lock"></i></template>
+			<template v-if="input.type === 'password'" #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 			<template #caption>
 				<span v-if="okButtonDisabled && disabledReason === 'charactersExceeded'" v-text="i18n.t('_dialog.charactersExceeded', { current: (inputValue as string).length, max: input.maxLength ?? 'NaN' })"/>
 				<span v-else-if="okButtonDisabled && disabledReason === 'charactersBelow'" v-text="i18n.t('_dialog.charactersBelow', { current: (inputValue as string).length, min: input.minLength ?? 'NaN' })"/>
@@ -196,7 +196,7 @@ onBeforeUnmount(() => {
 	box-sizing: border-box;
 	text-align: center;
 	background: var(--panel);
-	border-radius: 16px;
+	border-radius: 4px;
 }
 
 .icon {
diff --git a/packages/frontend/src/components/MkDonation.vue b/packages/frontend/src/components/MkDonation.vue
index 01b6dbf59d..d79d48eef7 100644
--- a/packages/frontend/src/components/MkDonation.vue
+++ b/packages/frontend/src/components/MkDonation.vue
@@ -31,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkButton @click="neverShow">{{ i18n.ts.neverShow }}</MkButton>
 		</div>
 	</div>
-	<button class="_button" :class="$style.close" @click="close"><i class="ti ti-x"></i></button>
+	<button class="_button" :class="$style.close" @click="close"><i class="ph-x ph-bold ph-lg"></i></button>
 </div>
 </template>
 
diff --git a/packages/frontend/src/components/MkDrive.file.vue b/packages/frontend/src/components/MkDrive.file.vue
index e3f96724d9..530859bc00 100644
--- a/packages/frontend/src/components/MkDrive.file.vue
+++ b/packages/frontend/src/components/MkDrive.file.vue
@@ -100,7 +100,7 @@ function onDragend() {
 	position: relative;
 	padding: 8px 0 0 0;
 	min-height: 180px;
-	border-radius: 8px;
+	border-radius: 5px;
 	cursor: pointer;
 
 	&:hover {
diff --git a/packages/frontend/src/components/MkDrive.folder.vue b/packages/frontend/src/components/MkDrive.folder.vue
index 5322664664..f352e655ba 100644
--- a/packages/frontend/src/components/MkDrive.folder.vue
+++ b/packages/frontend/src/components/MkDrive.folder.vue
@@ -20,8 +20,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 	@dragend="onDragend"
 >
 	<p :class="$style.name">
-		<template v-if="hover"><i :class="$style.icon" class="ti ti-folder ti-fw"></i></template>
-		<template v-if="!hover"><i :class="$style.icon" class="ti ti-folder ti-fw"></i></template>
+		<template v-if="hover"><i :class="$style.icon" class="ph-folder ph-bold ph-lg ti-fw"></i></template>
+		<template v-if="!hover"><i :class="$style.icon" class="ph-folder ph-bold ph-lg ti-fw"></i></template>
 		{{ folder.name }}
 	</p>
 	<p v-if="defaultStore.state.uploadFolder == folder.id" :class="$style.upload">
@@ -253,7 +253,7 @@ function onContextmenu(ev: MouseEvent) {
 	let menu;
 	menu = [{
 		text: i18n.ts.openInWindow,
-		icon: 'ti ti-app-window',
+		icon: 'ph-app-window ph-bold ph-lg',
 		action: () => {
 			os.popup(defineAsyncComponent(() => import('@/components/MkDriveWindow.vue')), {
 				initialFolder: props.folder,
@@ -262,17 +262,17 @@ function onContextmenu(ev: MouseEvent) {
 		},
 	}, null, {
 		text: i18n.ts.rename,
-		icon: 'ti ti-forms',
+		icon: 'ph-textbox ph-bold ph-lg',
 		action: rename,
 	}, null, {
 		text: i18n.ts.delete,
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		danger: true,
 		action: deleteFolder,
 	}];
 	if (defaultStore.state.devMode) {
 		menu = menu.concat([null, {
-			icon: 'ti ti-id',
+			icon: 'ph-identification-card ph-bold ph-lg',
 			text: i18n.ts.copyFolderId,
 			action: () => {
 				copyToClipboard(props.folder.id);
diff --git a/packages/frontend/src/components/MkDrive.navFolder.vue b/packages/frontend/src/components/MkDrive.navFolder.vue
index 59458ad568..cac3c17c85 100644
--- a/packages/frontend/src/components/MkDrive.navFolder.vue
+++ b/packages/frontend/src/components/MkDrive.navFolder.vue
@@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	@dragleave="onDragleave"
 	@drop.stop="onDrop"
 >
-	<i v-if="folder == null" class="ti ti-cloud" style="margin-right: 4px;"></i>
+	<i v-if="folder == null" class="ph-cloud ph-bold ph-lg" style="margin-right: 4px;"></i>
 	<span>{{ folder == null ? i18n.ts.drive : folder.name }}</span>
 </div>
 </template>
diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index 648e4c4e3d..3fbbd536e5 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				@removeFolder="removeFolder"
 			/>
 			<template v-for="f in hierarchyFolders">
-				<span :class="[$style.navPathItem, $style.navSeparator]"><i class="ti ti-chevron-right"></i></span>
+				<span :class="[$style.navPathItem, $style.navSeparator]"><i class="ph-caret-right ph-bold ph-lg"></i></span>
 				<XNavFolder
 					:folder="f"
 					:parentFolder="folder"
@@ -27,10 +27,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 					@removeFolder="removeFolder"
 				/>
 			</template>
-			<span v-if="folder != null" :class="[$style.navPathItem, $style.navSeparator]"><i class="ti ti-chevron-right"></i></span>
+			<span v-if="folder != null" :class="[$style.navPathItem, $style.navSeparator]"><i class="ph-caret-right ph-bold ph-lg"></i></span>
 			<span v-if="folder != null" :class="[$style.navPathItem, $style.navCurrent]">{{ folder.name }}</span>
 		</div>
-		<button class="_button" :class="$style.navMenu" @click="showMenu"><i class="ti ti-dots"></i></button>
+		<button class="_button" :class="$style.navMenu" @click="showMenu"><i class="ph-dots-three ph-bold ph-lg"></i></button>
 	</nav>
 	<div
 		ref="main"
@@ -620,26 +620,26 @@ function getMenu() {
 		type: 'label',
 	}, {
 		text: i18n.ts.upload,
-		icon: 'ti ti-upload',
+		icon: 'ph-upload ph-bold ph-lg',
 		action: () => { selectLocalFile(); },
 	}, {
 		text: i18n.ts.fromUrl,
-		icon: 'ti ti-link',
+		icon: 'ph-link ph-bold ph-lg',
 		action: () => { urlUpload(); },
 	}, null, {
 		text: folder.value ? folder.value.name : i18n.ts.drive,
 		type: 'label',
 	}, folder.value ? {
 		text: i18n.ts.renameFolder,
-		icon: 'ti ti-forms',
+		icon: 'ph-textbox ph-bold ph-lg',
 		action: () => { renameFolder(folder.value); },
 	} : undefined, folder.value ? {
 		text: i18n.ts.deleteFolder,
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		action: () => { deleteFolder(folder.value as Misskey.entities.DriveFolder); },
 	} : undefined, {
 		text: i18n.ts.createFolder,
-		icon: 'ti ti-folder-plus',
+		icon: 'ph-folder ph-bold ph-lg-plus',
 		action: () => { createFolder(); },
 	}];
 }
diff --git a/packages/frontend/src/components/MkDriveFileThumbnail.vue b/packages/frontend/src/components/MkDriveFileThumbnail.vue
index 5b07fed2d1..66807cf42c 100644
--- a/packages/frontend/src/components/MkDriveFileThumbnail.vue
+++ b/packages/frontend/src/components/MkDriveFileThumbnail.vue
@@ -6,16 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div ref="thumbnail" :class="$style.root">
 	<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="ti ti-photo" :class="$style.icon"></i>
-	<i v-else-if="is === 'video'" class="ti ti-video" :class="$style.icon"></i>
-	<i v-else-if="is === 'audio' || is === 'midi'" class="ti ti-file-music" :class="$style.icon"></i>
-	<i v-else-if="is === 'csv'" class="ti ti-file-text" :class="$style.icon"></i>
-	<i v-else-if="is === 'pdf'" class="ti ti-file-text" :class="$style.icon"></i>
-	<i v-else-if="is === 'textfile'" class="ti ti-file-text" :class="$style.icon"></i>
-	<i v-else-if="is === 'archive'" class="ti ti-file-zip" :class="$style.icon"></i>
-	<i v-else class="ti ti-file" :class="$style.icon"></i>
+	<i v-else-if="is === 'image'" class="ph-image-square ph-bold ph-lg" :class="$style.icon"></i>
+	<i v-else-if="is === 'video'" class="ph-video ph-bold ph-lg" :class="$style.icon"></i>
+	<i v-else-if="is === 'audio' || is === 'midi'" class="ph-file-audio ph-bold ph-lg" :class="$style.icon"></i>
+	<i v-else-if="is === 'csv'" class="ph-file-text ph-bold ph-lg" :class="$style.icon"></i>
+	<i v-else-if="is === 'pdf'" class="ph-file-text ph-bold ph-lg" :class="$style.icon"></i>
+	<i v-else-if="is === 'textfile'" class="ph-file-text ph-bold ph-lg" :class="$style.icon"></i>
+	<i v-else-if="is === 'archive'" class="ph-file-zip ph-bold ph-lg" :class="$style.icon"></i>
+	<i v-else class="ph-file ph-bold ph-lg" :class="$style.icon"></i>
 
-	<i v-if="isThumbnailAvailable && is === 'video'" class="ti ti-video" :class="$style.iconSub"></i>
+	<i v-if="isThumbnailAvailable && is === 'video'" class="ph-video ph-bold ph-lg" :class="$style.iconSub"></i>
 </div>
 </template>
 
@@ -63,7 +63,7 @@ const isThumbnailAvailable = computed(() => {
 	position: relative;
 	display: flex;
 	background: var(--panel);
-	border-radius: 8px;
+	border-radius: 5px;
 	overflow: clip;
 }
 
diff --git a/packages/frontend/src/components/MkEmojiPicker.section.vue b/packages/frontend/src/components/MkEmojiPicker.section.vue
index 08297ea5ba..00e0a0e042 100644
--- a/packages/frontend/src/components/MkEmojiPicker.section.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.section.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <!-- このコンポーネントの要素のclassは親から利用されるのでむやみに弄らないこと -->
 <section>
 	<header class="_acrylic" @click="shown = !shown">
-		<i class="toggle ti-fw" :class="shown ? 'ti ti-chevron-down' : 'ti ti-chevron-up'"></i> <slot></slot> ({{ emojis.length }})
+		<i class="toggle ti-fw" :class="shown ? 'ph-caret-down ph-bold ph-lg' : 'ph-caret-up ph-bold ph-lg'"></i> <slot></slot> ({{ emojis.length }})
 	</header>
 	<div v-if="shown" class="body">
 		<button
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index 32f440ae5d..e56cba5739 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -54,7 +54,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</section>
 
 			<section>
-				<header class="_acrylic"><i class="ti ti-clock ti-fw"></i> {{ i18n.ts.recentUsed }}</header>
+				<header class="_acrylic"><i class="ph-clock ph-bold ph-lg ti-fw"></i> {{ i18n.ts.recentUsed }}</header>
 				<div class="body">
 					<button
 						v-for="emoji in recentlyUsedEmojis"
@@ -88,10 +88,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 	</div>
 	<div class="tabs">
-		<button class="_button tab" :class="{ active: tab === 'index' }" @click="tab = 'index'"><i class="ti ti-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="ti ti-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>
+		<button class="_button tab" :class="{ active: tab === 'index' }" @click="tab = 'index'"><i class="ph-asterisk ph-bold ph-lg ti-fw"></i></button>
+		<button class="_button tab" :class="{ active: tab === 'custom' }" @click="tab = 'custom'"><i class="ph-smiley ph-bold ph-lg ti-fw"></i></button>
+		<button class="_button tab" :class="{ active: tab === 'unicode' }" @click="tab = 'unicode'"><i class="ph-leaf ph-bold ph-lg ti-fw"></i></button>
+		<button class="_button tab" :class="{ active: tab === 'tags' }" @click="tab = 'tags'"><i class="ph-hash ph-bold ph-lg ti-fw"></i></button>
 	</div>
 </div>
 </template>
diff --git a/packages/frontend/src/components/MkFoldableSection.vue b/packages/frontend/src/components/MkFoldableSection.vue
index ed3cb0868b..e889dd3cff 100644
--- a/packages/frontend/src/components/MkFoldableSection.vue
+++ b/packages/frontend/src/components/MkFoldableSection.vue
@@ -9,8 +9,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.title"><div><slot name="header"></slot></div></div>
 		<div :class="$style.divider"></div>
 		<button class="_button" :class="$style.button">
-			<template v-if="showBody"><i class="ti ti-chevron-up"></i></template>
-			<template v-else><i class="ti ti-chevron-down"></i></template>
+			<template v-if="showBody"><i class="ph-caret-up ph-bold ph-lg"></i></template>
+			<template v-else><i class="ph-caret-down ph-bold ph-lg"></i></template>
 		</button>
 	</header>
 	<Transition
diff --git a/packages/frontend/src/components/MkFolder.vue b/packages/frontend/src/components/MkFolder.vue
index 60ecc13056..007c4b329d 100644
--- a/packages/frontend/src/components/MkFolder.vue
+++ b/packages/frontend/src/components/MkFolder.vue
@@ -19,8 +19,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 				<div :class="$style.headerRight">
 					<span :class="$style.headerRightText"><slot name="suffix"></slot></span>
-					<i v-if="opened" class="ti ti-chevron-up icon"></i>
-					<i v-else class="ti ti-chevron-down icon"></i>
+					<i v-if="opened" class="ph-caret-up ph-bold ph-lg icon"></i>
+					<i v-else class="ph-caret-down ph-bold ph-lg icon"></i>
 				</div>
 			</div>
 		</template>
@@ -139,7 +139,7 @@ onMounted(() => {
 	background: var(--buttonBg);
 	-webkit-backdrop-filter: var(--blur, blur(15px));
 	backdrop-filter: var(--blur, blur(15px));
-	border-radius: 6px;
+	border-radius: 5px;
 	transition: border-radius 0.3s;
 
 	&:hover {
diff --git a/packages/frontend/src/components/MkFollowButton.vue b/packages/frontend/src/components/MkFollowButton.vue
index 15043fcd0b..d5df6f5753 100644
--- a/packages/frontend/src/components/MkFollowButton.vue
+++ b/packages/frontend/src/components/MkFollowButton.vue
@@ -12,20 +12,20 @@ SPDX-License-Identifier: AGPL-3.0-only
 >
 	<template v-if="!wait">
 		<template v-if="hasPendingFollowRequestFromYou && user.isLocked">
-			<span v-if="full" :class="$style.text">{{ i18n.ts.followRequestPending }}</span><i class="ti ti-hourglass-empty"></i>
+			<span v-if="full" :class="$style.text">{{ i18n.ts.followRequestPending }}</span><i class="ph-hourglass ph-bold ph-lg"></i>
 		</template>
 		<template v-else-if="hasPendingFollowRequestFromYou && !user.isLocked">
 			<!-- つまりリモートフォローの場合。 -->
 			<span v-if="full" :class="$style.text">{{ i18n.ts.processing }}</span><MkLoading :em="true" :colored="false"/>
 		</template>
 		<template v-else-if="isFollowing">
-			<span v-if="full" :class="$style.text">{{ i18n.ts.unfollow }}</span><i class="ti ti-minus"></i>
+			<span v-if="full" :class="$style.text">{{ i18n.ts.unfollow }}</span><i class="ph-minus ph-bold ph-lg"></i>
 		</template>
 		<template v-else-if="!isFollowing && user.isLocked">
-			<span v-if="full" :class="$style.text">{{ i18n.ts.followRequest }}</span><i class="ti ti-plus"></i>
+			<span v-if="full" :class="$style.text">{{ i18n.ts.followRequest }}</span><i class="ph-plus ph-bold ph-lg"></i>
 		</template>
 		<template v-else-if="!isFollowing && !user.isLocked">
-			<span v-if="full" :class="$style.text">{{ i18n.ts.follow }}</span><i class="ti ti-plus"></i>
+			<span v-if="full" :class="$style.text">{{ i18n.ts.follow }}</span><i class="ph-plus ph-bold ph-lg"></i>
 		</template>
 	</template>
 	<template v-else>
diff --git a/packages/frontend/src/components/MkGoogle.vue b/packages/frontend/src/components/MkGoogle.vue
index b899656e4f..be282bbfd6 100644
--- a/packages/frontend/src/components/MkGoogle.vue
+++ b/packages/frontend/src/components/MkGoogle.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div :class="$style.root">
 	<input v-model="query" :class="$style.input" type="search" :placeholder="q">
-	<button :class="$style.button" @click="search"><i class="ti ti-search"></i> {{ i18n.ts.searchByGoogle }}</button>
+	<button :class="$style.button" @click="search"><i class="ph-magnifying-glass ph-bold ph-lg"></i> {{ i18n.ts.searchByGoogle }}</button>
 </div>
 </template>
 
diff --git a/packages/frontend/src/components/MkInfo.vue b/packages/frontend/src/components/MkInfo.vue
index 37490887e1..ceb76d0d97 100644
--- a/packages/frontend/src/components/MkInfo.vue
+++ b/packages/frontend/src/components/MkInfo.vue
@@ -5,8 +5,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div :class="[$style.root, { [$style.warn]: warn }]">
-	<i v-if="warn" class="ti ti-alert-triangle" :class="$style.i"></i>
-	<i v-else class="ti ti-info-circle" :class="$style.i"></i>
+	<i v-if="warn" class="ph-warning ph-bold ph-lg" :class="$style.i"></i>
+	<i v-else class="ph-info ph-bold ph-lg" :class="$style.i"></i>
 	<slot></slot>
 </div>
 </template>
diff --git a/packages/frontend/src/components/MkInput.vue b/packages/frontend/src/components/MkInput.vue
index 315ce958c5..b203589af0 100644
--- a/packages/frontend/src/components/MkInput.vue
+++ b/packages/frontend/src/components/MkInput.vue
@@ -35,7 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="$style.caption"><slot name="caption"></slot></div>
 
-	<MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
@@ -221,7 +221,7 @@ defineExpose({
 	color: var(--fg);
 	background: var(--panel);
 	border: solid 1px var(--panel);
-	border-radius: 6px;
+	border-radius: 5px;
 	outline: none;
 	box-shadow: none;
 	box-sizing: border-box;
diff --git a/packages/frontend/src/components/MkInstanceCardMini.vue b/packages/frontend/src/components/MkInstanceCardMini.vue
index de726e3aa4..e514e2c6ab 100644
--- a/packages/frontend/src/components/MkInstanceCardMini.vue
+++ b/packages/frontend/src/components/MkInstanceCardMini.vue
@@ -46,7 +46,7 @@ function getInstanceIcon(instance): string {
 	align-items: center;
 	padding: 16px;
 	background: var(--panel);
-	border-radius: 8px;
+	border-radius: 5px;
 
 	> :global(.icon) {
 		display: block;
diff --git a/packages/frontend/src/components/MkInviteCode.vue b/packages/frontend/src/components/MkInviteCode.vue
index ff3794ad18..8e3561e2b8 100644
--- a/packages/frontend/src/components/MkInviteCode.vue
+++ b/packages/frontend/src/components/MkInviteCode.vue
@@ -50,8 +50,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 		</div>
 		<div :class="$style.buttons">
-			<MkButton v-if="!invite.used && !isExpired" primary rounded @click="copyInviteCode()"><i class="ti ti-copy"></i> {{ i18n.ts.copy }}</MkButton>
-			<MkButton v-if="!invite.used || moderator" danger rounded @click="deleteCode()"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+			<MkButton v-if="!invite.used && !isExpired" primary rounded @click="copyInviteCode()"><i class="ph-copy ph-bold ph-lg"></i> {{ i18n.ts.copy }}</MkButton>
+			<MkButton v-if="!invite.used || moderator" danger rounded @click="deleteCode()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 		</div>
 	</div>
 </MkFolder>
diff --git a/packages/frontend/src/components/MkKeyValue.vue b/packages/frontend/src/components/MkKeyValue.vue
index 4f1e4df040..7a1a5eb016 100644
--- a/packages/frontend/src/components/MkKeyValue.vue
+++ b/packages/frontend/src/components/MkKeyValue.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="$style.value">
 		<slot name="value"></slot>
-		<button v-if="copy" v-tooltip="i18n.ts.copy" class="_textButton" style="margin-left: 0.5em;" @click="copy_"><i class="ti ti-copy"></i></button>
+		<button v-if="copy" v-tooltip="i18n.ts.copy" class="_textButton" style="margin-left: 0.5em;" @click="copy_"><i class="ph-copy ph-bold ph-lg"></i></button>
 	</div>
 </div>
 </template>
diff --git a/packages/frontend/src/components/MkLaunchPad.vue b/packages/frontend/src/components/MkLaunchPad.vue
index 321acc0fbc..8425c258a8 100644
--- a/packages/frontend/src/components/MkLaunchPad.vue
+++ b/packages/frontend/src/components/MkLaunchPad.vue
@@ -74,7 +74,7 @@ function close() {
 	overflow: auto;
 	overscroll-behavior: contain;
 	text-align: left;
-	border-radius: 16px;
+	border-radius: 4px;
 
 	&.asDrawer {
 		width: 100%;
@@ -97,7 +97,7 @@ function close() {
 			justify-content: center;
 			vertical-align: bottom;
 			height: 100px;
-			border-radius: 10px;
+			border-radius: 5px;
 
 			&:hover {
 				color: var(--accent);
diff --git a/packages/frontend/src/components/MkLink.vue b/packages/frontend/src/components/MkLink.vue
index 0501d797f8..114b9b4faf 100644
--- a/packages/frontend/src/components/MkLink.vue
+++ b/packages/frontend/src/components/MkLink.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	:title="url"
 >
 	<slot></slot>
-	<i v-if="target === '_blank'" class="ti ti-external-link" :class="$style.icon"></i>
+	<i v-if="target === '_blank'" class="ph-arrow-square-out ph-bold ph-lg" :class="$style.icon"></i>
 </component>
 </template>
 
diff --git a/packages/frontend/src/components/MkMediaBanner.vue b/packages/frontend/src/components/MkMediaBanner.vue
index 10b2ac9ece..d04f0b453c 100644
--- a/packages/frontend/src/components/MkMediaBanner.vue
+++ b/packages/frontend/src/components/MkMediaBanner.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div :class="$style.root">
 	<div v-if="media.isSensitive && hide" :class="$style.sensitive" @click="hide = false">
-		<span style="font-size: 1.6em;"><i class="ti ti-alert-triangle"></i></span>
+		<span style="font-size: 1.6em;"><i class="ph-warning ph-bold ph-lg"></i></span>
 		<b>{{ i18n.ts.sensitive }}</b>
 		<span>{{ i18n.ts.clickToShow }}</span>
 	</div>
@@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		:title="media.name"
 		:download="media.name"
 	>
-		<span style="font-size: 1.6em;"><i class="ti ti-download"></i></span>
+		<span style="font-size: 1.6em;"><i class="ph-download ph-bold ph-lg"></i></span>
 		<b>{{ media.name }}</b>
 	</a>
 </div>
@@ -82,7 +82,7 @@ onMounted(() => {
 }
 
 .audio {
-	border-radius: 8px;
+	border-radius: 5px;
 	overflow: clip;
 }
 </style>
diff --git a/packages/frontend/src/components/MkMediaImage.vue b/packages/frontend/src/components/MkMediaImage.vue
index 5be7f30b58..016a4b020f 100644
--- a/packages/frontend/src/components/MkMediaImage.vue
+++ b/packages/frontend/src/components/MkMediaImage.vue
@@ -32,8 +32,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template v-if="hide">
 		<div :class="$style.hiddenText">
 			<div :class="$style.hiddenTextWrapper">
-				<b v-if="image.isSensitive" style="display: block;"><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.enableDataSaverMode ? ` (${i18n.ts.image}${image.size ? ' ' + bytes(image.size) : ''})` : '' }}</b>
-				<b v-else style="display: block;"><i class="ti ti-photo"></i> {{ defaultStore.state.enableDataSaverMode && image.size ? bytes(image.size) : i18n.ts.image }}</b>
+				<b v-if="image.isSensitive" style="display: block;"><i class="ph-eye-closed ph-bold ph-lg"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.enableDataSaverMode ? ` (${i18n.ts.image}${image.size ? ' ' + bytes(image.size) : ''})` : '' }}</b>
+				<b v-else style="display: block;"><i class="ph-image-square ph-bold ph-lg"></i> {{ defaultStore.state.enableDataSaverMode && image.size ? bytes(image.size) : i18n.ts.image }}</b>
 				<span v-if="controls" style="display: block;">{{ i18n.ts.clickToShow }}</span>
 			</div>
 		</div>
@@ -42,11 +42,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.indicators">
 			<div v-if="['image/gif', 'image/apng'].includes(image.type)" :class="$style.indicator">GIF</div>
 			<div v-if="image.comment" :class="$style.indicator">ALT</div>
-			<div v-if="image.isSensitive" :class="$style.indicator" style="color: var(--warn);" :title="i18n.ts.sensitive"><i class="ti ti-eye-exclamation"></i></div>
-			<div v-if="!image.comment" :class="$style.indicator" title="Image lacks descriptive text"><i class="ti ti-pencil-off"></i></div>
+			<div v-if="image.isSensitive" :class="$style.indicator" style="color: var(--warn);" :title="i18n.ts.sensitive"><i class="ph-eye-closed ph-bold ph-lg"></i></div>
+			<div v-if="!image.comment" :class="$style.indicator" title="Image lacks descriptive text"><i class="ph-pencil ph-bold ph-lg-off"></i></div>
 		</div>
-		<button :class="$style.menu" class="_button" @click.stop="showMenu"><i class="ti ti-dots" style="vertical-align: middle;"></i></button>
-		<i class="ti ti-eye-off" :class="$style.hide" @click.stop="hide = true"></i>
+		<button :class="$style.menu" class="_button" @click.stop="showMenu"><i class="ph-dots-three ph-bold ph-lg" style="vertical-align: middle;"></i></button>
+		<i class="ph-eye-slash ph-bold ph-lg" :class="$style.hide" @click.stop="hide = true"></i>
 	</template>
 </div>
 </template>
@@ -104,13 +104,13 @@ watch(() => props.image, () => {
 function showMenu(ev: MouseEvent) {
 	os.popupMenu([{
 		text: i18n.ts.hide,
-		icon: 'ti ti-eye-off',
+		icon: 'ph-eye-slash ph-bold ph-lg',
 		action: () => {
 			hide = true;
 		},
 	}, ...(iAmModerator ? [{
 		text: i18n.ts.markAsSensitive,
-		icon: 'ti ti-eye-exclamation',
+		icon: 'ph-eye-closed ph-bold ph-lg',
 		danger: true,
 		action: () => {
 			os.apiWithDialog('drive/files/update', { fileId: props.image.id, isSensitive: true });
@@ -157,7 +157,7 @@ function showMenu(ev: MouseEvent) {
 .hide {
 	display: block;
 	position: absolute;
-	border-radius: 6px;
+	border-radius: 5px;
 	background-color: black;
 	color: var(--accentLighten);
 	font-size: 12px;
@@ -187,7 +187,7 @@ function showMenu(ev: MouseEvent) {
 .menu {
 	display: block;
 	position: absolute;
-	border-radius: 999px;
+	border-radius: 4px;
 	background-color: rgba(0, 0, 0, 0.3);
 	-webkit-backdrop-filter: var(--blur, blur(15px));
 	backdrop-filter: var(--blur, blur(15px));
@@ -223,7 +223,7 @@ function showMenu(ev: MouseEvent) {
 .indicator {
 	/* Hardcode to black because either --bg or --fg makes it hard to read in dark/light mode */
 	background-color: black;
-	border-radius: 6px;
+	border-radius: 5px;
 	color: var(--accentLighten);
 	display: inline-block;
 	font-weight: bold;
diff --git a/packages/frontend/src/components/MkMediaList.vue b/packages/frontend/src/components/MkMediaList.vue
index f134f2021d..c9f02dd452 100644
--- a/packages/frontend/src/components/MkMediaList.vue
+++ b/packages/frontend/src/components/MkMediaList.vue
@@ -341,7 +341,7 @@ const previewable = (file: Misskey.entities.DriveFile): boolean => {
 
 .media {
 	overflow: hidden; // clipにするとバグる
-	border-radius: 8px;
+	border-radius: 5px;
 }
 
 :global(.pswp) {
diff --git a/packages/frontend/src/components/MkMediaVideo.vue b/packages/frontend/src/components/MkMediaVideo.vue
index 3ca5f62925..e4ddabaaf6 100644
--- a/packages/frontend/src/components/MkMediaVideo.vue
+++ b/packages/frontend/src/components/MkMediaVideo.vue
@@ -7,8 +7,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div v-if="hide" :class="[$style.hidden, (video.isSensitive && defaultStore.state.highlightSensitiveMedia) && $style.sensitiveContainer]" @click="hide = false">
 	<!-- 【注意】dataSaverMode が有効になっている際には、hide が false になるまでサムネイルや動画を読み込まないようにすること -->
 	<div :class="$style.sensitive">
-		<b v-if="video.isSensitive" style="display: block;"><i class="ti ti-alert-triangle"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.enableDataSaverMode ? ` (${i18n.ts.video}${video.size ? ' ' + bytes(video.size) : ''})` : '' }}</b>
-		<b v-else style="display: block;"><i class="ti ti-movie"></i> {{ defaultStore.state.enableDataSaverMode && video.size ? bytes(video.size) : i18n.ts.video }}</b>
+		<b v-if="video.isSensitive" style="display: block;"><i class="ph-warning ph-bold ph-lg"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.enableDataSaverMode ? ` (${i18n.ts.video}${video.size ? ' ' + bytes(video.size) : ''})` : '' }}</b>
+		<b v-else style="display: block;"><i class="ph-film-strip ph-bold ph-lg"></i> {{ defaultStore.state.enableDataSaverMode && video.size ? bytes(video.size) : i18n.ts.video }}</b>
 		<span>{{ i18n.ts.clickToShow }}</span>
 	</div>
 </div>
@@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			:src="video.url"
 		>
 	</video>
-	<i class="ti ti-eye-off" :class="$style.hide" @click="hide = true"></i>
+	<i class="ph-eye-slash ph-bold ph-lg" :class="$style.hide" @click="hide = true"></i>
 </div>
 </template>
 
@@ -68,7 +68,7 @@ const hide = ref((defaultStore.state.nsfw === 'force' || defaultStore.state.enab
 .hide {
 	display: block;
 	position: absolute;
-	border-radius: 6px;
+	border-radius: 5px;
 	background-color: black;
 	color: var(--accentLighten);
 	font-size: 14px;
@@ -118,7 +118,7 @@ const hide = ref((defaultStore.state.nsfw === 'force' || defaultStore.state.enab
 .indicator {
 	/* Hardcode to black because either --bg or --fg makes it hard to read in dark/light mode */
 	background-color: black;
-	border-radius: 6px;
+	border-radius: 5px;
 	color: var(--accentLighten);
 	display: inline-block;
 	font-weight: bold;
diff --git a/packages/frontend/src/components/MkMention.vue b/packages/frontend/src/components/MkMention.vue
index ffc9ca3f4d..e9cc9d5f4f 100644
--- a/packages/frontend/src/components/MkMention.vue
+++ b/packages/frontend/src/components/MkMention.vue
@@ -43,7 +43,7 @@ const bgCss = bg.toRgbString();
 .root {
 	display: inline-block;
 	padding: 4px 8px 4px 4px;
-	border-radius: 999px;
+	border-radius: 4px;
 	color: var(--mention);
 
 	&.isMe {
diff --git a/packages/frontend/src/components/MkMenu.vue b/packages/frontend/src/components/MkMenu.vue
index 079f07ee47..626698aa42 100644
--- a/packages/frontend/src/components/MkMenu.vue
+++ b/packages/frontend/src/components/MkMenu.vue
@@ -42,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<button v-else-if="item.type === 'parent'" class="_button" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter="preferClick ? null : showChildren(item, $event)" @click="!preferClick ? null : showChildren(item, $event)">
 				<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]" style="pointer-events: none;"></i>
 				<span style="pointer-events: none;">{{ item.text }}</span>
-				<span :class="$style.caret" style="pointer-events: none;"><i class="ti ti-chevron-right ti-fw"></i></span>
+				<span :class="$style.caret" style="pointer-events: none;"><i class="ph-caret-right ph-bold ph-lg ti-fw"></i></span>
 			</button>
 			<button v-else :tabindex="i" class="_button" role="menuitem" :class="[$style.item, { [$style.danger]: item.danger, [$style.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="ti-fw" :class="[$style.icon, item.icon]"></i>
@@ -288,7 +288,7 @@ onBeforeUnmount(() => {
 		margin: auto;
 		width: calc(100% - 16px);
 		height: 100%;
-		border-radius: 6px;
+		border-radius: 5px;
 	}
 
 	&:not(:disabled):hover {
diff --git a/packages/frontend/src/components/MkModalWindow.vue b/packages/frontend/src/components/MkModalWindow.vue
index 1fdf0beb26..800950ea82 100644
--- a/packages/frontend/src/components/MkModalWindow.vue
+++ b/packages/frontend/src/components/MkModalWindow.vue
@@ -7,12 +7,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 <MkModal ref="modal" :preferType="'dialog'" @click="onBgClick" @closed="$emit('closed')">
 	<div ref="rootEl" :class="$style.root" :style="{ width: `${width}px`, height: `min(${height}px, 100%)` }" @keydown="onKeydown">
 		<div ref="headerEl" :class="$style.header">
-			<button v-if="withOkButton" :class="$style.headerButton" class="_button" @click="$emit('close')"><i class="ti ti-x"></i></button>
+			<button v-if="withOkButton" :class="$style.headerButton" class="_button" @click="$emit('close')"><i class="ph-x ph-bold ph-lg"></i></button>
 			<span :class="$style.title">
 				<slot name="header"></slot>
 			</span>
-			<button v-if="!withOkButton" :class="$style.headerButton" class="_button" data-cy-modal-window-close @click="$emit('close')"><i class="ti ti-x"></i></button>
-			<button v-if="withOkButton" :class="$style.headerButton" class="_button" :disabled="okButtonDisabled" @click="$emit('ok')"><i class="ti ti-check"></i></button>
+			<button v-if="!withOkButton" :class="$style.headerButton" class="_button" data-cy-modal-window-close @click="$emit('close')"><i class="ph-x ph-bold ph-lg"></i></button>
+			<button v-if="withOkButton" :class="$style.headerButton" class="_button" :disabled="okButtonDisabled" @click="$emit('ok')"><i class="ph-check ph-bold ph-lg"></i></button>
 		</div>
 		<div :class="$style.body">
 			<slot :width="bodyWidth" :height="bodyHeight"></slot>
diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue
index 915a84b361..14dd7ad467 100644
--- a/packages/frontend/src/components/MkNote.vue
+++ b/packages/frontend/src/components/MkNote.vue
@@ -13,13 +13,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 	:tabindex="!isDeleted ? '-1' : undefined"
 >
 	<MkNoteSub v-if="appearNote.reply && !renoteCollapsed" :note="appearNote.reply" :class="$style.replyTo"/>
-	<div v-if="pinned" :class="$style.tip"><i class="ti ti-pin"></i> {{ i18n.ts.pinnedNote }}</div>
-	<!--<div v-if="appearNote._prId_" class="tip"><i class="ti ti-speakerphone"></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="tip"><i class="ti ti-bolt"></i> {{ i18n.ts.featured }}</div>-->
+	<div v-if="pinned" :class="$style.tip"><i class="ph-push-pin ph-bold ph-lg"></i> {{ i18n.ts.pinnedNote }}</div>
+	<!--<div v-if="appearNote._prId_" class="tip"><i class="ph-megaphone ph-bold ph-lg"></i> {{ i18n.ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ i18n.ts.hideThisNote }} <i class="ph-x ph-bold ph-lg"></i></button></div>-->
+	<!--<div v-if="appearNote._featuredId_" class="tip"><i class="ph-lightning ph-bold pg-lg"></i> {{ i18n.ts.featured }}</div>-->
 	<div v-if="isRenote" :class="$style.renote">
 		<div v-if="note.channel" :class="$style.colorBar" :style="{ background: note.channel.color }"></div>
 		<MkAvatar :class="$style.renoteAvatar" :user="note.user" link preview/>
-		<i class="ti ti-repeat" style="margin-right: 4px;"></i>
+		<i class="ph-repeat ph-bold ph-lg" style="margin-right: 4px;"></i>
 		<I18n :src="i18n.ts.renotedBy" tag="span" :class="$style.renoteText">
 			<template #user>
 				<MkA v-user-preview="note.userId" :class="$style.renoteUserName" :to="userPage(note.user)">
@@ -29,17 +29,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</I18n>
 		<div :class="$style.renoteInfo">
 			<button ref="renoteTime" :class="$style.renoteTime" class="_button" @click="showRenoteMenu()">
-				<i class="ti ti-dots" :class="$style.renoteMenu"></i>
+				<i class="ph-dots-three ph-bold ph-lg" :class="$style.renoteMenu"></i>
 				<MkTime :time="note.createdAt"/>
 			</button>
 			<span v-if="note.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[note.visibility]">
-				<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
-				<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
-				<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
+				<i v-if="note.visibility === 'home'" class="ph-house ph-bold ph-lg"></i>
+				<i v-else-if="note.visibility === 'followers'" class="ph-lock ph-bold ph-lg"></i>
+				<i v-else-if="note.visibility === 'specified'" ref="specified" class="ph-envelope ph-bold ph-lg"></i>
 			</span>
-			<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
-			<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
-			<span v-if="note.updatedAt" style="margin-left: 0.5em;" title="Edited"><i class="ti ti-pencil"></i></span>
+			<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ph-rocket ph-bold pg-lg"></i></span>
+			<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ph-television ph-bold ph-lg"></i></span>
+			<span v-if="note.updatedAt" style="margin-left: 0.5em;" title="Edited"><i class="ph-pencil ph-bold ph-lg"></i></span>
 		</div>
 	</div>
 	<div v-if="renoteCollapsed" :class="$style.collapsedRenoteTarget">
@@ -60,7 +60,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]" >
 					<div :class="$style.text">
 						<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
-						<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
+						<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ph-arrow-bend-left-up ph-bold pg-lg"></i></MkA>
 						<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
 						<div v-if="translating || translation" :class="$style.translation">
 							<MkLoading v-if="translating" mini/>
@@ -83,7 +83,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
 					</button>
 				</div>
-				<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
+				<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ph-television ph-bold ph-lg"></i> {{ appearNote.channel.name }}</MkA>
 			</div>
 			<MkReactionsViewer :note="appearNote" :maxNumber="16" v-on:click.stop>
 				<template #more>
@@ -92,7 +92,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkReactionsViewer>
 			<footer :class="$style.footer">
 				<button :class="$style.footerButton" class="_button" v-on:click.stop @click="reply()">
-					<i class="ti ti-arrow-back-up"></i>
+					<i class="ph-arrow-u-up-left ph-bold pg-lg"></i>
 					<p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ appearNote.repliesCount }}</p>
 				</button>
 				<button
@@ -102,24 +102,24 @@ SPDX-License-Identifier: AGPL-3.0-only
 					class="_button"
 					@mousedown="renote()"
 				>
-					<i class="ti ti-repeat"></i>
+					<i class="ph-repeat ph-bold ph-lg"></i>
 					<p v-if="appearNote.renoteCount > 0" :class="$style.footerButtonCount">{{ appearNote.renoteCount }}</p>
 				</button>
 				<button v-else :class="$style.footerButton" class="_button" disabled>
-					<i class="ti ti-ban"></i>
+					<i class="ph-prohibit ph-bold ph-lg"></i>
 				</button>
 				<button v-if="appearNote.myReaction == null" ref="reactButton" :class="$style.footerButton" class="_button" @mousedown="react()">
-					<i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
-					<i v-else class="ti ti-plus"></i>
+					<i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ph-heart ph-bold ph-lg"></i>
+					<i v-else class="ph-smiley ph-bold ph-lg"></i>
 				</button>
 				<button v-if="appearNote.myReaction != null" ref="reactButton" :class="$style.footerButton" class="_button" @click="undoReact(appearNote)">
-					<i class="ti ti-minus"></i>
+					<i class="ph-minus ph-bold ph-lg"></i>
 				</button>
 				<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @mousedown="clip()">
-					<i class="ti ti-paperclip"></i>
+					<i class="ph-paperclip ph-bold ph-lg"></i>
 				</button>
 				<button ref="menuButton" :class="$style.footerButton" class="_button" @mousedown="menu()">
-					<i class="ti ti-dots"></i>
+					<i class="ph-dots-three ph-bold ph-lg"></i>
 				</button>
 			</footer>
 		</div>
@@ -281,7 +281,7 @@ function renote(viaKeyboard = false) {
 	if (appearNote.channel) {
 		items = items.concat([{
 			text: i18n.ts.inChannelRenote,
-			icon: 'ti ti-repeat',
+			icon: 'ph-repeat ph-bold ph-lg',
 			action: () => {
 				const el = renoteButton.value as HTMLElement | null | undefined;
 				if (el) {
@@ -300,7 +300,7 @@ function renote(viaKeyboard = false) {
 			},
 		}, {
 			text: i18n.ts.inChannelQuote,
-			icon: 'ti ti-quote',
+			icon: 'ph-quotes ph-bold ph-lg',
 			action: () => {
 				os.post({
 					renote: appearNote,
@@ -312,7 +312,7 @@ function renote(viaKeyboard = false) {
 
 	items = items.concat([{
 		text: i18n.ts.renote,
-		icon: 'ti ti-repeat',
+		icon: 'ph-repeat ph-bold ph-lg',
 		action: () => {
 			const el = renoteButton.value as HTMLElement | null | undefined;
 			if (el) {
@@ -341,7 +341,7 @@ function renote(viaKeyboard = false) {
 		},
 	}, {
 		text: i18n.ts.quote,
-		icon: 'ti ti-quote',
+		icon: 'ph-quotes ph-bold ph-lg',
 		action: () => {
 			os.post({
 				renote: appearNote,
@@ -440,7 +440,7 @@ function showRenoteMenu(viaKeyboard = false): void {
 	function getUnrenote(): MenuItem {
 		return {
 			text: i18n.ts.unrenote,
-			icon: 'ti ti-trash',
+			icon: 'ph-trash ph-bold ph-lg',
 			danger: true,
 			action: () => {
 				os.api('notes/delete', {
@@ -552,7 +552,7 @@ function readPromo() {
 			padding: 0 4px;
 			margin-bottom: 0 !important;
 			background: var(--popup);
-			border-radius: 8px;
+			border-radius: 5px;
 			box-shadow: 0px 4px 32px var(--shadow);
 		}
 
@@ -684,7 +684,7 @@ function readPromo() {
 	left: 8px;
 	width: 5px;
 	height: calc(100% - 16px);
-	border-radius: 999px;
+	border-radius: 4px;
 	pointer-events: none;
 }
 
@@ -724,7 +724,7 @@ function readPromo() {
 	background: var(--popup);
 	padding: 6px 10px;
 	font-size: 0.8em;
-	border-radius: 999px;
+	border-radius: 4px;
 	box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
 }
 
@@ -754,7 +754,7 @@ function readPromo() {
 	background: var(--panel);
 	padding: 6px 10px;
 	font-size: 0.8em;
-	border-radius: 999px;
+	border-radius: 4px;
 	box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
 }
 
@@ -789,7 +789,7 @@ function readPromo() {
 .quoteNote {
 	padding: 16px;
 	border: dashed 1px var(--renote);
-	border-radius: 8px;
+	border-radius: 5px;
 	overflow: clip;
 }
 
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue
index 3956c9dc51..73769b6a6a 100644
--- a/packages/frontend/src/components/MkNoteDetailed.vue
+++ b/packages/frontend/src/components/MkNoteDetailed.vue
@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<MkNoteSub v-if="appearNote.reply" :note="appearNote.reply" :class="$style.replyTo"/>
 	<div v-if="isRenote" :class="$style.renote">
 		<MkAvatar :class="$style.renoteAvatar" :user="note.user" link preview/>
-		<i class="ti ti-repeat" style="margin-right: 4px;"></i>
+		<i class="ph-repeat ph-bold ph-lg" style="margin-right: 4px;"></i>
 		<span :class="$style.renoteText">
 			<I18n :src="i18n.ts.renotedBy" tag="span">
 				<template #user>
@@ -32,15 +32,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</span>
 		<div :class="$style.renoteInfo">
 			<button ref="renoteTime" class="_button" :class="$style.renoteTime" @click="showRenoteMenu()">
-				<i v-if="isMyRenote" class="ti ti-dots" style="margin-right: 4px;"></i>
+				<i v-if="isMyRenote" class="ph-dots-three ph-bold ph-lg" style="margin-right: 4px;"></i>
 				<MkTime :time="note.createdAt"/>
 			</button>
 			<span v-if="note.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[note.visibility]">
-				<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
-				<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
-				<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
+				<i v-if="note.visibility === 'home'" class="ph-house ph-bold ph-lg"></i>
+				<i v-else-if="note.visibility === 'followers'" class="ph-lock ph-bold ph-lg"></i>
+				<i v-else-if="note.visibility === 'specified'" ref="specified" class="ph-envelope ph-bold ph-lg"></i>
 			</span>
-			<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
+			<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ph-rocket ph-bold pg-lg"></i></span>
 		</div>
 	</div>
 	<article :class="$style.note" @contextmenu.stop="onContextmenu">
@@ -54,12 +54,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<span v-if="appearNote.user.isBot" :class="$style.isBot">bot</span>
 					<div :class="$style.noteHeaderInfo">
 						<span v-if="appearNote.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[appearNote.visibility]">
-							<i v-if="appearNote.visibility === 'home'" class="ti ti-home"></i>
-							<i v-else-if="appearNote.visibility === 'followers'" class="ti ti-lock"></i>
-							<i v-else-if="appearNote.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
+							<i v-if="appearNote.visibility === 'home'" class="ph-house ph-bold ph-lg"></i>
+							<i v-else-if="appearNote.visibility === 'followers'" class="ph-lock ph-bold ph-lg"></i>
+							<i v-else-if="appearNote.visibility === 'specified'" ref="specified" class="ph-envelope ph-bold ph-lg"></i>
 						</span>
-						<span v-if="appearNote.updatedAt" style="margin-left: 0.5em;" title="Edited"><i class="ti ti-pencil"></i></span>
-						<span v-if="appearNote.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
+						<span v-if="appearNote.updatedAt" style="margin-left: 0.5em;" title="Edited"><i class="ph-pencil ph-bold ph-lg"></i></span>
+						<span v-if="appearNote.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ph-rocket ph-bold pg-lg"></i></span>
 					</div>
 				</div>
 				<div :class="$style.noteHeaderUsername"><MkAcct :user="appearNote.user"/></div>
@@ -73,7 +73,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</p>
 			<div v-show="appearNote.cw == null || showContent">
 				<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
-				<MkA v-if="appearNote.replyId" :class="$style.noteReplyTarget" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
+				<MkA v-if="appearNote.replyId" :class="$style.noteReplyTarget" :to="`/notes/${appearNote.replyId}`"><i class="ph-arrow-bend-left-up ph-bold pg-lg"></i></MkA>
 				<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :emojiUrls="appearNote.emojis"/>
 				<a v-if="appearNote.renote != null" :class="$style.rn">RN:</a>
 				<div v-if="translating || translation" :class="$style.translation">
@@ -90,7 +90,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" style="margin-top: 6px;"/>
 				<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div>
 			</div>
-			<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA>
+			<MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ph-television ph-bold ph-lg"></i> {{ appearNote.channel.name }}</MkA>
 		</div>
 		<footer>
 			<div :class="$style.noteFooterInfo">
@@ -100,7 +100,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 			<MkReactionsViewer ref="reactionsViewer" :note="appearNote"/>
 			<button class="_button" :class="$style.noteFooterButton" @click="reply()">
-				<i class="ti ti-arrow-back-up"></i>
+				<i class="ph-arrow-u-up-left ph-bold pg-lg"></i>
 				<p v-if="appearNote.repliesCount > 0" :class="$style.noteFooterButtonCount">{{ appearNote.repliesCount }}</p>
 			</button>
 			<button
@@ -110,31 +110,31 @@ SPDX-License-Identifier: AGPL-3.0-only
 				:class="$style.noteFooterButton"
 				@mousedown="renote()"
 			>
-				<i class="ti ti-repeat"></i>
+				<i class="ph-repeat ph-bold ph-lg"></i>
 				<p v-if="appearNote.renoteCount > 0" :class="$style.noteFooterButtonCount">{{ appearNote.renoteCount }}</p>
 			</button>
 			<button v-else class="_button" :class="$style.noteFooterButton" disabled>
-				<i class="ti ti-ban"></i>
+				<i class="ph-prohibit ph-bold ph-lg"></i>
 			</button>
 			<button v-if="appearNote.myReaction == null" ref="reactButton" :class="$style.noteFooterButton" class="_button" @mousedown="react()">
-				<i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
-				<i v-else class="ti ti-plus"></i>
+				<i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ph-heart ph-bold ph-lg"></i>
+				<i v-else class="ph-smiley ph-bold ph-lg"></i>
 			</button>
 			<button v-if="appearNote.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(appearNote)">
-				<i class="ti ti-minus"></i>
+				<i class="ph-minus ph-bold ph-lg"></i>
 			</button>
 			<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
-				<i class="ti ti-paperclip"></i>
+				<i class="ph-paperclip ph-bold ph-lg"></i>
 			</button>
 			<button ref="menuButton" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
-				<i class="ti ti-dots"></i>
+				<i class="ph-dots-three ph-bold ph-lg"></i>
 			</button>
 		</footer>
 	</article>
 	<div :class="$style.tabs">
-		<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'replies' }]" @click="tab = 'replies'"><i class="ti ti-arrow-back-up"></i> {{ i18n.ts.replies }}</button>
-		<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'renotes' }]" @click="tab = 'renotes'"><i class="ti ti-repeat"></i> {{ i18n.ts.renotes }}</button>
-		<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'reactions' }]" @click="tab = 'reactions'"><i class="ti ti-icons"></i> {{ i18n.ts.reactions }}</button>
+		<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'replies' }]" @click="tab = 'replies'"><i class="ph-arrow-u-up-left ph-bold pg-lg"></i> {{ i18n.ts.replies }}</button>
+		<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'renotes' }]" @click="tab = 'renotes'"><i class="ph-repeat ph-bold ph-lg"></i> {{ i18n.ts.renotes }}</button>
+		<button class="_button" :class="[$style.tab, { [$style.tabActive]: tab === 'reactions' }]" @click="tab = 'reactions'"><i class="ph-smiley ph-bold pg-lg"></i> {{ i18n.ts.reactions }}</button>
 	</div>
 	<div>
 		<div v-if="tab === 'replies'" :class="$style.tab_replies">
@@ -327,7 +327,7 @@ function renote(viaKeyboard = false) {
 	if (appearNote.channel) {
 		items = items.concat([{
 			text: i18n.ts.inChannelRenote,
-			icon: 'ti ti-repeat',
+			icon: 'ph-repeat ph-bold ph-lg',
 			action: () => {
 				const el = renoteButton.value as HTMLElement | null | undefined;
 				if (el) {
@@ -346,7 +346,7 @@ function renote(viaKeyboard = false) {
 			},
 		}, {
 			text: i18n.ts.inChannelQuote,
-			icon: 'ti ti-quote',
+			icon: 'ph-quotes ph-bold ph-lg',
 			action: () => {
 				os.post({
 					renote: appearNote,
@@ -358,7 +358,7 @@ function renote(viaKeyboard = false) {
 
 	items = items.concat([{
 		text: i18n.ts.renote,
-		icon: 'ti ti-repeat',
+		icon: 'ph-repeat ph-bold ph-lg',
 		action: () => {
 			const el = renoteButton.value as HTMLElement | null | undefined;
 			if (el) {
@@ -376,7 +376,7 @@ function renote(viaKeyboard = false) {
 		},
 	}, {
 		text: i18n.ts.quote,
-		icon: 'ti ti-quote',
+		icon: 'ph-quotes ph-bold ph-lg',
 		action: () => {
 			os.post({
 				renote: appearNote,
@@ -475,7 +475,7 @@ function showRenoteMenu(viaKeyboard = false): void {
 	pleaseLogin();
 	os.popupMenu([{
 		text: i18n.ts.unrenote,
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		danger: true,
 		action: () => {
 			os.api('notes/delete', {
@@ -552,7 +552,7 @@ if (appearNote.reply && appearNote.reply.replyId && defaultStore.state.autoloadC
 	width: 28px;
 	height: 28px;
 	margin: 0 8px 0 0;
-	border-radius: 6px;
+	border-radius: 5px;
 }
 
 .renoteText {
@@ -679,7 +679,7 @@ if (appearNote.reply && appearNote.reply.replyId && defaultStore.state.autoloadC
 .quoteNote {
 	padding: 16px;
 	border: dashed 1px var(--renote);
-	border-radius: 8px;
+	border-radius: 5px;
 	overflow: clip;
 }
 
@@ -757,7 +757,7 @@ if (appearNote.reply && appearNote.reply.replyId && defaultStore.state.autoloadC
 .reactionTab {
 	padding: 4px 6px;
 	border: solid 1px var(--divider);
-	border-radius: 6px;
+	border-radius: 5px;
 }
 
 .reactionTabActive {
diff --git a/packages/frontend/src/components/MkNoteHeader.vue b/packages/frontend/src/components/MkNoteHeader.vue
index 63392fef71..1247c0fb6e 100644
--- a/packages/frontend/src/components/MkNoteHeader.vue
+++ b/packages/frontend/src/components/MkNoteHeader.vue
@@ -18,13 +18,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkTime :time="note.createdAt"/>
 		</MkA>
 		<span v-if="note.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[note.visibility]">
-			<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
-			<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
-			<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
+			<i v-if="note.visibility === 'home'" class="ph-house ph-bold ph-lg"></i>
+			<i v-else-if="note.visibility === 'followers'" class="ph-lock ph-bold ph-lg"></i>
+			<i v-else-if="note.visibility === 'specified'" ref="specified" class="ph-envelope ph-bold ph-lg"></i>
 		</span>
-		<span v-if="note.updatedAt" style="margin-left: 0.5em;" title="Edited"><i class="ti ti-pencil"></i></span>
-		<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
-		<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
+		<span v-if="note.updatedAt" style="margin-left: 0.5em;" title="Edited"><i class="ph-pencil ph-bold ph-lg"></i></span>
+		<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ph-rocket ph-bold pg-lg"></i></span>
+		<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ph-television ph-bold ph-lg"></i></span>
 	</div>
 </header>
 </template>
diff --git a/packages/frontend/src/components/MkNoteSimple.vue b/packages/frontend/src/components/MkNoteSimple.vue
index f8ef3f3fa6..b7da548e9d 100644
--- a/packages/frontend/src/components/MkNoteSimple.vue
+++ b/packages/frontend/src/components/MkNoteSimple.vue
@@ -50,7 +50,7 @@ const showContent = $ref(false);
 	margin: 0 10px 0 0;
 	width: 34px;
 	height: 34px;
-	border-radius: 8px;
+	border-radius: 5px;
 	position: sticky !important;
 	top: calc(16px + var(--stickyTop, 0px));
 	left: 0;
diff --git a/packages/frontend/src/components/MkNoteSub.vue b/packages/frontend/src/components/MkNoteSub.vue
index 2a3cd9bf02..6e30ac484f 100644
--- a/packages/frontend/src/components/MkNoteSub.vue
+++ b/packages/frontend/src/components/MkNoteSub.vue
@@ -19,13 +19,43 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkSubNoteContent :class="$style.text" :note="note"/>
 				</div>
 			</div>
+			<footer>
+				<MkReactionsViewer ref="reactionsViewer" :note="note"/>
+				<button class="_button" :class="$style.noteFooterButton" @click="reply()">
+					<i class="ph-arrow-u-up-left ph-bold pg-lg"></i>
+					<p v-if="note.repliesCount > 0" :class="$style.noteFooterButtonCount">{{ note.repliesCount }}</p>
+				</button>
+				<button
+				v-if="canRenote"
+				ref="renoteButton"
+				class="_button"
+				:class="$style.noteFooterButton"
+				@mousedown="renote()"
+				>
+					<i class="ph-repeat ph-bold ph-lg"></i>
+					<p v-if="note.renoteCount > 0" :class="$style.noteFooterButtonCount">{{ note.renoteCount }}</p>
+				</button>
+				<button v-else class="_button" :class="$style.noteFooterButton" disabled>
+					<i class="ph-prohibit ph-bold ph-lg"></i>
+				</button>
+				<button v-if="note.myReaction == null" ref="reactButton" :class="$style.noteFooterButton" class="_button" @mousedown="react()">
+					<i v-if="note.reactionAcceptance === 'likeOnly'" class="ph-heart ph-bold ph-lg"></i>
+					<i v-else class="ph-smiley ph-bold ph-lg"></i>
+				</button>
+				<button v-if="note.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(note)">
+					<i class="ph-minus ph-bold ph-lg"></i>
+				</button>
+				<button ref="menuButton" class="_button" :class="$style.noteFooterButton" @mousedown="menu()">
+					<i class="ph-dots-three ph-bold ph-lg"></i>
+				</button>
+			</footer>
 		</div>
 	</div>
 	<template v-if="depth < 5">
 		<MkNoteSub v-for="reply in replies" :key="reply.id" :note="reply" :class="$style.reply" :detail="true" :depth="depth + 1"/>
 	</template>
 	<div v-else :class="$style.more">
-		<MkA class="_link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="ti ti-chevron-double-right"></i></MkA>
+		<MkA class="_link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="ph-caret-double-right ph-bold ph-lg"></i></MkA>
 	</div>
 </div>
 <div v-else :class="$style.muted" @click="muted = false">
@@ -40,9 +70,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 </template>
 
 <script lang="ts" setup>
-import { ref } from 'vue';
+import { computed, ref, shallowRef } from 'vue';
 import * as Misskey from 'misskey-js';
 import MkNoteHeader from '@/components/MkNoteHeader.vue';
+import MkReactionsViewer from '@/components/MkReactionsViewer.vue';
 import MkSubNoteContent from '@/components/MkSubNoteContent.vue';
 import MkCwButton from '@/components/MkCwButton.vue';
 import { notePage } from '@/filters/note.js';
@@ -52,6 +83,14 @@ import { $i } from '@/account.js';
 import { userPage } from "@/filters/user";
 import { checkWordMute } from "@/scripts/check-word-mute";
 import { defaultStore } from "@/store";
+import { pleaseLogin } from '@/scripts/please-login.js';
+import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
+import MkRippleEffect from '@/components/MkRippleEffect.vue';
+import { reactionPicker } from '@/scripts/reaction-picker.js';
+import { claimAchievement } from '@/scripts/achievements.js';
+import type { MenuItem } from '@/types/menu.js';
+import { getNoteMenu } from '@/scripts/get-note-menu.js';
+const canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i.id);
 
 const props = withDefaults(defineProps<{
 	note: Misskey.entities.Note;
@@ -63,11 +102,150 @@ const props = withDefaults(defineProps<{
 	depth: 1,
 });
 
+function focus() {
+	el.value.focus();
+}
+
 const muted = ref(checkWordMute(props.note, $i, defaultStore.state.mutedWords));
+const translation = ref(null);
+const translating = ref(false);
+const isDeleted = ref(false);
+const reactButton = shallowRef<HTMLElement>();
+const renoteButton = shallowRef<HTMLElement>();
+const menuButton = shallowRef<HTMLElement>();
+
+function reply(viaKeyboard = false): void {
+	pleaseLogin();
+	showMovedDialog();
+	os.post({
+		reply: props.note,
+		channel: props.note.channel,
+		animation: !viaKeyboard,
+	}, () => {
+		focus();
+	});
+}
+
+function react(viaKeyboard = false): void {
+	pleaseLogin();
+	showMovedDialog();
+	if (props.note.reactionAcceptance === 'likeOnly') {
+		os.api('notes/reactions/create', {
+			noteId: props.note.id,
+			reaction: '❤️',
+		});
+		const el = reactButton.value as HTMLElement | null | undefined;
+		if (el) {
+			const rect = el.getBoundingClientRect();
+			const x = rect.left + (el.offsetWidth / 2);
+			const y = rect.top + (el.offsetHeight / 2);
+			os.popup(MkRippleEffect, { x, y }, {}, 'end');
+		}
+	} else {
+		blur();
+		reactionPicker.show(reactButton.value, reaction => {
+			os.api('notes/reactions/create', {
+				noteId: props.note.id,
+				reaction: reaction,
+			});
+			if (props.note.text && props.note.text.length > 100 && (Date.now() - new Date(props.note.createdAt).getTime() < 1000 * 3)) {
+				claimAchievement('reactWithoutRead');
+			}
+		}, () => {
+			focus();
+		});
+	}
+}
+
+function undoReact(note): void {
+	const oldReaction = note.myReaction;
+	if (!oldReaction) return;
+	os.api('notes/reactions/delete', {
+		noteId: note.id,
+	});
+}
 
 let showContent = $ref(false);
 let replies: Misskey.entities.Note[] = $ref([]);
 
+function renote(viaKeyboard = false) {
+	pleaseLogin();
+	showMovedDialog();
+
+	let items = [] as MenuItem[];
+
+	if (props.note.channel) {
+		items = items.concat([{
+			text: i18n.ts.inChannelRenote,
+			icon: 'ph-repeat ph-bold ph-lg',
+			action: () => {
+				const el = renoteButton.value as HTMLElement | null | undefined;
+				if (el) {
+					const rect = el.getBoundingClientRect();
+					const x = rect.left + (el.offsetWidth / 2);
+					const y = rect.top + (el.offsetHeight / 2);
+					os.popup(MkRippleEffect, { x, y }, {}, 'end');
+				}
+
+				os.api('notes/create', {
+					renoteId: props.note.id,
+					channelId: props.note.channelId,
+				}).then(() => {
+					os.toast(i18n.ts.renoted);
+				});
+			},
+		}, {
+			text: i18n.ts.inChannelQuote,
+			icon: 'ph-quotes ph-bold ph-lg',
+			action: () => {
+				os.post({
+					renote: props.note,
+					channel: props.note.channel,
+				});
+			},
+		}, null]);
+	}
+
+	items = items.concat([{
+		text: i18n.ts.renote,
+		icon: 'ph-repeat ph-bold ph-lg',
+		action: () => {
+			const el = renoteButton.value as HTMLElement | null | undefined;
+			if (el) {
+				const rect = el.getBoundingClientRect();
+				const x = rect.left + (el.offsetWidth / 2);
+				const y = rect.top + (el.offsetHeight / 2);
+				os.popup(MkRippleEffect, { x, y }, {}, 'end');
+			}
+
+			os.api('notes/create', {
+				renoteId: props.note.id,
+			}).then(() => {
+				os.toast(i18n.ts.renoted);
+			});
+		},
+	}, {
+		text: i18n.ts.quote,
+		icon: 'ph-quotes ph-bold ph-lg',
+		action: () => {
+			os.post({
+				renote: props.note,
+			});
+		},
+	}]);
+
+	os.popupMenu(items, renoteButton.value, {
+		viaKeyboard,
+	});
+}
+
+function menu(viaKeyboard = false): void {
+	const { menu, cleanup } = getNoteMenu({ note: props.note, translating, translation, menuButton, isDeleted });
+	os.popupMenu(menu, menuButton.value, {
+		viaKeyboard,
+	}).then(focus).finally(cleanup);
+}
+
 if (props.detail) {
 	os.api('notes/children', {
 		noteId: props.note.id,
@@ -100,7 +278,7 @@ if (props.detail) {
 	left: 8px;
 	width: 5px;
 	height: calc(100% - 8px);
-	border-radius: 999px;
+	border-radius: 4px;
 	pointer-events: none;
 }
 
@@ -110,7 +288,7 @@ if (props.detail) {
 	margin: 0 8px 0 0;
 	width: 38px;
 	height: 38px;
-	border-radius: 8px;
+	border-radius: 5px;
 }
 
 .body {
@@ -122,6 +300,31 @@ if (props.detail) {
 	margin-bottom: 2px;
 }
 
+.noteFooterButton {
+	margin: 0;
+	padding: 8px;
+	padding-top: 10px;
+	opacity: 0.7;
+
+	&:not(:last-child) {
+		margin-right: 14px;
+	}
+
+	&:hover {
+		color: var(--fgHighlighted);
+	}
+}
+
+.noteFooterButtonCount {
+	display: inline;
+	margin: 0 0 0 8px;
+	opacity: 0.7;
+
+	&.reacted {
+		color: var(--accent);
+	}
+}
+
 .cw {
 	cursor: default;
 	display: block;
@@ -159,6 +362,6 @@ if (props.detail) {
 	padding: 8px !important;
 	border: 1px solid var(--divider);
 	margin: 8px 8px 0 8px;
-	border-radius: 8px;
+	border-radius: 5px;
 }
 </style>
diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue
index 7ba102fd97..7e7694bf4b 100644
--- a/packages/frontend/src/components/MkNotification.vue
+++ b/packages/frontend/src/components/MkNotification.vue
@@ -25,15 +25,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 				[$style.t_achievementEarned]: notification.type === 'achievementEarned',
 			}]"
 		>
-			<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 === '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 === 'pollEnded'" class="ti ti-chart-arrows"></i>
-			<i v-else-if="notification.type === 'achievementEarned'" class="ti ti-medal"></i>
+			<i v-if="notification.type === 'follow'" class="ph-plus ph-bold ph-lg"></i>
+			<i v-else-if="notification.type === 'receiveFollowRequest'" class="ph-clock ph-bold ph-lg"></i>
+			<i v-else-if="notification.type === 'followRequestAccepted'" class="ph-check ph-bold ph-lg"></i>
+			<i v-else-if="notification.type === 'renote'" class="ph-repeat ph-bold ph-lg"></i>
+			<i v-else-if="notification.type === 'reply'" class="ph-arrow-u-up-left ph-bold pg-lg"></i>
+			<i v-else-if="notification.type === 'mention'" class="ph-at ph-bold ph-lg"></i>
+			<i v-else-if="notification.type === 'quote'" class="ph-quotes ph-bold ph-lg"></i>
+			<i v-else-if="notification.type === 'pollEnded'" class="ph-chart-bar-horizontal ph-bold pg-lg"></i>
+			<i v-else-if="notification.type === 'achievementEarned'" class="ph-trophy ph-bold ph-lg"></i>
 			<!-- notification.reaction が null になることはまずないが、ここでoptional chaining使うと一部ブラウザで刺さるので念の為 -->
 			<MkReactionIcon
 				v-else-if="notification.type === 'reaction'"
@@ -57,14 +57,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</header>
 		<div>
 			<MkA v-if="notification.type === 'reaction'" :class="$style.text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
-				<i class="ti ti-quote" :class="$style.quote"></i>
+				<i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
 				<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :author="notification.note.user"/>
-				<i class="ti ti-quote" :class="$style.quote"></i>
+				<i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
 			</MkA>
 			<MkA v-else-if="notification.type === 'renote'" :class="$style.text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note.renote)">
-				<i class="ti ti-quote" :class="$style.quote"></i>
+				<i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
 				<Mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :nowrap="true" :author="notification.note.renote.user"/>
-				<i class="ti ti-quote" :class="$style.quote"></i>
+				<i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
 			</MkA>
 			<MkA v-else-if="notification.type === 'reply'" :class="$style.text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
 				<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :author="notification.note.user"/>
@@ -79,9 +79,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :author="notification.note.user"/>
 			</MkA>
 			<MkA v-else-if="notification.type === 'pollEnded'" :class="$style.text" :to="notePage(notification.note)" :title="getNoteSummary(notification.note)">
-				<i class="ti ti-quote" :class="$style.quote"></i>
+				<i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
 				<Mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :author="notification.note.user"/>
-				<i class="ti ti-quote" :class="$style.quote"></i>
+				<i class="ph-quotes ph-bold ph-lg" :class="$style.quote"></i>
 			</MkA>
 			<MkA v-else-if="notification.type === 'achievementEarned'" :class="$style.text" to="/my/achievements">
 				{{ i18n.ts._achievements._types['_' + notification.achievement].title }}
@@ -94,8 +94,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<template v-else-if="notification.type === 'receiveFollowRequest'">
 				<span :class="$style.text" style="opacity: 0.6;">{{ i18n.ts.receiveFollowRequest }}</span>
 				<div v-if="full && !followRequestDone" :class="$style.followRequestCommands">
-					<MkButton :class="$style.followRequestCommandButton" rounded primary @click="acceptFollowRequest()"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
-					<MkButton :class="$style.followRequestCommandButton" rounded danger @click="rejectFollowRequest()"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
+					<MkButton :class="$style.followRequestCommandButton" rounded primary @click="acceptFollowRequest()"><i class="ph-check ph-bold ph-lg"/> {{ i18n.ts.accept }}</MkButton>
+					<MkButton :class="$style.followRequestCommandButton" rounded danger @click="rejectFollowRequest()"><i class="ph-x ph-bold ph-lg"/> {{ i18n.ts.reject }}</MkButton>
 				</div>
 			</template>
 			<span v-else-if="notification.type === 'test'" :class="$style.text">{{ i18n.ts._notification.notificationWillBeDisplayedLikeThis }}</span>
@@ -181,7 +181,7 @@ useTooltip(reactionRef, (showing) => {
 	display: block;
 	width: 100%;
 	height: 100%;
-	border-radius: 6px;
+	border-radius: 5px;
 }
 
 .subIcon {
diff --git a/packages/frontend/src/components/MkOmit.vue b/packages/frontend/src/components/MkOmit.vue
index 8c113bd777..85202ff3c0 100644
--- a/packages/frontend/src/components/MkOmit.vue
+++ b/packages/frontend/src/components/MkOmit.vue
@@ -69,7 +69,7 @@ onUnmounted(() => {
 				background: var(--panel);
 				padding: 6px 10px;
 				font-size: 0.8em;
-				border-radius: 999px;
+				border-radius: 4px;
 				box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
 			}
 
diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue
index 3b273ac545..70fae436f4 100644
--- a/packages/frontend/src/components/MkPageWindow.vue
+++ b/packages/frontend/src/components/MkPageWindow.vue
@@ -66,7 +66,7 @@ const buttonsLeft = $computed(() => {
 
 	if (history.length > 1) {
 		buttons.push({
-			icon: 'ti ti-arrow-left',
+			icon: 'ph-arrow-left ph-bold pg-lg',
 			onClick: back,
 		});
 	}
@@ -75,11 +75,11 @@ const buttonsLeft = $computed(() => {
 });
 const buttonsRight = $computed(() => {
 	const buttons = [{
-		icon: 'ti ti-reload',
+		icon: 'ph-arrow-clockwise ph-bold ph-lg',
 		title: i18n.ts.reload,
 		onClick: reload,
 	}, {
-		icon: 'ti ti-player-eject',
+		icon: 'ph-eject ph-bold pg-lg',
 		title: i18n.ts.showInPage,
 		onClick: expand,
 	}];
@@ -101,22 +101,22 @@ provide('shouldHeaderThin', true);
 provide('forceSpacerMin', true);
 
 const contextmenu = $computed(() => ([{
-	icon: 'ti ti-player-eject',
+	icon: 'ph-eject ph-bold pg-lg',
 	text: i18n.ts.showInPage,
 	action: expand,
 }, {
-	icon: 'ti ti-window-maximize',
+	icon: 'ph-frame-corners ph-bold ph-lg',
 	text: i18n.ts.popout,
 	action: popout,
 }, {
-	icon: 'ti ti-external-link',
+	icon: 'ph-arrow-square-out ph-bold ph-lg',
 	text: i18n.ts.openInNewTab,
 	action: () => {
 		window.open(url + router.getCurrentPath(), '_blank');
 		windowEl.close();
 	},
 }, {
-	icon: 'ti ti-link',
+	icon: 'ph-link ph-bold ph-lg',
 	text: i18n.ts.copyLink,
 	action: () => {
 		copyToClipboard(url + router.getCurrentPath());
diff --git a/packages/frontend/src/components/MkPasswordDialog.vue b/packages/frontend/src/components/MkPasswordDialog.vue
index 3abca7826f..28bcd56762 100644
--- a/packages/frontend/src/components/MkPasswordDialog.vue
+++ b/packages/frontend/src/components/MkPasswordDialog.vue
@@ -21,15 +21,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 		<div class="_gaps">
 			<MkInput ref="passwordInput" v-model="password" :placeholder="i18n.ts.password" type="password" autocomplete="current-password webauthn" :withPasswordToggle="true">
-				<template #prefix><i class="ti ti-password"></i></template>
+				<template #prefix><i class="ph-password ph-bold ph-lg"></i></template>
 			</MkInput>
 
 			<MkInput v-if="$i.twoFactorEnabled" v-model="token" type="text" pattern="^([0-9]{6}|[A-Z0-9]{32})$" autocomplete="one-time-code" :spellcheck="false">
 				<template #label>{{ i18n.ts.token }} ({{ i18n.ts['2fa'] }})</template>
-				<template #prefix><i class="ti ti-123"></i></template>
+				<template #prefix><i class="ph-keyhole ph-bold pg-lg"></i></template>
 			</MkInput>
 
-			<MkButton :disabled="(password ?? '') == '' || ($i.twoFactorEnabled && (token ?? '') == '')" primary rounded style="margin: 0 auto;" @click="done"><i class="ti ti-lock-open"></i> {{ i18n.ts.continue }}</MkButton>
+			<MkButton :disabled="(password ?? '') == '' || ($i.twoFactorEnabled && (token ?? '') == '')" primary rounded style="margin: 0 auto;" @click="done"><i class="ph-lock ph-bold ph-lg-open"></i> {{ i18n.ts.continue }}</MkButton>
 		</div>
 	</MkSpacer>
 </MkModalWindow>
diff --git a/packages/frontend/src/components/MkPoll.vue b/packages/frontend/src/components/MkPoll.vue
index 682f8e3060..9230104a3a 100644
--- a/packages/frontend/src/components/MkPoll.vue
+++ b/packages/frontend/src/components/MkPoll.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<li v-for="(choice, i) in note.poll.choices" :key="i" :class="$style.choice" @click="vote(i)">
 			<div :class="$style.bg" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div>
 			<span :class="$style.fg">
-				<template v-if="choice.isVoted"><i class="ti ti-check" style="margin-right: 4px; color: var(--accent);"></i></template>
+				<template v-if="choice.isVoted"><i class="ph-check ph-bold ph-lg" style="margin-right: 4px; color: var(--accent);"></i></template>
 				<Mfm :text="choice.text" :plain="true"/>
 				<span v-if="showResult" style="margin-left: 4px; opacity: 0.7;">({{ i18n.t('_poll.votesCount', { n: choice.votes }) }})</span>
 			</span>
diff --git a/packages/frontend/src/components/MkPollEditor.vue b/packages/frontend/src/components/MkPollEditor.vue
index 43e576d1ab..f46779a632 100644
--- a/packages/frontend/src/components/MkPollEditor.vue
+++ b/packages/frontend/src/components/MkPollEditor.vue
@@ -6,14 +6,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div class="zmdxowus">
 	<p v-if="choices.length < 2" class="caution">
-		<i class="ti ti-alert-triangle"></i>{{ i18n.ts._poll.noOnlyOneChoice }}
+		<i class="ph-warning ph-bold ph-lg"></i>{{ i18n.ts._poll.noOnlyOneChoice }}
 	</p>
 	<ul>
 		<li v-for="(choice, i) in choices" :key="i">
 			<MkInput class="input" small :modelValue="choice" :placeholder="i18n.t('_poll.choiceN', { n: i + 1 })" @update:modelValue="onInput(i, $event)">
 			</MkInput>
 			<button class="_button" @click="remove(i)">
-				<i class="ti ti-x"></i>
+				<i class="ph-x ph-bold ph-lg"></i>
 			</button>
 		</li>
 	</ul>
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index 71df95c745..1ec5b0d61e 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 >
 	<header :class="$style.header">
 		<div :class="$style.headerLeft">
-			<button v-if="!fixed" :class="$style.cancel" class="_button" @click="cancel"><i class="ti ti-x"></i></button>
+			<button v-if="!fixed" :class="$style.cancel" class="_button" @click="cancel"><i class="ph-x ph-bold ph-lg"></i></button>
 			<button v-click-anime v-tooltip="i18n.ts.switchAccount" :class="$style.account" class="_button" @click="openAccountMenu">
 				<MkAvatar :user="postAccount ?? $i" :class="$style.avatar"/>
 			</button>
@@ -21,47 +21,47 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.headerRight">
 			<template v-if="!(channel != null && fixed)">
 				<button v-if="channel == null" ref="visibilityButton" v-click-anime v-tooltip="i18n.ts.visibility" :class="['_button', $style.headerRightItem, $style.visibility]" @click="setVisibility">
-					<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"></i></span>
-					<span v-if="visibility === 'specified'"><i class="ti ti-mail"></i></span>
+					<span v-if="visibility === 'public'"><i class="ph-globe-hemisphere-west ph-bold ph-lg"></i></span>
+					<span v-if="visibility === 'home'"><i class="ph-house ph-bold ph-lg"></i></span>
+					<span v-if="visibility === 'followers'"><i class="ph-lock ph-bold ph-lg"></i></span>
+					<span v-if="visibility === 'specified'"><i class="ph-envelope ph-bold ph-lg"></i></span>
 					<span :class="$style.headerRightButtonText">{{ i18n.ts._visibility[visibility] }}</span>
 				</button>
 				<button v-else class="_button" :class="[$style.headerRightItem, $style.visibility]" disabled>
-					<span><i class="ti ti-device-tv"></i></span>
+					<span><i class="ph-television ph-bold ph-lg"></i></span>
 					<span :class="$style.headerRightButtonText">{{ channel.name }}</span>
 				</button>
 			</template>
 			<button v-click-anime v-tooltip="i18n.ts._visibility.disableFederation" class="_button" :class="[$style.headerRightItem, { [$style.danger]: localOnly }]" :disabled="channel != null || visibility === 'specified'" @click="toggleLocalOnly">
-				<span v-if="!localOnly"><i class="ti ti-rocket"></i></span>
-				<span v-else><i class="ti ti-rocket-off"></i></span>
+				<span v-if="!localOnly"><i class="ph-rocket-launch ph-bold pg-lg"></i></span>
+				<span v-else><i class="ph-rocket ph-bold pg-lg"></i></span>
 			</button>
 			<button v-click-anime v-tooltip="i18n.ts.reactionAcceptance" class="_button" :class="[$style.headerRightItem, { [$style.danger]: reactionAcceptance === 'likeOnly' }]" @click="toggleReactionAcceptance">
-				<span v-if="reactionAcceptance === 'likeOnly'"><i class="ti ti-heart"></i></span>
-				<span v-else-if="reactionAcceptance === 'likeOnlyForRemote'"><i class="ti ti-heart-plus"></i></span>
-				<span v-else><i class="ti ti-icons"></i></span>
+				<span v-if="reactionAcceptance === 'likeOnly'"><i class="ph-heart ph-bold ph-lg"></i></span>
+				<span v-else-if="reactionAcceptance === 'likeOnlyForRemote'"><i class="ph-heart ph-bold ph-lg"></i></span>
+				<span v-else><i class="ph-smiley ph-bold pg-lg"></i></span>
 			</button>
 			<button v-click-anime class="_button" :class="$style.submit" :disabled="!canPost" data-cy-open-post-form-submit @click="post">
 				<div :class="$style.submitInner">
 					<template v-if="posted"></template>
 					<template v-else-if="posting"><MkEllipsis/></template>
 					<template v-else>{{ submitText }}</template>
-					<i style="margin-left: 6px;" :class="posted ? 'ti ti-check' : reply ? 'ti ti-arrow-back-up' : renote ? 'ti ti-quote' : 'ti ti-send'"></i>
+					<i style="margin-left: 6px;" :class="posted ? 'ph-check ph-bold ph-lg' : reply ? 'ph-arrow-u-up-left ph-bold pg-lg' : renote ? 'ph-quotes ph-bold ph-lg' : 'ph-paper-plane-tilt ph-bold ph-lg'"></i>
 				</div>
 			</button>
 		</div>
 	</header>
 	<MkNoteSimple v-if="reply" :class="$style.targetNote" :note="reply"/>
 	<MkNoteSimple v-if="renote" :class="$style.targetNote" :note="renote"/>
-	<div v-if="quoteId" :class="$style.withQuote"><i class="ti ti-quote"></i> {{ i18n.ts.quoteAttached }}<button @click="quoteId = null"><i class="ti ti-x"></i></button></div>
+	<div v-if="quoteId" :class="$style.withQuote"><i class="ph-quotes ph-bold ph-lg"></i> {{ i18n.ts.quoteAttached }}<button @click="quoteId = null"><i class="ph-x ph-bold ph-lg"></i></button></div>
 	<div v-if="visibility === 'specified'" :class="$style.toSpecified">
 		<span style="margin-right: 8px;">{{ i18n.ts.recipient }}</span>
 		<div :class="$style.visibleUsers">
 			<span v-for="u in visibleUsers" :key="u.id" :class="$style.visibleUser">
 				<MkAcct :user="u"/>
-				<button class="_button" style="padding: 4px 8px;" @click="removeVisibleUser(u)"><i class="ti ti-x"></i></button>
+				<button class="_button" style="padding: 4px 8px;" @click="removeVisibleUser(u)"><i class="ph-x ph-bold ph-lg"></i></button>
 			</span>
-			<button class="_buttonPrimary" style="padding: 4px; border-radius: 8px;" @click="addVisibleUser"><i class="ti ti-plus ti-fw"></i></button>
+			<button class="_buttonPrimary" style="padding: 4px; border-radius: 5px;" @click="addVisibleUser"><i class="ph-plus ph-bold ph-lg ti-fw"></i></button>
 		</div>
 	</div>
 	<MkInfo v-if="hasNotSpecifiedMentions" warn :class="$style.hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo>
@@ -78,17 +78,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<footer :class="$style.footer">
 		<div :class="$style.footerLeft">
-			<button v-tooltip="i18n.ts.attachFile" class="_button" :class="$style.footerButton" @click="chooseFileFrom"><i class="ti ti-photo-plus"></i></button>
-			<button v-tooltip="i18n.ts.poll" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: poll }]" @click="togglePoll"><i class="ti ti-chart-arrows"></i></button>
-			<button v-tooltip="i18n.ts.useCw" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: useCw }]" @click="useCw = !useCw"><i class="ti ti-eye-off"></i></button>
-			<button v-tooltip="i18n.ts.mention" class="_button" :class="$style.footerButton" @click="insertMention"><i class="ti ti-at"></i></button>
-			<button v-tooltip="i18n.ts.hashtags" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: withHashtags }]" @click="withHashtags = !withHashtags"><i class="ti ti-hash"></i></button>
-			<button v-if="postFormActions.length > 0" v-tooltip="i18n.ts.plugin" class="_button" :class="$style.footerButton" @click="showActions"><i class="ti ti-plug"></i></button>
-			<button v-tooltip="i18n.ts.emoji" :class="['_button', $style.footerButton]" @click="insertEmoji"><i class="ti ti-mood-happy"></i></button>
+			<button v-tooltip="i18n.ts.attachFile" class="_button" :class="$style.footerButton" @click="chooseFileFrom"><i class="ph-image-square ph-bold ph-lg-plus"></i></button>
+			<button v-tooltip="i18n.ts.poll" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: poll }]" @click="togglePoll"><i class="ph-chart-bar-horizontal ph-bold pg-lg"></i></button>
+			<button v-tooltip="i18n.ts.useCw" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: useCw }]" @click="useCw = !useCw"><i class="ph-eye-slash ph-bold ph-lg"></i></button>
+			<button v-tooltip="i18n.ts.mention" class="_button" :class="$style.footerButton" @click="insertMention"><i class="ph-at ph-bold ph-lg"></i></button>
+			<button v-tooltip="i18n.ts.hashtags" class="_button" :class="[$style.footerButton, { [$style.footerButtonActive]: withHashtags }]" @click="withHashtags = !withHashtags"><i class="ph-hash ph-bold ph-lg"></i></button>
+			<button v-if="postFormActions.length > 0" v-tooltip="i18n.ts.plugin" class="_button" :class="$style.footerButton" @click="showActions"><i class="ph-plug ph-bold ph-lg"></i></button>
+			<button v-tooltip="i18n.ts.emoji" :class="['_button', $style.footerButton]" @click="insertEmoji"><i class="ph-smiley ph-bold ph-lg"></i></button>
 		</div>
 		<div :class="$style.footerRight">
-			<button v-tooltip="i18n.ts.previewNoteText" class="_button" :class="[$style.footerButton, { [$style.previewButtonActive]: showPreview }]" @click="showPreview = !showPreview"><i class="ti ti-eye"></i></button>
-			<!--<button v-tooltip="i18n.ts.more" class="_button" :class="$style.footerButton" @click="showingOptions = !showingOptions"><i class="ti ti-dots"></i></button>-->
+			<button v-tooltip="i18n.ts.previewNoteText" class="_button" :class="[$style.footerButton, { [$style.previewButtonActive]: showPreview }]" @click="showPreview = !showPreview"><i class="ph-eye ph-bold ph-lg"></i></button>
+			<!--<button v-tooltip="i18n.ts.more" class="_button" :class="$style.footerButton" @click="showingOptions = !showingOptions"><i class="ph-dots-three ph-bold ph-lg"></i></button>-->
 		</div>
 	</footer>
 	<datalist id="hashtags">
@@ -993,7 +993,7 @@ defineExpose({
 	padding: 0 12px;
 	line-height: 34px;
 	font-weight: bold;
-	border-radius: 6px;
+	border-radius: 5px;
 	min-width: 90px;
 	box-sizing: border-box;
 	color: var(--fgOnAccent);
@@ -1003,7 +1003,7 @@ defineExpose({
 .headerRightItem {
 	margin: 0;
 	padding: 8px;
-	border-radius: 6px;
+	border-radius: 5px;
 
 	&:hover {
 		background: var(--X5);
@@ -1066,7 +1066,7 @@ defineExpose({
 .visibleUser {
 	margin-right: 14px;
 	padding: 8px 0 8px 8px;
-	border-radius: 8px;
+	border-radius: 5px;
 	background: var(--X4);
 }
 
@@ -1135,7 +1135,7 @@ defineExpose({
 	padding: 4px 6px;
 	font-size: .9em;
 	color: var(--warn);
-	border-radius: 6px;
+	border-radius: 5px;
 	min-width: 1.6em;
 	text-align: center;
 
@@ -1175,7 +1175,7 @@ defineExpose({
 	font-size: 1em;
 	width: auto;
 	height: 100%;
-	border-radius: 6px;
+	border-radius: 5px;
 
 	&:hover {
 		background: var(--X5);
diff --git a/packages/frontend/src/components/MkPostFormAttaches.vue b/packages/frontend/src/components/MkPostFormAttaches.vue
index 624a44ecae..4fa0928223 100644
--- a/packages/frontend/src/components/MkPostFormAttaches.vue
+++ b/packages/frontend/src/components/MkPostFormAttaches.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div :class="$style.file" @click="showFileMenu(element, $event)" @contextmenu.prevent="showFileMenu(element, $event)">
 				<MkDriveFileThumbnail :data-id="element.id" :class="$style.thumbnail" :file="element" fit="cover"/>
 				<div v-if="element.isSensitive" :class="$style.sensitive">
-					<i class="ti ti-eye-exclamation" style="margin: auto;"></i>
+					<i class="ph-eye-closed ph-bold ph-lg" style="margin: auto;"></i>
 				</div>
 			</div>
 		</template>
@@ -103,23 +103,23 @@ function showFileMenu(file: Misskey.entities.DriveFile, ev: MouseEvent): void {
 	const isImage = file.type.startsWith('image/');
 	os.popupMenu([{
 		text: i18n.ts.renameFile,
-		icon: 'ti ti-forms',
+		icon: 'ph-textbox ph-bold ph-lg',
 		action: () => { rename(file); },
 	}, {
 		text: file.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive,
-		icon: file.isSensitive ? 'ti ti-eye-exclamation' : 'ti ti-eye',
+		icon: file.isSensitive ? 'ph-eye-closed ph-bold ph-lg' : 'ph-eye ph-bold ph-lg',
 		action: () => { toggleSensitive(file); },
 	}, {
 		text: i18n.ts.describeFile,
-		icon: 'ti ti-text-caption',
+		icon: 'ph-text-indent ph-bold ph-lg',
 		action: () => { describe(file); },
 	}, ...isImage ? [{
 		text: i18n.ts.cropImage,
-		icon: 'ti ti-crop',
+		icon: 'ph-crop ph-bold ph-lg',
 		action: () : void => { crop(file); },
 	}] : [], {
 		text: i18n.ts.attachCancel,
-		icon: 'ti ti-circle-x',
+		icon: 'ph-x-circle ph-bold ph-lg',
 		action: () => { detachMedia(file.id); },
 	}], ev.currentTarget ?? ev.target).then(() => menuShowing = false);
 	menuShowing = true;
diff --git a/packages/frontend/src/components/MkRadio.vue b/packages/frontend/src/components/MkRadio.vue
index c4df3e991b..e0eca18ed2 100644
--- a/packages/frontend/src/components/MkRadio.vue
+++ b/packages/frontend/src/components/MkRadio.vue
@@ -55,7 +55,7 @@ function toggle(): void {
 	background-color: var(--panel);
 	background-clip: padding-box !important;
 	border: solid 1px var(--panel);
-	border-radius: 6px;
+	border-radius: 5px;
 	font-size: 90%;
 	transition: all 0.2s;
 	user-select: none;
diff --git a/packages/frontend/src/components/MkRange.vue b/packages/frontend/src/components/MkRange.vue
index 2cfc27ceee..03d8da4393 100644
--- a/packages/frontend/src/components/MkRange.vue
+++ b/packages/frontend/src/components/MkRange.vue
@@ -181,7 +181,7 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
 		padding: 7px 12px;
 		background: var(--panel);
 		border: solid 1px var(--panel);
-		border-radius: 6px;
+		border-radius: 5px;
 
 		> .container {
 			position: relative;
@@ -197,7 +197,7 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
 				width: calc(100% - #{$thumbWidth});
 				height: 3px;
 				background: rgba(0, 0, 0, 0.1);
-				border-radius: 999px;
+				border-radius: 4px;
 				overflow: clip;
 
 				> .highlight {
@@ -228,7 +228,7 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
 					height: 3px;
 					margin-left: - math.div($tickWidth, 2);
 					background: var(--divider);
-					border-radius: 999px;
+					border-radius: 4px;
 				}
 			}
 
@@ -238,7 +238,7 @@ const onMousedown = (ev: MouseEvent | TouchEvent) => {
 				height: $thumbHeight;
 				cursor: grab;
 				background: var(--accent);
-				border-radius: 999px;
+				border-radius: 4px;
 
 				&:hover {
 					background: var(--accentLighten);
diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
index d0db515219..03c91e2ba6 100644
--- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue
+++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue
@@ -119,7 +119,7 @@ useTooltip(buttonEl, async (showing) => {
 	margin: 2px;
 	padding: 0 6px;
 	font-size: 1.5em;
-	border-radius: 6px;
+	border-radius: 5px;
 
 	&.canToggle {
 		background: var(--buttonBg);
@@ -147,7 +147,7 @@ useTooltip(buttonEl, async (showing) => {
 	&.large {
 		height: 52px;
 		font-size: 2em;
-		border-radius: 8px;
+		border-radius: 5px;
 
 		> .count {
 			font-size: 0.6em;
diff --git a/packages/frontend/src/components/MkRemoteCaution.vue b/packages/frontend/src/components/MkRemoteCaution.vue
index 0ce67e872b..702279ae58 100644
--- a/packages/frontend/src/components/MkRemoteCaution.vue
+++ b/packages/frontend/src/components/MkRemoteCaution.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <template>
-<div :class="$style.root"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i>{{ i18n.ts.remoteUserCaution }}<a :class="$style.link" :href="href" rel="nofollow noopener" target="_blank">{{ i18n.ts.showOnRemote }}</a></div>
+<div :class="$style.root"><i class="ph-warning ph-bold ph-lg" style="margin-right: 8px;"></i>{{ i18n.ts.remoteUserCaution }}<a :class="$style.link" :href="href" rel="nofollow noopener" target="_blank">{{ i18n.ts.showOnRemote }}</a></div>
 </template>
 
 <script lang="ts" setup>
diff --git a/packages/frontend/src/components/MkRolePreview.vue b/packages/frontend/src/components/MkRolePreview.vue
index 3e4586cee4..0e8ce35609 100644
--- a/packages/frontend/src/components/MkRolePreview.vue
+++ b/packages/frontend/src/components/MkRolePreview.vue
@@ -11,9 +11,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<img :class="$style.badge" :src="role.iconUrl"/>
 			</template>
 			<template v-else>
-				<i v-if="role.isAdministrator" class="ti ti-crown" style="color: var(--accent);"></i>
-				<i v-else-if="role.isModerator" class="ti ti-shield" style="color: var(--accent);"></i>
-				<i v-else class="ti ti-user" style="opacity: 0.7;"></i>
+				<i v-if="role.isAdministrator" class="ph-crown ph-bold ph-lg" style="color: var(--accent);"></i>
+				<i v-else-if="role.isModerator" class="ph-shield ph-bold ph-lg" style="color: var(--accent);"></i>
+				<i v-else class="ph-user ph-bold ph-lg" style="opacity: 0.7;"></i>
 			</template>
 		</span>
 		<span :class="$style.name">{{ role.name }}</span>
diff --git a/packages/frontend/src/components/MkSelect.vue b/packages/frontend/src/components/MkSelect.vue
index 5a1c788005..83563587e2 100644
--- a/packages/frontend/src/components/MkSelect.vue
+++ b/packages/frontend/src/components/MkSelect.vue
@@ -23,11 +23,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 		>
 			<slot></slot>
 		</select>
-		<div ref="suffixEl" :class="$style.suffix"><i class="ti ti-chevron-down" :class="[$style.chevron, { [$style.chevronOpening]: opening }]"></i></div>
+		<div ref="suffixEl" :class="$style.suffix"><i class="ph-caret-down ph-bold ph-lg" :class="[$style.chevron, { [$style.chevronOpening]: opening }]"></i></div>
 	</div>
 	<div :class="$style.caption"><slot name="caption"></slot></div>
 
-	<MkButton v-if="manualSave && changed" primary @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton v-if="manualSave && changed" primary @click="updated"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
@@ -241,7 +241,7 @@ function show(ev: MouseEvent) {
 	color: var(--fg);
 	background: var(--panel);
 	border: solid 1px var(--panel);
-	border-radius: 6px;
+	border-radius: 5px;
 	outline: none;
 	box-shadow: none;
 	box-sizing: border-box;
diff --git a/packages/frontend/src/components/MkSignin.vue b/packages/frontend/src/components/MkSignin.vue
index 0fd67a0b46..4fddc3f27b 100644
--- a/packages/frontend/src/components/MkSignin.vue
+++ b/packages/frontend/src/components/MkSignin.vue
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<template #suffix>@{{ host }}</template>
 			</MkInput>
 			<MkInput v-if="!user || user && !user.usePasswordLessLogin" v-model="password" :placeholder="i18n.ts.password" type="password" autocomplete="current-password webauthn" :withPasswordToggle="true" required data-cy-signin-password>
-				<template #prefix><i class="ti ti-lock"></i></template>
+				<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 				<template #caption><button class="_textButton" type="button" @click="resetPassword">{{ i18n.ts.forgotPassword }}</button></template>
 			</MkInput>
 			<MkButton type="submit" large primary rounded :disabled="signing" style="margin: 0 auto;">{{ signing ? i18n.ts.loggingIn : i18n.ts.login }}</MkButton>
@@ -35,11 +35,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<p style="margin-bottom:0;">{{ i18n.ts['2fa'] }}</p>
 				<MkInput v-if="user && user.usePasswordLessLogin" v-model="password" type="password" autocomplete="current-password" :withPasswordToggle="true" required>
 					<template #label>{{ i18n.ts.password }}</template>
-					<template #prefix><i class="ti ti-lock"></i></template>
+					<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 				</MkInput>
 				<MkInput v-model="token" type="text" pattern="^([0-9]{6}|[A-Z0-9]{32})$" autocomplete="one-time-code" :spellcheck="false" required>
 					<template #label>{{ i18n.ts.token }}</template>
-					<template #prefix><i class="ti ti-123"></i></template>
+					<template #prefix><i class="ph-keyhole ph-bold pg-lg"></i></template>
 				</MkInput>
 				<MkButton type="submit" :disabled="signing" large primary rounded style="margin: 0 auto;">{{ signing ? i18n.ts.loggingIn : i18n.ts.login }}</MkButton>
 			</div>
diff --git a/packages/frontend/src/components/MkSignupDialog.form.vue b/packages/frontend/src/components/MkSignupDialog.form.vue
index a67251eda1..174b042649 100644
--- a/packages/frontend/src/components/MkSignupDialog.form.vue
+++ b/packages/frontend/src/components/MkSignupDialog.form.vue
@@ -6,59 +6,59 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div>
 	<div :class="$style.banner">
-		<i class="ti ti-user-edit"></i>
+		<i class="ph-user-list ph-bold ph-lg"></i>
 	</div>
 	<MkSpacer :marginMin="20" :marginMax="32">
 		<form class="_gaps_m" autocomplete="new-password" @submit.prevent="onSubmit">
 			<MkInput v-if="instance.disableRegistration" v-model="invitationCode" type="text" :spellcheck="false" required>
 				<template #label>{{ i18n.ts.invitationCode }}</template>
-				<template #prefix><i class="ti ti-key"></i></template>
+				<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 			</MkInput>
 			<MkInput v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false" autocomplete="username" 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="ti ti-help-circle"></i></div></template>
+				<template #label>{{ i18n.ts.username }} <div v-tooltip:dialog="i18n.ts.usernameInfo" class="_button _help"><i class="ph-question ph-bold ph-lg"></i></div></template>
 				<template #prefix>@</template>
 				<template #suffix>@{{ host }}</template>
 				<template #caption>
-					<div><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.cannotBeChangedLater }}</div>
+					<div><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.cannotBeChangedLater }}</div>
 					<span v-if="usernameState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{ 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>
+					<span v-else-if="usernameState === 'ok'" style="color: var(--success)"><i class="ph-check ph-bold ph-lg ti-fw"></i> {{ i18n.ts.available }}</span>
+					<span v-else-if="usernameState === 'unavailable'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.unavailable }}</span>
+					<span v-else-if="usernameState === 'error'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.error }}</span>
+					<span v-else-if="usernameState === 'invalid-format'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.usernameInvalidFormat }}</span>
+					<span v-else-if="usernameState === 'min-range'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.tooShort }}</span>
+					<span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.tooLong }}</span>
 				</template>
 			</MkInput>
 			<MkInput v-if="instance.emailRequiredForSignup" v-model="email" :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="ti ti-help-circle"></i></div></template>
-				<template #prefix><i class="ti ti-mail"></i></template>
+				<template #label>{{ i18n.ts.emailAddress }} <div v-tooltip:dialog="i18n.ts._signup.emailAddressInfo" class="_button _help"><i class="ph-question ph-bold ph-lg"></i></div></template>
+				<template #prefix><i class="ph-envelope ph-bold ph-lg"></i></template>
 				<template #caption>
 					<span v-if="emailState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{ 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>
+					<span v-else-if="emailState === 'ok'" style="color: var(--success)"><i class="ph-check ph-bold ph-lg ti-fw"></i> {{ i18n.ts.available }}</span>
+					<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
+					<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
+					<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
+					<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
+					<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
+					<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.unavailable }}</span>
+					<span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.error }}</span>
 				</template>
 			</MkInput>
 			<MkInput v-model="password" type="password" autocomplete="new-password" required data-cy-signup-password @update:modelValue="onChangePassword">
 				<template #label>{{ i18n.ts.password }}</template>
-				<template #prefix><i class="ti ti-lock"></i></template>
+				<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 				<template #caption>
-					<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>
+					<span v-if="passwordStrength == 'low'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.weakPassword }}</span>
+					<span v-if="passwordStrength == 'medium'" style="color: var(--warn)"><i class="ph-check ph-bold ph-lg ti-fw"></i> {{ i18n.ts.normalPassword }}</span>
+					<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="ph-check ph-bold ph-lg ti-fw"></i> {{ i18n.ts.strongPassword }}</span>
 				</template>
 			</MkInput>
 			<MkInput v-model="retypedPassword" 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="ti ti-lock"></i></template>
+				<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 				<template #caption>
-					<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>
+					<span v-if="passwordRetypeState == 'match'" style="color: var(--success)"><i class="ph-check ph-bold ph-lg ti-fw"></i> {{ i18n.ts.passwordMatched }}</span>
+					<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="ph-warning ph-bold ph-lg ti-fw"></i> {{ i18n.ts.passwordNotMatched }}</span>
 				</template>
 			</MkInput>
 			<MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :class="$style.captcha" provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/>
diff --git a/packages/frontend/src/components/MkSignupDialog.rules.vue b/packages/frontend/src/components/MkSignupDialog.rules.vue
index aa4a184d7b..c58107bd1f 100644
--- a/packages/frontend/src/components/MkSignupDialog.rules.vue
+++ b/packages/frontend/src/components/MkSignupDialog.rules.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div>
 	<div :class="$style.banner">
-		<i class="ti ti-checklist"></i>
+		<i class="ph-check ph-bold ph-lglist"></i>
 	</div>
 	<MkSpacer :marginMin="20" :marginMax="28">
 		<div class="_gaps_m">
@@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 			<MkFolder v-if="availableServerRules" :defaultOpen="true">
 				<template #label>{{ i18n.ts.serverRules }}</template>
-				<template #suffix><i v-if="agreeServerRules" class="ti ti-check" style="color: var(--success)"></i></template>
+				<template #suffix><i v-if="agreeServerRules" class="ph-check ph-bold ph-lg" style="color: var(--success)"></i></template>
 
 				<ol class="_gaps_s" :class="$style.rules">
 					<li v-for="item in instance.serverRules" :class="$style.rule"><div :class="$style.ruleText" v-html="item"></div></li>
@@ -32,18 +32,18 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 			<MkFolder v-if="availableTos" :defaultOpen="true">
 				<template #label>{{ i18n.ts.termsOfService }}</template>
-				<template #suffix><i v-if="agreeTos" class="ti ti-check" style="color: var(--success)"></i></template>
+				<template #suffix><i v-if="agreeTos" class="ph-check ph-bold ph-lg" style="color: var(--success)"></i></template>
 
-				<a :href="instance.tosUrl" class="_link" target="_blank">{{ i18n.ts.termsOfService }} <i class="ti ti-external-link"></i></a>
+				<a :href="instance.tosUrl" class="_link" target="_blank">{{ i18n.ts.termsOfService }} <i class="ph-arrow-square-out ph-bold ph-lg"></i></a>
 
 				<MkSwitch :modelValue="agreeTos" style="margin-top: 16px;" @update:modelValue="updateAgreeTos">{{ i18n.ts.agree }}</MkSwitch>
 			</MkFolder>
 
 			<MkFolder :defaultOpen="true">
 				<template #label>{{ i18n.ts.basicNotesBeforeCreateAccount }}</template>
-				<template #suffix><i v-if="agreeNote" class="ti ti-check" style="color: var(--success)"></i></template>
+				<template #suffix><i v-if="agreeNote" class="ph-check ph-bold ph-lg" style="color: var(--success)"></i></template>
 
-				<a href="https://misskey-hub.net/docs/notes.html" class="_link" target="_blank">{{ i18n.ts.basicNotesBeforeCreateAccount }} <i class="ti ti-external-link"></i></a>
+				<a href="https://misskey-hub.net/docs/notes.html" class="_link" target="_blank">{{ i18n.ts.basicNotesBeforeCreateAccount }} <i class="ph-arrow-square-out ph-bold ph-lg"></i></a>
 
 				<MkSwitch :modelValue="agreeNote" style="margin-top: 16px;" data-cy-signup-rules-notes-agree @update:modelValue="updateAgreeNote">{{ i18n.ts.agree }}</MkSwitch>
 			</MkFolder>
@@ -52,7 +52,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 			<div class="_buttonsCenter">
 				<MkButton inline rounded @click="emit('cancel')">{{ i18n.ts.cancel }}</MkButton>
-				<MkButton inline primary rounded gradate :disabled="!agreed" data-cy-signup-rules-continue @click="emit('done')">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
+				<MkButton inline primary rounded gradate :disabled="!agreed" data-cy-signup-rules-continue @click="emit('done')">{{ i18n.ts.continue }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 			</div>
 		</div>
 	</MkSpacer>
@@ -165,7 +165,7 @@ async function updateAgreeNote(v: boolean) {
 		font-weight: bold;
 		align-items: center;
 		justify-content: center;
-		border-radius: 999px;
+		border-radius: 4px;
 	}
 }
 
diff --git a/packages/frontend/src/components/MkSubNoteContent.vue b/packages/frontend/src/components/MkSubNoteContent.vue
index 14d08968d1..021dc0d863 100644
--- a/packages/frontend/src/components/MkSubNoteContent.vue
+++ b/packages/frontend/src/components/MkSubNoteContent.vue
@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div @click="noteclick(note.id)">
 		<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="$style.reply" :to="`/notes/${note.replyId}`" v-on:click.stop><i class="ti ti-arrow-back-up"></i></MkA>
+		<MkA v-if="note.replyId" :class="$style.reply" :to="`/notes/${note.replyId}`" v-on:click.stop><i class="ph-arrow-bend-left-up ph-bold pg-lg"></i></MkA>
 		<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i" :emojiUrls="note.emojis"/>
 		<MkA v-if="note.renoteId" :class="$style.rp" :to="`/notes/${note.renoteId}`" v-on:click.stop>RN: ...</MkA>
 	</div>
@@ -78,7 +78,7 @@ const collapsed = $ref(isLong);
 				background: var(--panel);
 				padding: 6px 10px;
 				font-size: 0.8em;
-				border-radius: 999px;
+				border-radius: 4px;
 				box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
 			}
 
@@ -114,7 +114,7 @@ const collapsed = $ref(isLong);
 	background: var(--popup);
 	padding: 6px 10px;
 	font-size: 0.8em;
-	border-radius: 999px;
+	border-radius: 4px;
 	box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
 }
 </style>
diff --git a/packages/frontend/src/components/MkSuperMenu.vue b/packages/frontend/src/components/MkSuperMenu.vue
index efd5665396..f5af327820 100644
--- a/packages/frontend/src/components/MkSuperMenu.vue
+++ b/packages/frontend/src/components/MkSuperMenu.vue
@@ -59,7 +59,7 @@ defineProps<{
 				width: 100%;
 				box-sizing: border-box;
 				padding: 9px 16px 9px 8px;
-				border-radius: 9px;
+				border-radius: 5px;
 				font-size: 0.9em;
 
 				&:hover {
diff --git a/packages/frontend/src/components/MkSwitch.button.vue b/packages/frontend/src/components/MkSwitch.button.vue
index a7e91acc39..9d20103364 100644
--- a/packages/frontend/src/components/MkSwitch.button.vue
+++ b/packages/frontend/src/components/MkSwitch.button.vue
@@ -52,7 +52,7 @@ const toggle = () => {
 	background: var(--switchOffBg);
 	background-clip: content-box;
 	border: solid 1px var(--switchOffBg);
-	border-radius: 999px;
+	border-radius: 4px;
 	cursor: pointer;
 	transition: inherit;
 	user-select: none;
@@ -72,7 +72,7 @@ const toggle = () => {
 	top: 3px;
 	width: 15px;
 	height: 15px;
-	border-radius: 999px;
+	border-radius: 4px;
 	transition: all 0.2s ease;
 
 	&:not(.knobChecked) {
diff --git a/packages/frontend/src/components/MkSwitch.vue b/packages/frontend/src/components/MkSwitch.vue
index 8e946e7437..7521bd6c76 100644
--- a/packages/frontend/src/components/MkSwitch.vue
+++ b/packages/frontend/src/components/MkSwitch.vue
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<span @click="toggle">
 				<slot name="label"></slot><slot></slot>
 			</span>
-			<span v-if="helpText" v-tooltip:dialog="helpText" class="_button _help" :class="$style.help"><i class="ti ti-help-circle"></i></span>
+			<span v-if="helpText" v-tooltip:dialog="helpText" class="_button _help" :class="$style.help"><i class="ph-question ph-bold ph-lg"></i></span>
 		</span>
 		<p :class="$style.caption"><slot name="caption"></slot></p>
 	</span>
diff --git a/packages/frontend/src/components/MkTab.vue b/packages/frontend/src/components/MkTab.vue
index 9785d89403..2b93d2eb4f 100644
--- a/packages/frontend/src/components/MkTab.vue
+++ b/packages/frontend/src/components/MkTab.vue
@@ -39,7 +39,7 @@ export default defineComponent({
 	> button {
 		flex: 1;
 		padding: 10px 8px;
-		border-radius: 999px;
+		border-radius: 4px;
 
 		&:disabled {
 			opacity: 1 !important;
diff --git a/packages/frontend/src/components/MkTextarea.vue b/packages/frontend/src/components/MkTextarea.vue
index 7c1ddcbbed..036ad3b9e7 100644
--- a/packages/frontend/src/components/MkTextarea.vue
+++ b/packages/frontend/src/components/MkTextarea.vue
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="$style.caption"><slot name="caption"></slot></div>
 
-	<MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
@@ -153,7 +153,7 @@ onMounted(() => {
 	color: var(--fg);
 	background: var(--panel);
 	border: solid 1px var(--panel);
-	border-radius: 6px;
+	border-radius: 5px;
 	outline: none;
 	box-shadow: none;
 	box-sizing: border-box;
diff --git a/packages/frontend/src/components/MkToast.vue b/packages/frontend/src/components/MkToast.vue
index 48908cf3e6..78eccd0618 100644
--- a/packages/frontend/src/components/MkToast.vue
+++ b/packages/frontend/src/components/MkToast.vue
@@ -66,7 +66,7 @@ onMounted(() => {
 	max-width: calc(100% - 32px);
 	width: min-content;
 	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
-	border-radius: 8px;
+	border-radius: 5px;
 	overflow: clip;
 	text-align: center;
 	pointer-events: none;
diff --git a/packages/frontend/src/components/MkUrlPreview.vue b/packages/frontend/src/components/MkUrlPreview.vue
index e2844f8fa1..9cec4009c8 100644
--- a/packages/frontend/src/components/MkUrlPreview.vue
+++ b/packages/frontend/src/components/MkUrlPreview.vue
@@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="$style.action">
 		<MkButton :small="true" inline @click="playerEnabled = false">
-			<i class="ti ti-x"></i> {{ i18n.ts.disablePlayer }}
+			<i class="ph-x ph-bold ph-lg"></i> {{ i18n.ts.disablePlayer }}
 		</MkButton>
 	</div>
 </template>
@@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="$style.action">
 		<MkButton :small="true" inline @click="tweetExpanded = false">
-			<i class="ti ti-x"></i> {{ i18n.ts.close }}
+			<i class="ph-x ph-bold ph-lg"></i> {{ i18n.ts.close }}
 		</MkButton>
 	</div>
 </template>
@@ -67,15 +67,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template v-if="showActions">
 		<div v-if="tweetId" :class="$style.action">
 			<MkButton :small="true" inline @click="tweetExpanded = true">
-				<i class="ti ti-brand-x"></i> {{ i18n.ts.expandTweet }}
+				<i class="ph-twitter-logo ph-bold ph-lg"></i> {{ i18n.ts.expandTweet }}
 			</MkButton>
 		</div>
 		<div v-if="!playerEnabled && player.url" :class="$style.action">
 			<MkButton :small="true" inline @click="playerEnabled = true">
-				<i class="ti ti-player-play"></i> {{ i18n.ts.enablePlayer }}
+				<i class="ph-play ph-bold pg-lg"></i> {{ i18n.ts.enablePlayer }}
 			</MkButton>
 			<MkButton v-if="!isMobile" :small="true" inline @click="openPlayer()">
-				<i class="ti ti-picture-in-picture"></i> {{ i18n.ts.openInWindow }}
+				<i class="ph-picture-in-picture ph-bold ph-lg"></i> {{ i18n.ts.openInWindow }}
 			</MkButton>
 		</div>
 	</template>
@@ -231,7 +231,7 @@ onUnmounted(() => {
 	display: block;
 	font-size: 14px;
 	box-shadow: 0 0 0 1px var(--divider);
-	border-radius: 8px;
+	border-radius: 5px;
 	overflow: clip;
 
 	&:hover {
diff --git a/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue b/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue
index 235df8822f..42ccb621b6 100644
--- a/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue
+++ b/packages/frontend/src/components/MkUserAnnouncementEditDialog.vue
@@ -24,10 +24,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</MkTextarea>
 				<MkRadios v-model="icon">
 					<template #label>{{ i18n.ts.icon }}</template>
-					<option value="info"><i class="ti ti-info-circle"></i></option>
-					<option value="warning"><i class="ti ti-alert-triangle" style="color: var(--warn);"></i></option>
-					<option value="error"><i class="ti ti-circle-x" style="color: var(--error);"></i></option>
-					<option value="success"><i class="ti ti-check" style="color: var(--success);"></i></option>
+					<option value="info"><i class="ph-info ph-bold ph-lg"></i></option>
+					<option value="warning"><i class="ph-warning ph-bold ph-lg" style="color: var(--warn);"></i></option>
+					<option value="error"><i class="ph-x-circle ph-bold ph-lg" style="color: var(--error);"></i></option>
+					<option value="success"><i class="ph-check ph-bold ph-lg" style="color: var(--success);"></i></option>
 				</MkRadios>
 				<MkRadios v-model="display">
 					<template #label>{{ i18n.ts.display }}</template>
@@ -39,11 +39,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 					{{ i18n.ts._announcement.needConfirmationToRead }}
 					<template #caption>{{ i18n.ts._announcement.needConfirmationToReadDescription }}</template>
 				</MkSwitch>
-				<MkButton v-if="announcement" danger @click="del()"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+				<MkButton v-if="announcement" danger @click="del()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 			</div>
 		</MkSpacer>
 		<div :class="$style.footer">
-			<MkButton primary rounded style="margin: 0 auto;" @click="done"><i class="ti ti-check"></i> {{ props.announcement ? i18n.ts.update : i18n.ts.create }}</MkButton>
+			<MkButton primary rounded style="margin: 0 auto;" @click="done"><i class="ph-check ph-bold ph-lg"></i> {{ props.announcement ? i18n.ts.update : i18n.ts.create }}</MkButton>
 		</div>
 	</div>
 </MkModalWindow>
diff --git a/packages/frontend/src/components/MkUserCardMini.vue b/packages/frontend/src/components/MkUserCardMini.vue
index fbc2e09b0b..465a109887 100644
--- a/packages/frontend/src/components/MkUserCardMini.vue
+++ b/packages/frontend/src/components/MkUserCardMini.vue
@@ -50,7 +50,7 @@ onMounted(() => {
 	align-items: center;
 	padding: 16px;
 	background: var(--panel);
-	border-radius: 8px;
+	border-radius: 5px;
 
 	> :global(.avatar) {
 		display: block;
diff --git a/packages/frontend/src/components/MkUserInfo.vue b/packages/frontend/src/components/MkUserInfo.vue
index c13ef60f3b..6bb2fc8957 100644
--- a/packages/frontend/src/components/MkUserInfo.vue
+++ b/packages/frontend/src/components/MkUserInfo.vue
@@ -100,7 +100,7 @@ defineProps<{
 	color: #fff;
 	background: rgba(0, 0, 0, 0.7);
 	font-size: 0.7em;
-	border-radius: 6px;
+	border-radius: 5px;
 }
 
 .description {
diff --git a/packages/frontend/src/components/MkUserPopup.vue b/packages/frontend/src/components/MkUserPopup.vue
index 33ef07d54b..da75bbc1c2 100644
--- a/packages/frontend/src/components/MkUserPopup.vue
+++ b/packages/frontend/src/components/MkUserPopup.vue
@@ -44,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<div>{{ number(user.followersCount) }}</div>
 				</div>
 			</div>
-			<button class="_button" :class="$style.menu" @click="showMenu"><i class="ti ti-dots"></i></button>
+			<button class="_button" :class="$style.menu" @click="showMenu"><i class="ph-dots-three ph-bold ph-lg"></i></button>
 			<MkFollowButton v-if="$i && user.id != $i.id" :class="$style.follow" :user="user" mini/>
 		</div>
 		<div v-else>
@@ -145,7 +145,7 @@ onMounted(() => {
 	color: #fff;
 	background: rgba(0, 0, 0, 0.7);
 	font-size: 0.7em;
-	border-radius: 6px;
+	border-radius: 5px;
 }
 
 .avatarBack {
@@ -226,7 +226,7 @@ onMounted(() => {
 	right: 44px;
 	padding: 6px;
 	background: var(--panel);
-	border-radius: 999px;
+	border-radius: 4px;
 }
 
 .follow {
diff --git a/packages/frontend/src/components/MkUserSetupDialog.Privacy.vue b/packages/frontend/src/components/MkUserSetupDialog.Privacy.vue
index 841ab5ba0c..07ea6d5849 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.Privacy.vue
+++ b/packages/frontend/src/components/MkUserSetupDialog.Privacy.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<MkFolder>
 		<template #label>{{ i18n.ts.makeFollowManuallyApprove }}</template>
-		<template #icon><i class="ti ti-lock"></i></template>
+		<template #icon><i class="ph-lock ph-bold ph-lg"></i></template>
 		<template #suffix>{{ isLocked ? i18n.ts.on : i18n.ts.off }}</template>
 
 		<MkSwitch v-model="isLocked">{{ i18n.ts.makeFollowManuallyApprove }}<template #caption>{{ i18n.ts.lockedAccountInfo }}</template></MkSwitch>
@@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<MkFolder>
 		<template #label>{{ i18n.ts.hideOnlineStatus }}</template>
-		<template #icon><i class="ti ti-eye-off"></i></template>
+		<template #icon><i class="ph-eye-slash ph-bold ph-lg"></i></template>
 		<template #suffix>{{ hideOnlineStatus ? i18n.ts.on : i18n.ts.off }}</template>
 
 		<MkSwitch v-model="hideOnlineStatus">{{ i18n.ts.hideOnlineStatus }}<template #caption>{{ i18n.ts.hideOnlineStatusDescription }}</template></MkSwitch>
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<MkFolder>
 		<template #label>{{ i18n.ts.noCrawle }}</template>
-		<template #icon><i class="ti ti-world-x"></i></template>
+		<template #icon><i class="ph-planet ph-bold ph-lg"></i></template>
 		<template #suffix>{{ noCrawle ? i18n.ts.on : i18n.ts.off }}</template>
 
 		<MkSwitch v-model="noCrawle">{{ i18n.ts.noCrawle }}<template #caption>{{ i18n.ts.noCrawleDescription }}</template></MkSwitch>
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<MkFolder>
 		<template #label>{{ i18n.ts.preventAiLearning }}</template>
-		<template #icon><i class="ti ti-photo-shield"></i></template>
+		<template #icon><i class="ph-image-square ph-bold ph-lg-shield"></i></template>
 		<template #suffix>{{ preventAiLearning ? i18n.ts.on : i18n.ts.off }}</template>
 
 		<MkSwitch v-model="preventAiLearning">{{ i18n.ts.preventAiLearning }}<template #caption>{{ i18n.ts.preventAiLearningDescription }}</template></MkSwitch>
diff --git a/packages/frontend/src/components/MkUserSetupDialog.User.vue b/packages/frontend/src/components/MkUserSetupDialog.User.vue
index 746781d71f..69cbdcf763 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.User.vue
+++ b/packages/frontend/src/components/MkUserSetupDialog.User.vue
@@ -18,8 +18,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<span v-else style="opacity: 0.7;">{{ i18n.ts.noAccountDescription }}</span>
 	</div>
 	<div :class="$style.footer">
-		<MkButton v-if="!isFollowing" primary gradate rounded full @click="follow"><i class="ti ti-plus"></i> {{ i18n.ts.follow }}</MkButton>
-		<div v-else style="opacity: 0.7; text-align: center;">{{ i18n.ts.youFollowing }} <i class="ti ti-check"></i></div>
+		<MkButton v-if="!isFollowing" primary gradate rounded full @click="follow"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.follow }}</MkButton>
+		<div v-else style="opacity: 0.7; text-align: center;">{{ i18n.ts.youFollowing }} <i class="ph-check ph-bold ph-lg"></i></div>
 	</div>
 </div>
 </template>
diff --git a/packages/frontend/src/components/MkUserSetupDialog.vue b/packages/frontend/src/components/MkUserSetupDialog.vue
index d60e01c44d..0ec42a4a7c 100644
--- a/packages/frontend/src/components/MkUserSetupDialog.vue
+++ b/packages/frontend/src/components/MkUserSetupDialog.vue
@@ -12,10 +12,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 	@close="close(true)"
 	@closed="emit('closed')"
 >
-	<template v-if="page === 1" #header><i class="ti ti-user-edit"></i> {{ i18n.ts._initialAccountSetting.profileSetting }}</template>
-	<template v-else-if="page === 2" #header><i class="ti ti-lock"></i> {{ i18n.ts._initialAccountSetting.privacySetting }}</template>
-	<template v-else-if="page === 3" #header><i class="ti ti-user-plus"></i> {{ i18n.ts.follow }}</template>
-	<template v-else-if="page === 4" #header><i class="ti ti-bell-plus"></i> {{ i18n.ts.pushNotification }}</template>
+	<template v-if="page === 1" #header><i class="ph-user-list ph-bold ph-lg"></i> {{ i18n.ts._initialAccountSetting.profileSetting }}</template>
+	<template v-else-if="page === 2" #header><i class="ph-lock ph-bold ph-lg"></i> {{ i18n.ts._initialAccountSetting.privacySetting }}</template>
+	<template v-else-if="page === 3" #header><i class="ph-user-plus ph-bold ph-lg"></i> {{ i18n.ts.follow }}</template>
+	<template v-else-if="page === 4" #header><i class="ph-bell-ringing ph-bold pg-lg"></i> {{ i18n.ts.pushNotification }}</template>
 	<template v-else-if="page === 5" #header>{{ i18n.ts.done }}</template>
 	<template v-else #header>{{ i18n.ts.initialAccountSetting }}</template>
 
@@ -35,10 +35,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkAnimBg style="position: absolute; top: 0;" :scale="1.5"/>
 					<MkSpacer :marginMin="20" :marginMax="28">
 						<div class="_gaps" style="text-align: center;">
-							<i class="ti ti-confetti" style="display: block; margin: auto; font-size: 3em; color: var(--accent);"></i>
+							<i class="ph-confetti ph-bold ph-lg" style="display: block; margin: auto; font-size: 3em; color: var(--accent);"></i>
 							<div style="font-size: 120%;">{{ i18n.ts._initialAccountSetting.accountCreated }}</div>
 							<div>{{ i18n.ts._initialAccountSetting.letsStartAccountSetup }}</div>
-							<MkButton primary rounded gradate style="margin: 16px auto 0 auto;" data-cy-user-setup-continue @click="page++">{{ i18n.ts._initialAccountSetting.profileSetting }} <i class="ti ti-arrow-right"></i></MkButton>
+							<MkButton primary rounded gradate style="margin: 16px auto 0 auto;" data-cy-user-setup-continue @click="page++">{{ i18n.ts._initialAccountSetting.profileSetting }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 							<MkButton style="margin: 0 auto;" transparent rounded @click="later(true)">{{ i18n.ts.later }}</MkButton>
 						</div>
 					</MkSpacer>
@@ -49,8 +49,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkSpacer :marginMin="20" :marginMax="28">
 						<XProfile/>
 						<div class="_buttonsCenter" style="margin-top: 16px;">
-							<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton>
-							<MkButton primary rounded gradate data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
+							<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ph-arrow-left ph-bold pg-lg"></i> {{ i18n.ts.goBack }}</MkButton>
+							<MkButton primary rounded gradate data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 						</div>
 					</MkSpacer>
 				</div>
@@ -60,8 +60,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkSpacer :marginMin="20" :marginMax="28">
 						<XPrivacy/>
 						<div class="_buttonsCenter" style="margin-top: 16px;">
-							<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton>
-							<MkButton primary rounded gradate data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
+							<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ph-arrow-left ph-bold pg-lg"></i> {{ i18n.ts.goBack }}</MkButton>
+							<MkButton primary rounded gradate data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 						</div>
 					</MkSpacer>
 				</div>
@@ -73,8 +73,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</MkSpacer>
 					<div :class="$style.pageFooter">
 						<div class="_buttonsCenter">
-							<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton>
-							<MkButton primary rounded gradate style="" data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
+							<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ph-arrow-left ph-bold pg-lg"></i> {{ i18n.ts.goBack }}</MkButton>
+							<MkButton primary rounded gradate style="" data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 						</div>
 					</div>
 				</div>
@@ -83,13 +83,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div :class="$style.centerPage">
 					<MkSpacer :marginMin="20" :marginMax="28">
 						<div class="_gaps" style="text-align: center;">
-							<i class="ti ti-bell-ringing-2" style="display: block; margin: auto; font-size: 3em; color: var(--accent);"></i>
+							<i class="ph-bell-ringing ph-bold pg-lg" style="display: block; margin: auto; font-size: 3em; color: var(--accent);"></i>
 							<div style="font-size: 120%;">{{ i18n.ts.pushNotification }}</div>
 							<div style="padding: 0 16px;">{{ i18n.t('_initialAccountSetting.pushNotificationDescription', { name: instance.name ?? host }) }}</div>
 							<MkPushNotificationAllowButton primary showOnlyToRegister style="margin: 0 auto;"/>
 							<div class="_buttonsCenter" style="margin-top: 16px;">
-								<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton>
-								<MkButton primary rounded gradate data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
+								<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ph-arrow-left ph-bold pg-lg"></i> {{ i18n.ts.goBack }}</MkButton>
+								<MkButton primary rounded gradate data-cy-user-setup-continue @click="page++">{{ i18n.ts.continue }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 							</div>
 						</div>
 					</MkSpacer>
@@ -100,7 +100,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkAnimBg style="position: absolute; top: 0;" :scale="1.5"/>
 					<MkSpacer :marginMin="20" :marginMax="28">
 						<div class="_gaps" style="text-align: center;">
-							<i class="ti ti-check" style="display: block; margin: auto; font-size: 3em; color: var(--accent);"></i>
+							<i class="ph-check ph-bold ph-lg" style="display: block; margin: auto; font-size: 3em; color: var(--accent);"></i>
 							<div style="font-size: 120%;">{{ i18n.ts._initialAccountSetting.initialAccountSettingCompleted }}</div>
 							<I18n :src="i18n.ts._initialAccountSetting.ifYouNeedLearnMore" tag="div" style="padding: 0 16px;">
 								<template #name>{{ instance.name ?? host }}</template>
@@ -110,7 +110,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 							</I18n>
 							<div>{{ i18n.t('_initialAccountSetting.haveFun', { name: instance.name ?? host }) }}</div>
 							<div class="_buttonsCenter" style="margin-top: 16px;">
-								<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton>
+								<MkButton rounded data-cy-user-setup-back @click="page--"><i class="ph-arrow-left ph-bold pg-lg"></i> {{ i18n.ts.goBack }}</MkButton>
 								<MkButton primary rounded gradate data-cy-user-setup-continue @click="close(false)">{{ i18n.ts.close }}</MkButton>
 							</div>
 						</div>
diff --git a/packages/frontend/src/components/MkVisibilityPicker.vue b/packages/frontend/src/components/MkVisibilityPicker.vue
index 982a69925b..675de076a6 100644
--- a/packages/frontend/src/components/MkVisibilityPicker.vue
+++ b/packages/frontend/src/components/MkVisibilityPicker.vue
@@ -10,28 +10,28 @@ SPDX-License-Identifier: AGPL-3.0-only
 			{{ i18n.ts.visibility }}
 		</div>
 		<button key="public" class="_button" :class="[$style.item, { [$style.active]: v === 'public' }]" data-index="1" @click="choose('public')">
-			<div :class="$style.icon"><i class="ti ti-world"></i></div>
+			<div :class="$style.icon"><i class="ph-globe-hemisphere-west ph-bold ph-lg"></i></div>
 			<div :class="$style.body">
 				<span :class="$style.itemTitle">{{ i18n.ts._visibility.public }}</span>
 				<span :class="$style.itemDescription">{{ i18n.ts._visibility.publicDescription }}</span>
 			</div>
 		</button>
 		<button key="home" class="_button" :class="[$style.item, { [$style.active]: v === 'home' }]" data-index="2" @click="choose('home')">
-			<div :class="$style.icon"><i class="ti ti-home"></i></div>
+			<div :class="$style.icon"><i class="ph-house ph-bold ph-lg"></i></div>
 			<div :class="$style.body">
 				<span :class="$style.itemTitle">{{ i18n.ts._visibility.home }}</span>
 				<span :class="$style.itemDescription">{{ i18n.ts._visibility.homeDescription }}</span>
 			</div>
 		</button>
 		<button key="followers" class="_button" :class="[$style.item, { [$style.active]: v === 'followers' }]" data-index="3" @click="choose('followers')">
-			<div :class="$style.icon"><i class="ti ti-lock"></i></div>
+			<div :class="$style.icon"><i class="ph-lock ph-bold ph-lg"></i></div>
 			<div :class="$style.body">
 				<span :class="$style.itemTitle">{{ i18n.ts._visibility.followers }}</span>
 				<span :class="$style.itemDescription">{{ i18n.ts._visibility.followersDescription }}</span>
 			</div>
 		</button>
 		<button key="specified" :disabled="localOnly" class="_button" :class="[$style.item, { [$style.active]: v === 'specified' }]" data-index="4" @click="choose('specified')">
-			<div :class="$style.icon"><i class="ti ti-mail"></i></div>
+			<div :class="$style.icon"><i class="ph-envelope ph-bold ph-lg"></i></div>
 			<div :class="$style.body">
 				<span :class="$style.itemTitle">{{ i18n.ts._visibility.specified }}</span>
 				<span :class="$style.itemDescription">{{ i18n.ts._visibility.specifiedDescription }}</span>
diff --git a/packages/frontend/src/components/MkVisitorDashboard.vue b/packages/frontend/src/components/MkVisitorDashboard.vue
index 8fe3c38eba..fd491db921 100644
--- a/packages/frontend/src/components/MkVisitorDashboard.vue
+++ b/packages/frontend/src/components/MkVisitorDashboard.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div v-if="meta" :class="$style.root">
 	<div :class="[$style.main, $style.panel]">
 		<img :src="instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="$style.mainIcon"/>
-		<button class="_button _acrylic" :class="$style.mainMenu" @click="showMenu"><i class="ti ti-dots"></i></button>
+		<button class="_button _acrylic" :class="$style.mainMenu" @click="showMenu"><i class="ph-dots-three ph-bold ph-lg"></i></button>
 		<div :class="$style.mainFg">
 			<h1 :class="$style.mainTitle">
 				<!-- 背景色によってはロゴが見えなくなるのでとりあえず無効に -->
@@ -94,19 +94,19 @@ function signup() {
 function showMenu(ev) {
 	os.popupMenu([{
 		text: i18n.ts.instanceInfo,
-		icon: 'ti ti-info-circle',
+		icon: 'ph-info ph-bold ph-lg',
 		action: () => {
 			os.pageWindow('/about');
 		},
 	}, {
 		text: i18n.ts.aboutMisskey,
-		icon: 'ti ti-info-circle',
+		icon: 'ph-info ph-bold ph-lg',
 		action: () => {
 			os.pageWindow('/about-sharkey');
 		},
 	}, null, {
 		text: i18n.ts.help,
-		icon: 'ti ti-help-circle',
+		icon: 'ph-question ph-bold ph-lg',
 		action: () => {
 			window.open('https://misskey-hub.net/help.md', '_blank');
 		},
@@ -151,7 +151,7 @@ function exploreOtherServers() {
 	right: 16px;
 	width: 32px;
 	height: 32px;
-	border-radius: 8px;
+	border-radius: 5px;
 	font-size: 18px;
 }
 
diff --git a/packages/frontend/src/components/MkWaitingDialog.vue b/packages/frontend/src/components/MkWaitingDialog.vue
index 1326ca2693..28943efd1a 100644
--- a/packages/frontend/src/components/MkWaitingDialog.vue
+++ b/packages/frontend/src/components/MkWaitingDialog.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <MkModal ref="modal" :preferType="'dialog'" :zPriority="'high'" @click="success ? done() : () => {}" @closed="emit('closed')">
 	<div :class="[$style.root, { [$style.iconOnly]: (text == null) || success }]">
-		<i v-if="success" :class="[$style.icon, $style.success]" class="ti ti-check"></i>
+		<i v-if="success" :class="[$style.icon, $style.success]" class="ph-check ph-bold ph-lg"></i>
 		<MkLoading v-else :class="[$style.icon, $style.waiting]" :em="true"/>
 		<div v-if="text && !success" :class="$style.text">{{ text }}<MkEllipsis/></div>
 	</div>
diff --git a/packages/frontend/src/components/MkWidgets.vue b/packages/frontend/src/components/MkWidgets.vue
index e2d7ceab7b..48ec702823 100644
--- a/packages/frontend/src/components/MkWidgets.vue
+++ b/packages/frontend/src/components/MkWidgets.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<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 data-cy-widget-add @click="addWidget"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
+			<MkButton inline primary data-cy-widget-add @click="addWidget"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
 			<MkButton inline @click="$emit('exit')">{{ i18n.ts.close }}</MkButton>
 		</header>
 		<Sortable
@@ -25,8 +25,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 		>
 			<template #item="{element}">
 				<div :class="[$style.widget, $style.customizeContainer]" data-cy-customize-container>
-					<button :class="$style.customizeContainerConfig" class="_button" @click.prevent.stop="configWidget(element.id)"><i class="ti ti-settings"></i></button>
-					<button :class="$style.customizeContainerRemove" data-cy-customize-container-remove class="_button" @click.prevent.stop="removeWidget(element)"><i class="ti ti-x"></i></button>
+					<button :class="$style.customizeContainerConfig" class="_button" @click.prevent.stop="configWidget(element.id)"><i class="ph-gear ph-bold pg-lg"></i></button>
+					<button :class="$style.customizeContainerRemove" data-cy-customize-container-remove class="_button" @click.prevent.stop="removeWidget(element)"><i class="ph-x ph-bold ph-lg"></i></button>
 					<div class="handle">
 						<component :is="`widget-${element.name}`" :ref="el => widgetRefs[element.id] = el" class="widget" :class="$style.customizeContainerHandleWidget" :widget="element" @updateProps="updateWidget(element.id, $event)"/>
 					</div>
@@ -111,7 +111,7 @@ function onContextmenu(widget: Widget, ev: MouseEvent) {
 		type: 'label',
 		text: i18n.t(`_widgets.${widget.name}`),
 	}, {
-		icon: 'ti ti-settings',
+		icon: 'ph-gear ph-bold pg-lg',
 		text: i18n.ts.settings,
 		action: () => {
 			configWidget(widget.id);
diff --git a/packages/frontend/src/components/MkWindow.vue b/packages/frontend/src/components/MkWindow.vue
index ccb8b09b6c..d6c3e3f81d 100644
--- a/packages/frontend/src/components/MkWindow.vue
+++ b/packages/frontend/src/components/MkWindow.vue
@@ -27,11 +27,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<template v-if="!minimized">
 						<button v-for="button in buttonsRight" v-tooltip="button.title" class="_button" :class="[$style.headerButton, { [$style.highlighted]: button.highlighted }]" @click="button.onClick"><i :class="button.icon"></i></button>
 					</template>
-					<button v-if="canResize && minimized" v-tooltip="i18n.ts.windowRestore" class="_button" :class="$style.headerButton" @click="unMinimize()"><i class="ti ti-maximize"></i></button>
-					<button v-else-if="canResize && !maximized" v-tooltip="i18n.ts.windowMinimize" class="_button" :class="$style.headerButton" @click="minimize()"><i class="ti ti-minimize"></i></button>
-					<button v-if="canResize && maximized" v-tooltip="i18n.ts.windowRestore" class="_button" :class="$style.headerButton" @click="unMaximize()"><i class="ti ti-picture-in-picture"></i></button>
-					<button v-else-if="canResize && !maximized && !minimized" v-tooltip="i18n.ts.windowMaximize" class="_button" :class="$style.headerButton" @click="maximize()"><i class="ti ti-rectangle"></i></button>
-					<button v-if="closeButton" v-tooltip="i18n.ts.close" class="_button" :class="$style.headerButton" @click="close()"><i class="ti ti-x"></i></button>
+					<button v-if="canResize && minimized" v-tooltip="i18n.ts.windowRestore" class="_button" :class="$style.headerButton" @click="unMinimize()"><i class="ph-frame-corners ph-bold ph-lg"></i></button>
+					<button v-else-if="canResize && !maximized" v-tooltip="i18n.ts.windowMinimize" class="_button" :class="$style.headerButton" @click="minimize()"><i class="ph-arrows-in-simple ph-bold ph-lg"></i></button>
+					<button v-if="canResize && maximized" v-tooltip="i18n.ts.windowRestore" class="_button" :class="$style.headerButton" @click="unMaximize()"><i class="ph-picture-in-picture ph-bold ph-lg"></i></button>
+					<button v-else-if="canResize && !maximized && !minimized" v-tooltip="i18n.ts.windowMaximize" class="_button" :class="$style.headerButton" @click="maximize()"><i class="ph-frame-corners ph-bold ph-lg"></i></button>
+					<button v-if="closeButton" v-tooltip="i18n.ts.close" class="_button" :class="$style.headerButton" @click="close()"><i class="ph-x ph-bold ph-lg"></i></button>
 				</span>
 			</div>
 			<div :class="$style.content">
diff --git a/packages/frontend/src/components/MkYouTubePlayer.vue b/packages/frontend/src/components/MkYouTubePlayer.vue
index d74ad0eda4..7460515c33 100644
--- a/packages/frontend/src/components/MkYouTubePlayer.vue
+++ b/packages/frontend/src/components/MkYouTubePlayer.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <MkWindow :initialWidth="640" :initialHeight="402" :canResize="true" :closeButton="true">
 	<template #header>
-		<i class="icon ti ti-brand-youtube" style="margin-right: 0.5em;"></i>
+		<i class="icon ph-youtube-logo ph-bold ph-lg" style="margin-right: 0.5em;"></i>
 		<span>{{ title ?? 'YouTube' }}</span>
 	</template>
 
diff --git a/packages/frontend/src/components/form/link.vue b/packages/frontend/src/components/form/link.vue
index 4d711814b5..365ce6de66 100644
--- a/packages/frontend/src/components/form/link.vue
+++ b/packages/frontend/src/components/form/link.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<span :class="$style.text"><slot></slot></span>
 		<span :class="$style.suffix">
 			<span :class="$style.suffixText"><slot name="suffix"></slot></span>
-			<i class="ti ti-external-link"></i>
+			<i class="ph-arrow-square-out ph-bold ph-lg"></i>
 		</span>
 	</a>
 	<MkA v-else :class="[$style.main, { [$style.active]: active }]" class="_button" :to="to" :behavior="behavior">
@@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<span :class="$style.text"><slot></slot></span>
 		<span :class="$style.suffix">
 			<span :class="$style.suffixText"><slot name="suffix"></slot></span>
-			<i class="ti ti-chevron-right"></i>
+			<i class="ph-caret-right ph-bold ph-lg"></i>
 		</span>
 	</MkA>
 </div>
@@ -52,7 +52,7 @@ const props = defineProps<{
 	box-sizing: border-box;
 	padding: 10px 14px;
 	background: var(--buttonBg);
-	border-radius: 6px;
+	border-radius: 5px;
 	font-size: 0.9em;
 
 	&:hover {
diff --git a/packages/frontend/src/components/form/suspense.vue b/packages/frontend/src/components/form/suspense.vue
index e3db639ff0..f65f8a78ff 100644
--- a/packages/frontend/src/components/form/suspense.vue
+++ b/packages/frontend/src/components/form/suspense.vue
@@ -12,8 +12,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 </div>
 <div v-else>
 	<div :class="$style.error">
-		<div><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</div>
-		<MkButton inline style="margin-top: 16px;" @click="retry"><i class="ti ti-reload"></i> {{ i18n.ts.retry }}</MkButton>
+		<div><i class="ph-warning ph-bold ph-lg"></i> {{ i18n.ts.somethingHappened }}</div>
+		<MkButton inline style="margin-top: 16px;" @click="retry"><i class="ph-arrow-clockwise ph-bold ph-lg"></i> {{ i18n.ts.retry }}</MkButton>
 	</div>
 </div>
 </template>
diff --git a/packages/frontend/src/components/global/MkA.vue b/packages/frontend/src/components/global/MkA.vue
index 2c50511b8b..60cd834094 100644
--- a/packages/frontend/src/components/global/MkA.vue
+++ b/packages/frontend/src/components/global/MkA.vue
@@ -45,25 +45,25 @@ function onContextmenu(ev) {
 		type: 'label',
 		text: props.to,
 	}, {
-		icon: 'ti ti-app-window',
+		icon: 'ph-app-window ph-bold ph-lg',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(props.to);
 		},
 	}, {
-		icon: 'ti ti-player-eject',
+		icon: 'ph-eject ph-bold pg-lg',
 		text: i18n.ts.showInPage,
 		action: () => {
 			router.push(props.to, 'forcePage');
 		},
 	}, null, {
-		icon: 'ti ti-external-link',
+		icon: 'ph-arrow-square-out ph-bold ph-lg',
 		text: i18n.ts.openInNewTab,
 		action: () => {
 			window.open(props.to, '_blank');
 		},
 	}, {
-		icon: 'ti ti-link',
+		icon: 'ph-link ph-bold ph-lg',
 		text: i18n.ts.copyLink,
 		action: () => {
 			copyToClipboard(`${url}${props.to}`);
diff --git a/packages/frontend/src/components/global/MkAd.vue b/packages/frontend/src/components/global/MkAd.vue
index 421fe99127..280c66afbb 100644
--- a/packages/frontend/src/components/global/MkAd.vue
+++ b/packages/frontend/src/components/global/MkAd.vue
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	>
 		<a :href="chosen.url" target="_blank" :class="$style.link">
 			<img :src="chosen.imageUrl" :class="$style.img">
-			<button class="_button" :class="$style.i" @click.prevent.stop="toggleMenu"><i :class="$style.iIcon" class="ti ti-info-circle"></i></button>
+			<button class="_button" :class="$style.i" @click.prevent.stop="toggleMenu"><i :class="$style.iIcon" class="ph-info ph-bold ph-lg"></i></button>
 		</a>
 	</div>
 	<div v-else :class="$style.menu">
diff --git a/packages/frontend/src/components/global/MkAvatar.vue b/packages/frontend/src/components/global/MkAvatar.vue
index 27c25b9490..3b07ac110a 100644
--- a/packages/frontend/src/components/global/MkAvatar.vue
+++ b/packages/frontend/src/components/global/MkAvatar.vue
@@ -142,10 +142,10 @@ watch(() => props.user.avatarBlurhash, () => {
 }
 
 .square {
-	border-radius: 20%;
+	border-radius: 5px;
 
 	> .inner {
-		border-radius: 20%;
+		border-radius: 5px;
 	}
 }
 
diff --git a/packages/frontend/src/components/global/MkError.vue b/packages/frontend/src/components/global/MkError.vue
index 7181ae61a1..efb7b75fb9 100644
--- a/packages/frontend/src/components/global/MkError.vue
+++ b/packages/frontend/src/components/global/MkError.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" appear>
 	<div :class="$style.root">
 		<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
-		<p :class="$style.text"><i class="ti ti-alert-triangle"></i> {{ i18n.ts.somethingHappened }}</p>
+		<p :class="$style.text"><i class="ph-warning ph-bold ph-lg"></i> {{ i18n.ts.somethingHappened }}</p>
 		<MkButton :class="$style.button" @click="() => emit('retry')">{{ i18n.ts.retry }}</MkButton>
 	</div>
 </Transition>
@@ -44,6 +44,6 @@ const emit = defineEmits<{
   width: 128px;
 	height: 128px;
 	margin-bottom: 16px;
-	border-radius: 16px;
+	border-radius: 4px;
 }
 </style>
diff --git a/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts b/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts
index d3fd1bdc08..171b68cf7d 100644
--- a/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts
+++ b/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts
@@ -60,7 +60,7 @@ export const Icon = {
 		tabs: [
 			{
 				...OneTab.args.tabs[0],
-				icon: 'ti ti-home',
+				icon: 'ph-house ph-bold ph-lg',
 			},
 		],
 	},
@@ -87,17 +87,17 @@ export const SomeTabs = {
 			{
 				key: 'princess',
 				title: 'Princess',
-				icon: 'ti ti-crown',
+				icon: 'ph-crown ph-bold ph-lg',
 			},
 			{
 				key: 'fairy',
 				title: 'Fairy',
-				icon: 'ti ti-snowflake',
+				icon: 'ph-snowflake ph-bold pg-lg',
 			},
 			{
 				key: 'angel',
 				title: 'Angel',
-				icon: 'ti ti-feather',
+				icon: 'ph-feather ph-bold pg-lg',
 			},
 		],
 	},
diff --git a/packages/frontend/src/components/global/MkPageHeader.tabs.vue b/packages/frontend/src/components/global/MkPageHeader.tabs.vue
index e62967963f..57e41ed06a 100644
--- a/packages/frontend/src/components/global/MkPageHeader.tabs.vue
+++ b/packages/frontend/src/components/global/MkPageHeader.tabs.vue
@@ -242,7 +242,7 @@ onUnmounted(() => {
 	bottom: 0;
 	height: 3px;
 	background: var(--accent);
-	border-radius: 999px;
+	border-radius: 4px;
 	transition: none;
 	pointer-events: none;
 
diff --git a/packages/frontend/src/components/global/MkUrl.vue b/packages/frontend/src/components/global/MkUrl.vue
index a8832cde01..8ec8eefed6 100644
--- a/packages/frontend/src/components/global/MkUrl.vue
+++ b/packages/frontend/src/components/global/MkUrl.vue
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<span v-if="pathname != ''" :class="$style.pathname">{{ self ? pathname.substring(1) : pathname }}</span>
 	<span :class="$style.query">{{ query }}</span>
 	<span :class="$style.hash">{{ hash }}</span>
-	<i v-if="target === '_blank'" :class="$style.icon" class="ti ti-external-link"></i>
+	<i v-if="target === '_blank'" :class="$style.icon" class="ph-arrow-square-out ph-bold ph-lg"></i>
 </component>
 </template>
 
diff --git a/packages/frontend/src/navbar.ts b/packages/frontend/src/navbar.ts
index a7e8f512a8..5243931554 100644
--- a/packages/frontend/src/navbar.ts
+++ b/packages/frontend/src/navbar.ts
@@ -17,100 +17,100 @@ import { instance } from './instance.js';
 export const navbarItemDef = reactive({
 	notifications: {
 		title: i18n.ts.notifications,
-		icon: 'ti ti-bell',
+		icon: 'ph-bell ph-bold ph-lg',
 		show: computed(() => $i != null),
 		indicated: computed(() => $i != null && $i.hasUnreadNotification),
 		to: '/my/notifications',
 	},
 	drive: {
 		title: i18n.ts.drive,
-		icon: 'ti ti-cloud',
+		icon: 'ph-cloud ph-bold ph-lg',
 		show: computed(() => $i != null),
 		to: '/my/drive',
 	},
 	followRequests: {
 		title: i18n.ts.followRequests,
-		icon: 'ti ti-user-plus',
+		icon: 'ph-user-plus ph-bold ph-lg',
 		show: computed(() => $i != null && $i.isLocked),
 		indicated: computed(() => $i != null && $i.hasPendingReceivedFollowRequest),
 		to: '/my/follow-requests',
 	},
 	explore: {
 		title: i18n.ts.explore,
-		icon: 'ti ti-hash',
+		icon: 'ph-hash ph-bold ph-lg',
 		to: '/explore',
 	},
 	announcements: {
 		title: i18n.ts.announcements,
-		icon: 'ti ti-speakerphone',
+		icon: 'ph-megaphone ph-bold ph-lg',
 		indicated: computed(() => $i != null && $i.hasUnreadAnnouncement),
 		to: '/announcements',
 	},
 	search: {
 		title: i18n.ts.search,
-		icon: 'ti ti-search',
+		icon: 'ph-magnifying-glass ph-bold ph-lg',
 		to: '/search',
 	},
 	lookup: {
 		title: i18n.ts.lookup,
-		icon: 'ti ti-world-search',
+		icon: 'ph-binoculars ph-bold ph-lg',
 		action: (ev) => {
 			lookup();
 		},
 	},
 	lists: {
 		title: i18n.ts.lists,
-		icon: 'ti ti-list',
+		icon: 'ph-list ph-bold ph-lg',
 		show: computed(() => $i != null),
 		to: '/my/lists',
 	},
 	antennas: {
 		title: i18n.ts.antennas,
-		icon: 'ti ti-antenna',
+		icon: 'ph-flying-saucer ph-bold ph-lg',
 		show: computed(() => $i != null),
 		to: '/my/antennas',
 	},
 	favorites: {
 		title: i18n.ts.favorites,
-		icon: 'ti ti-star',
+		icon: 'ph-bookmark ph-bold ph-lg',
 		show: computed(() => $i != null),
 		to: '/my/favorites',
 	},
 	pages: {
 		title: i18n.ts.pages,
-		icon: 'ti ti-news',
+		icon: 'ph-newspaper ph-bold ph-lg',
 		to: '/pages',
 	},
 	play: {
 		title: 'Play',
-		icon: 'ti ti-player-play',
+		icon: 'ph-play ph-bold ph-lg',
 		to: '/play',
 	},
 	gallery: {
 		title: i18n.ts.gallery,
-		icon: 'ti ti-icons',
+		icon: 'ph-images ph-bold ph-lg',
 		to: '/gallery',
 	},
 	clips: {
 		title: i18n.ts.clip,
-		icon: 'ti ti-paperclip',
+		icon: 'ph-paperclip ph-bold ph-lg',
 		show: computed(() => $i != null),
 		to: '/my/clips',
 	},
 	channels: {
 		title: i18n.ts.channel,
-		icon: 'ti ti-device-tv',
+		icon: 'ph-television ph-bold ph-lg',
 		to: '/channels',
 	},
 	achievements: {
 		title: i18n.ts.achievements,
-		icon: 'ti ti-medal',
+		icon: 'ph-trophy ph-bold ph-lg',
 		show: computed(() => $i != null && instance.enableAchievements),
 		to: '/my/achievements',
 	},
 	ui: {
 		title: i18n.ts.switchUi,
-		icon: 'ti ti-devices',
+		icon: 'ph-devices ph-bold ph-lg',
 		action: (ev) => {
 			os.popupMenu([{
 				text: i18n.ts.default,
@@ -138,21 +138,21 @@ export const navbarItemDef = reactive({
 	},
 	about: {
 		title: i18n.ts.about,
-		icon: 'ti ti-info-circle',
+		icon: 'ph-info ph-bold ph-lg',
 		action: (ev) => {
 			openInstanceMenu(ev);
 		},
 	},
 	reload: {
 		title: i18n.ts.reload,
-		icon: 'ti ti-refresh',
+		icon: 'ph-arrows-clockwise ph-bold ph-lg',
 		action: (ev) => {
 			location.reload();
 		},
 	},
 	profile: {
 		title: i18n.ts.profile,
-		icon: 'ti ti-user',
+		icon: 'ph-user ph-bold ph-lg',
 		show: computed(() => $i != null),
 		to: `/@${$i?.username}`,
 	},
diff --git a/packages/frontend/src/pages/_error_.vue b/packages/frontend/src/pages/_error_.vue
index 7a3e2f444b..037d6c94a8 100644
--- a/packages/frontend/src/pages/_error_.vue
+++ b/packages/frontend/src/pages/_error_.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div v-show="loaded" :class="$style.root">
 		<img :src="serverErrorImageUrl" class="_ghost" :class="$style.img"/>
 		<div class="_gaps">
-			<div><b><i class="ti ti-alert-triangle"></i> {{ i18n.ts.pageLoadError }}</b></div>
+			<div><b><i class="ph-warning ph-bold ph-lg"></i> {{ i18n.ts.pageLoadError }}</b></div>
 			<div v-if="meta && (version === meta.version)">{{ i18n.ts.pageLoadErrorDescription }}</div>
 			<div v-else-if="serverIsDead">{{ i18n.ts.serverIsDead }}</div>
 			<template v-else>
@@ -68,7 +68,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.error,
-	icon: 'ti ti-alert-triangle',
+	icon: 'ph-warning ph-bold ph-lg',
 });
 </script>
 
@@ -82,6 +82,6 @@ definePageMetadata({
 	vertical-align: bottom;
 	height: 128px;
 	margin-bottom: 24px;
-	border-radius: 16px;
+	border-radius: 4px;
 }
 </style>
diff --git a/packages/frontend/src/pages/about-sharkey.vue b/packages/frontend/src/pages/about-sharkey.vue
index a360bbbd08..85047584d8 100644
--- a/packages/frontend/src/pages/about-sharkey.vue
+++ b/packages/frontend/src/pages/about-sharkey.vue
@@ -30,12 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<FormSection>
 					<div class="_formLinks">
 						<FormLink to="https://github.com/transfem-org/Sharkey" external>
-							<template #icon><i class="ti ti-code"></i></template>
+							<template #icon><i class="ph-code ph-bold pg-lg"></i></template>
 							{{ i18n.ts._aboutMisskey.source }}
 							<template #suffix>GitHub</template>
 						</FormLink>
 						<FormLink to="https://ko-fi.com/transfem" external>
-							<template #icon><i class="ti ti-pig-money"></i></template>
+							<template #icon><i class="ph-piggy-bank ph-bold pg-lg"></i></template>
 							{{ i18n.ts._aboutMisskey.donate }}
 							<template #suffix>Ko-Fi</template>
 						</FormLink>
@@ -206,7 +206,7 @@ definePageMetadata({
 				display: block;
 				width: 80px;
 				margin: 0 auto;
-				border-radius: 16px;
+				border-radius: 4px;
 				position: relative;
 				z-index: 1;
 			}
@@ -256,7 +256,7 @@ definePageMetadata({
 	align-items: center;
 	padding: 12px;
 	background: var(--buttonBg);
-	border-radius: 6px;
+	border-radius: 5px;
 
 	&:hover {
 		text-decoration: none;
@@ -289,7 +289,7 @@ definePageMetadata({
 	align-items: center;
 	padding: 12px;
 	background: var(--buttonBg);
-	border-radius: 6px;
+	border-radius: 5px;
 }
 
 .patronIcon {
diff --git a/packages/frontend/src/pages/about.emojis.vue b/packages/frontend/src/pages/about.emojis.vue
index c8f56f1674..d40f7dd2c5 100644
--- a/packages/frontend/src/pages/about.emojis.vue
+++ b/packages/frontend/src/pages/about.emojis.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<div class="query">
 		<MkInput v-model="q" class="" :placeholder="i18n.ts.search">
-			<template #prefix><i class="ti ti-search"></i></template>
+			<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 		</MkInput>
 
 		<!-- たくさんあると邪魔
diff --git a/packages/frontend/src/pages/about.federation.vue b/packages/frontend/src/pages/about.federation.vue
index 2aa5af939b..d4a780f366 100644
--- a/packages/frontend/src/pages/about.federation.vue
+++ b/packages/frontend/src/pages/about.federation.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div>
 	<div>
 		<MkInput v-model="host" :debounce="true" class="">
-			<template #prefix><i class="ti ti-search"></i></template>
+			<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 			<template #label>{{ i18n.ts.host }}</template>
 		</MkInput>
 		<FormSplit style="margin-top: var(--margin);">
diff --git a/packages/frontend/src/pages/about.vue b/packages/frontend/src/pages/about.vue
index 1efaeb1d7b..23b8e20b9f 100644
--- a/packages/frontend/src/pages/about.vue
+++ b/packages/frontend/src/pages/about.vue
@@ -144,27 +144,27 @@ const headerTabs = $computed(() => [{
 }, {
 	key: 'emojis',
 	title: i18n.ts.customEmojis,
-	icon: 'ti ti-icons',
+	icon: 'ph-smiley ph-bold pg-lg',
 }, {
 	key: 'federation',
 	title: i18n.ts.federation,
-	icon: 'ti ti-whirl',
+	icon: 'ph-globe-hemisphere-west ph-bold ph-lg',
 }, {
 	key: 'charts',
 	title: i18n.ts.charts,
-	icon: 'ti ti-chart-line',
+	icon: 'ph-chart-line ph-bold pg-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.instanceInfo,
-	icon: 'ti ti-info-circle',
+	icon: 'ph-info ph-bold ph-lg',
 })));
 </script>
 
 <style lang="scss" module>
 .banner {
 	text-align: center;
-	border-radius: 10px;
+	border-radius: 5px;
 	overflow: clip;
 	background-size: cover;
 	background-position: center center;
@@ -174,7 +174,7 @@ definePageMetadata(computed(() => ({
 	display: block;
 	margin: 16px auto 0 auto;
 	height: 64px;
-	border-radius: 8px;
+	border-radius: 5px;
 }
 
 .bannerName {
@@ -213,7 +213,7 @@ definePageMetadata(computed(() => ({
 		font-weight: bold;
 		align-items: center;
 		justify-content: center;
-		border-radius: 999px;
+		border-radius: 4px;
 	}
 }
 
diff --git a/packages/frontend/src/pages/achievements.vue b/packages/frontend/src/pages/achievements.vue
index 188ec5caa8..f735da7e67 100644
--- a/packages/frontend/src/pages/achievements.vue
+++ b/packages/frontend/src/pages/achievements.vue
@@ -50,7 +50,7 @@ onDeactivated(() => {
 
 definePageMetadata({
 	title: i18n.ts.achievements,
-	icon: 'ti ti-medal',
+	icon: 'ph-trophy ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin-file.vue b/packages/frontend/src/pages/admin-file.vue
index 4ce0f2936c..1451d13045 100644
--- a/packages/frontend/src/pages/admin-file.vue
+++ b/packages/frontend/src/pages/admin-file.vue
@@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 
 			<div>
-				<MkButton danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+				<MkButton danger @click="del"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 			</div>
 		</div>
 		<div v-else-if="tab === 'ip' && info" class="_gaps_m">
@@ -118,7 +118,7 @@ async function toggleIsSensitive(v) {
 
 const headerActions = $computed(() => [{
 	text: i18n.ts.openInNewTab,
-	icon: 'ti ti-external-link',
+	icon: 'ph-arrow-square-out ph-bold ph-lg',
 	handler: () => {
 		window.open(file.url, '_blank');
 	},
@@ -127,20 +127,20 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'overview',
 	title: i18n.ts.overview,
-	icon: 'ti ti-info-circle',
+	icon: 'ph-info ph-bold ph-lg',
 }, iAmModerator ? {
 	key: 'ip',
 	title: 'IP',
-	icon: 'ti ti-password',
+	icon: 'ph-password ph-bold ph-lg',
 } : null, {
 	key: 'raw',
 	title: 'Raw data',
-	icon: 'ti ti-code',
+	icon: 'ph-code ph-bold pg-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: file ? i18n.ts.file + ': ' + file.name : i18n.ts.file,
-	icon: 'ti ti-file',
+	icon: 'ph-file ph-bold ph-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/admin-user.vue b/packages/frontend/src/pages/admin-user.vue
index 5d671acf31..281a496904 100644
--- a/packages/frontend/src/pages/admin-user.vue
+++ b/packages/frontend/src/pages/admin-user.vue
@@ -63,7 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<div style="display: flex; flex-direction: column; gap: 1em;">
 							<MkKeyValue v-if="user.host" oneline>
 								<template #key>{{ i18n.ts.instanceInfo }}</template>
-								<template #value><MkA :to="`/instance-info/${user.host}`" class="_link">{{ user.host }} <i class="ti ti-chevron-right"></i></MkA></template>
+								<template #value><MkA :to="`/instance-info/${user.host}`" class="_link">{{ user.host }} <i class="ph-caret-right ph-bold ph-lg"></i></MkA></template>
 							</MkKeyValue>
 							<MkKeyValue v-else oneline>
 								<template #key>{{ i18n.ts.instanceInfo }}</template>
@@ -79,7 +79,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 							</MkKeyValue>
 						</div>
 
-						<MkButton v-if="user.host != null" @click="updateRemoteUser"><i class="ti ti-refresh"></i> {{ i18n.ts.updateRemoteUser }}</MkButton>
+						<MkButton v-if="user.host != null" @click="updateRemoteUser"><i class="ph-arrows-counter-clockwise ph-bold pg-lg"></i> {{ i18n.ts.updateRemoteUser }}</MkButton>
 
 						<MkFolder>
 							<template #label>Raw</template>
@@ -96,11 +96,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<MkSwitch v-model="suspended" @update:modelValue="toggleSuspend">{{ i18n.ts.suspend }}</MkSwitch>
 
 						<div>
-							<MkButton v-if="user.host == null" inline style="margin-right: 8px;" @click="resetPassword"><i class="ti ti-key"></i> {{ i18n.ts.resetPassword }}</MkButton>
+							<MkButton v-if="user.host == null" inline style="margin-right: 8px;" @click="resetPassword"><i class="ph-key ph-bold ph-lg"></i> {{ i18n.ts.resetPassword }}</MkButton>
 						</div>
 
 						<MkFolder>
-							<template #icon><i class="ti ti-license"></i></template>
+							<template #icon><i class="ph-scroll ph-bold ph-lg"></i></template>
 							<template #label>{{ i18n.ts._role.policies }}</template>
 							<div class="_gaps">
 								<div v-for="policy in Object.keys(info.policies)" :key="policy">
@@ -110,7 +110,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						</MkFolder>
 
 						<MkFolder>
-							<template #icon><i class="ti ti-password"></i></template>
+							<template #icon><i class="ph-password ph-bold ph-lg"></i></template>
 							<template #label>IP</template>
 							<MkInfo v-if="!iAmAdmin" warn>{{ i18n.ts.requireAdminForView }}</MkInfo>
 							<MkInfo v-else>The date is the IP address was first acknowledged.</MkInfo>
@@ -128,14 +128,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 
 			<div v-else-if="tab === 'roles'" class="_gaps">
-				<MkButton v-if="user.host == null" primary rounded @click="assignRole"><i class="ti ti-plus"></i> {{ i18n.ts.assign }}</MkButton>
+				<MkButton v-if="user.host == null" primary rounded @click="assignRole"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.assign }}</MkButton>
 
 				<div v-for="role in info.roles" :key="role.id" :class="$style.roleItem">
 					<div :class="$style.roleItemMain">
 						<MkRolePreview :class="$style.role" :role="role" :forModeration="true"/>
-						<button class="_button" :class="$style.roleToggle" @click="toggleRoleItem(role)"><i class="ti ti-chevron-down"></i></button>
-						<button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="unassignRole(role, $event)"><i class="ti ti-x"></i></button>
-						<button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ti ti-ban"></i></button>
+						<button class="_button" :class="$style.roleToggle" @click="toggleRoleItem(role)"><i class="ph-caret-down ph-bold ph-lg"></i></button>
+						<button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="unassignRole(role, $event)"><i class="ph-x ph-bold ph-lg"></i></button>
+						<button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ph-prohibit ph-bold ph-lg"></i></button>
 					</div>
 					<div v-if="expandedRoles.includes(role.id)" :class="$style.roleItemSub">
 						<div>Assigned: <MkTime :time="info.roleAssigns.find(a => a.roleId === role.id).createdAt" mode="detail"/></div>
@@ -146,17 +146,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 
 			<div v-else-if="tab === 'announcements'" class="_gaps">
-				<MkButton primary rounded @click="createAnnouncement"><i class="ti ti-plus"></i> {{ i18n.ts.new }}</MkButton>
+				<MkButton primary rounded @click="createAnnouncement"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.new }}</MkButton>
 
 				<MkPagination :pagination="announcementsPagination">
 					<template #default="{ items }">
 						<div class="_gaps_s">
 							<div v-for="announcement in items" :key="announcement.id" v-panel :class="$style.announcementItem" @click="editAnnouncement(announcement)">
 								<span style="margin-right: 0.5em;">
-									<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
-									<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
-									<i v-else-if="announcement.icon === 'error'" class="ti ti-circle-x" style="color: var(--error);"></i>
-									<i v-else-if="announcement.icon === 'success'" class="ti ti-check" style="color: var(--success);"></i>
+									<i v-if="announcement.icon === 'info'" class="ph-info ph-bold ph-lg"></i>
+									<i v-else-if="announcement.icon === 'warning'" class="ph-warning ph-bold ph-lg" style="color: var(--warn);"></i>
+									<i v-else-if="announcement.icon === 'error'" class="ph-x-circle ph-bold ph-lg" style="color: var(--error);"></i>
+									<i v-else-if="announcement.icon === 'success'" class="ph-check ph-bold ph-lg" style="color: var(--success);"></i>
 								</span>
 								<span>{{ announcement.title }}</span>
 								<span v-if="announcement.reads > 0" style="margin-left: auto; opacity: 0.7;">{{ i18n.ts.messageRead }}</span>
@@ -403,7 +403,7 @@ async function assignRole() {
 async function unassignRole(role, ev) {
 	os.popupMenu([{
 		text: i18n.ts.unassign,
-		icon: 'ti ti-x',
+		icon: 'ph-x ph-bold ph-lg',
 		danger: true,
 		action: async () => {
 			await os.apiWithDialog('admin/roles/unassign', { roleId: role.id, userId: user.id });
@@ -452,32 +452,32 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'overview',
 	title: i18n.ts.overview,
-	icon: 'ti ti-info-circle',
+	icon: 'ph-info ph-bold ph-lg',
 }, {
 	key: 'roles',
 	title: i18n.ts.roles,
-	icon: 'ti ti-badges',
+	icon: 'ph-seal-check ph-bold pg-lg',
 }, {
 	key: 'announcements',
 	title: i18n.ts.announcements,
-	icon: 'ti ti-speakerphone',
+	icon: 'ph-megaphone ph-bold ph-lg',
 }, {
 	key: 'drive',
 	title: i18n.ts.drive,
-	icon: 'ti ti-cloud',
+	icon: 'ph-cloud ph-bold ph-lg',
 }, {
 	key: 'chart',
 	title: i18n.ts.charts,
-	icon: 'ti ti-chart-line',
+	icon: 'ph-chart-line ph-bold pg-lg',
 }, {
 	key: 'raw',
 	title: 'Raw',
-	icon: 'ti ti-code',
+	icon: 'ph-code ph-bold pg-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: user ? acct(user) : i18n.ts.userInfo,
-	icon: 'ti ti-user-exclamation',
+	icon: 'ph-warning-circle ph-bold ph-lg',
 })));
 </script>
 
@@ -528,7 +528,7 @@ definePageMetadata(computed(() => ({
 			> .suspended, > .silenced, > .moderator {
 				display: inline-block;
 				border: solid 1px;
-				border-radius: 6px;
+				border-radius: 5px;
 				padding: 2px 6px;
 				font-size: 85%;
 			}
@@ -608,7 +608,7 @@ definePageMetadata(computed(() => ({
 .announcementItem {
 	display: flex;
 	padding: 8px 12px;
-	border-radius: 6px;
+	border-radius: 5px;
 	cursor: pointer;
 }
 </style>
diff --git a/packages/frontend/src/pages/admin/RolesEditorFormula.vue b/packages/frontend/src/pages/admin/RolesEditorFormula.vue
index 0112c9eb7f..92010f771c 100644
--- a/packages/frontend/src/pages/admin/RolesEditorFormula.vue
+++ b/packages/frontend/src/pages/admin/RolesEditorFormula.vue
@@ -22,10 +22,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<option value="not">{{ i18n.ts._role._condition.not }}</option>
 		</MkSelect>
 		<button v-if="draggable" class="drag-handle _button" :class="$style.dragHandle">
-			<i class="ti ti-menu-2"></i>
+			<i class="ph-list ph-bold ph-lg-2"></i>
 		</button>
 		<button v-if="draggable" class="_button" :class="$style.remove" @click="removeSelf">
-			<i class="ti ti-x"></i>
+			<i class="ph-x ph-bold ph-lg"></i>
 		</button>
 	</div>
 
@@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</template>
 		</Sortable>
-		<MkButton rounded style="margin: 0 auto;" @click="addValue"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
+		<MkButton rounded style="margin: 0 auto;" @click="addValue"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
 	</div>
 
 	<div v-else-if="type === 'not'" :class="$style.item">
diff --git a/packages/frontend/src/pages/admin/_header_.vue b/packages/frontend/src/pages/admin/_header_.vue
index 503fb2af9c..6b619249da 100644
--- a/packages/frontend/src/pages/admin/_header_.vue
+++ b/packages/frontend/src/pages/admin/_header_.vue
@@ -286,7 +286,7 @@ onUnmounted(() => {
 			bottom: 0;
 			height: 3px;
 			background: var(--accent);
-			border-radius: 999px;
+			border-radius: 4px;
 			transition: all 0.2s ease;
 			pointer-events: none;
 		}
diff --git a/packages/frontend/src/pages/admin/abuses.vue b/packages/frontend/src/pages/admin/abuses.vue
index 875702ee7e..d670cc7913 100644
--- a/packages/frontend/src/pages/admin/abuses.vue
+++ b/packages/frontend/src/pages/admin/abuses.vue
@@ -89,6 +89,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.abuseReports,
-	icon: 'ti ti-exclamation-circle',
+	icon: 'ph-warning-circle ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/ads.vue b/packages/frontend/src/pages/admin/ads.vue
index cd9d86ca45..257dca945a 100644
--- a/packages/frontend/src/pages/admin/ads.vue
+++ b/packages/frontend/src/pages/admin/ads.vue
@@ -55,12 +55,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<template #label>{{ i18n.ts.memo }}</template>
 				</MkTextarea>
 				<div class="buttons">
-					<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>
+					<MkButton class="button" inline primary style="margin-right: 12px;" @click="save(ad)"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton class="button" inline danger @click="remove(ad)"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.remove }}</MkButton>
 				</div>
 			</div>
 			<MkButton class="button" @click="more()">
-				<i class="ti ti-reload"></i>{{ i18n.ts.more }}
+				<i class="ph-arrow-clockwise ph-bold ph-lg"></i>{{ i18n.ts.more }}
 			</MkButton>
 		</div>
 	</MkSpacer>
@@ -207,7 +207,7 @@ refresh();
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.add,
 	handler: add,
 }]);
@@ -216,7 +216,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.ads,
-	icon: 'ti ti-ad',
+	icon: 'ph-flag ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/announcements.vue b/packages/frontend/src/pages/admin/announcements.vue
index f12c068a10..816922b3a9 100644
--- a/packages/frontend/src/pages/admin/announcements.vue
+++ b/packages/frontend/src/pages/admin/announcements.vue
@@ -13,10 +13,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkFolder v-for="announcement in announcements" :key="announcement.id ?? announcement._id" :defaultOpen="announcement.id == null">
 				<template #label>{{ announcement.title }}</template>
 				<template #icon>
-					<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
-					<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
-					<i v-else-if="announcement.icon === 'error'" class="ti ti-circle-x" style="color: var(--error);"></i>
-					<i v-else-if="announcement.icon === 'success'" class="ti ti-check" style="color: var(--success);"></i>
+					<i v-if="announcement.icon === 'info'" class="ph-info ph-bold ph-lg"></i>
+					<i v-else-if="announcement.icon === 'warning'" class="ph-warning ph-bold ph-lg" style="color: var(--warn);"></i>
+					<i v-else-if="announcement.icon === 'error'" class="ph-x-circle ph-bold ph-lg" style="color: var(--error);"></i>
+					<i v-else-if="announcement.icon === 'success'" class="ph-check ph-bold ph-lg" style="color: var(--success);"></i>
 				</template>
 				<template #caption>{{ announcement.text }}</template>
 
@@ -32,10 +32,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</MkInput>
 					<MkRadios v-model="announcement.icon">
 						<template #label>{{ i18n.ts.icon }}</template>
-						<option value="info"><i class="ti ti-info-circle"></i></option>
-						<option value="warning"><i class="ti ti-alert-triangle" style="color: var(--warn);"></i></option>
-						<option value="error"><i class="ti ti-circle-x" style="color: var(--error);"></i></option>
-						<option value="success"><i class="ti ti-check" style="color: var(--success);"></i></option>
+						<option value="info"><i class="ph-info ph-bold ph-lg"></i></option>
+						<option value="warning"><i class="ph-warning ph-bold ph-lg" style="color: var(--warn);"></i></option>
+						<option value="error"><i class="ph-x-circle ph-bold ph-lg" style="color: var(--error);"></i></option>
+						<option value="success"><i class="ph-check ph-bold ph-lg" style="color: var(--success);"></i></option>
 					</MkRadios>
 					<MkRadios v-model="announcement.display">
 						<template #label>{{ i18n.ts.display }}</template>
@@ -51,14 +51,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</MkSwitch>
 					<p v-if="announcement.reads">{{ i18n.t('nUsersRead', { n: announcement.reads }) }}</p>
 					<div class="buttons _buttons">
-						<MkButton class="button" inline primary @click="save(announcement)"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
-						<MkButton v-if="announcement.id != null" class="button" inline @click="archive(announcement)"><i class="ti ti-check"></i> {{ i18n.ts._announcement.end }} ({{ i18n.ts.archive }})</MkButton>
-						<MkButton v-if="announcement.id != null" class="button" inline danger @click="del(announcement)"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+						<MkButton class="button" inline primary @click="save(announcement)"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
+						<MkButton v-if="announcement.id != null" class="button" inline @click="archive(announcement)"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts._announcement.end }} ({{ i18n.ts.archive }})</MkButton>
+						<MkButton v-if="announcement.id != null" class="button" inline danger @click="del(announcement)"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 					</div>
 				</div>
 			</MkFolder>
 			<MkButton class="button" @click="more()">
-				<i class="ti ti-reload"></i>{{ i18n.ts.more }}
+				<i class="ph-arrow-clockwise ph-bold ph-lg"></i>{{ i18n.ts.more }}
 			</MkButton>
 		</div>
 	</MkSpacer>
@@ -143,7 +143,7 @@ refresh();
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.add,
 	handler: add,
 }]);
@@ -152,6 +152,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.announcements,
-	icon: 'ti ti-speakerphone',
+	icon: 'ph-megaphone ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/bot-protection.vue b/packages/frontend/src/pages/admin/bot-protection.vue
index 7f5709feb9..bda19eab50 100644
--- a/packages/frontend/src/pages/admin/bot-protection.vue
+++ b/packages/frontend/src/pages/admin/bot-protection.vue
@@ -16,11 +16,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 			<template v-if="provider === 'hcaptcha'">
 				<MkInput v-model="hcaptchaSiteKey">
-					<template #prefix><i class="ti ti-key"></i></template>
+					<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.hcaptchaSiteKey }}</template>
 				</MkInput>
 				<MkInput v-model="hcaptchaSecretKey">
-					<template #prefix><i class="ti ti-key"></i></template>
+					<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.hcaptchaSecretKey }}</template>
 				</MkInput>
 				<FormSlot>
@@ -30,11 +30,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</template>
 			<template v-else-if="provider === 'recaptcha'">
 				<MkInput v-model="recaptchaSiteKey">
-					<template #prefix><i class="ti ti-key"></i></template>
+					<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.recaptchaSiteKey }}</template>
 				</MkInput>
 				<MkInput v-model="recaptchaSecretKey">
-					<template #prefix><i class="ti ti-key"></i></template>
+					<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.recaptchaSecretKey }}</template>
 				</MkInput>
 				<FormSlot v-if="recaptchaSiteKey">
@@ -44,11 +44,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</template>
 			<template v-else-if="provider === 'turnstile'">
 				<MkInput v-model="turnstileSiteKey">
-					<template #prefix><i class="ti ti-key"></i></template>
+					<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.turnstileSiteKey }}</template>
 				</MkInput>
 				<MkInput v-model="turnstileSecretKey">
-					<template #prefix><i class="ti ti-key"></i></template>
+					<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.turnstileSecretKey }}</template>
 				</MkInput>
 				<FormSlot>
@@ -57,7 +57,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</FormSlot>
 			</template>
 
-			<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+			<MkButton primary @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 		</div>
 	</FormSuspense>
 </div>
diff --git a/packages/frontend/src/pages/admin/branding.vue b/packages/frontend/src/pages/admin/branding.vue
index d064dbd0a9..034681c762 100644
--- a/packages/frontend/src/pages/admin/branding.vue
+++ b/packages/frontend/src/pages/admin/branding.vue
@@ -11,12 +11,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<FormSuspense :p="init">
 				<div class="_gaps_m">
 					<MkInput v-model="iconUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts._serverSettings.iconUrl }}</template>
 					</MkInput>
 
 					<MkInput v-model="app192IconUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts._serverSettings.iconUrl }} (App/192px)</template>
 						<template #caption>
 							<div>{{ i18n.t('_serverSettings.appIconDescription', { host: instance.name ?? host }) }}</div>
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</MkInput>
 
 					<MkInput v-model="app512IconUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts._serverSettings.iconUrl }} (App/512px)</template>
 						<template #caption>
 							<div>{{ i18n.t('_serverSettings.appIconDescription', { host: instance.name ?? host }) }}</div>
@@ -38,27 +38,27 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</MkInput>
 
 					<MkInput v-model="bannerUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.bannerUrl }}</template>
 					</MkInput>
 
 					<MkInput v-model="backgroundImageUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.backgroundImageUrl }}</template>
 					</MkInput>
 
 					<MkInput v-model="notFoundImageUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.notFoundDescription }}</template>
 					</MkInput>
 
 					<MkInput v-model="infoImageUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.nothing }}</template>
 					</MkInput>
 
 					<MkInput v-model="serverErrorImageUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.somethingHappened }}</template>
 					</MkInput>
 
@@ -85,7 +85,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<template #footer>
 			<div :class="$style.footer">
 				<MkSpacer :contentMax="700" :marginMin="16" :marginMax="16">
-					<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton primary rounded @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 				</MkSpacer>
 			</div>
 		</template>
@@ -163,7 +163,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.branding,
-	icon: 'ti ti-paint',
+	icon: 'ph-paint-roller ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/database.vue b/packages/frontend/src/pages/admin/database.vue
index bba03deb4b..d3a46d2c2b 100644
--- a/packages/frontend/src/pages/admin/database.vue
+++ b/packages/frontend/src/pages/admin/database.vue
@@ -35,6 +35,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.database,
-	icon: 'ti ti-database',
+	icon: 'ph-database ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/email-settings.vue b/packages/frontend/src/pages/admin/email-settings.vue
index 32294847bb..8dcb5f4726 100644
--- a/packages/frontend/src/pages/admin/email-settings.vue
+++ b/packages/frontend/src/pages/admin/email-settings.vue
@@ -54,8 +54,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.footer">
 			<MkSpacer :contentMax="700" :marginMin="16" :marginMax="16">
 				<div class="_buttons">
-					<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
-					<MkButton rounded @click="testEmail"><i class="ti ti-send"></i> {{ i18n.ts.testEmail }}</MkButton>
+					<MkButton primary rounded @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton rounded @click="testEmail"><i class="ph-paper-plane-tilt ph-bold ph-lg"></i> {{ i18n.ts.testEmail }}</MkButton>
 				</div>
 			</MkSpacer>
 		</div>
@@ -131,7 +131,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.emailServer,
-	icon: 'ti ti-mail',
+	icon: 'ph-envelope ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/federation.vue b/packages/frontend/src/pages/admin/federation.vue
index 7dc0b46946..dc13b63d2b 100644
--- a/packages/frontend/src/pages/admin/federation.vue
+++ b/packages/frontend/src/pages/admin/federation.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div class="_gaps">
 				<div>
 					<MkInput v-model="host" :debounce="true" class="">
-						<template #prefix><i class="ti ti-search"></i></template>
+						<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.host }}</template>
 					</MkInput>
 					<FormSplit style="margin-top: var(--margin);">
@@ -101,7 +101,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.federation,
-	icon: 'ti ti-whirl',
+	icon: 'ph-globe-hemisphere-west ph-bold ph-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/admin/files.vue b/packages/frontend/src/pages/admin/files.vue
index 6fb6ef40f9..8935cd96b8 100644
--- a/packages/frontend/src/pages/admin/files.vue
+++ b/packages/frontend/src/pages/admin/files.vue
@@ -97,11 +97,11 @@ async function find() {
 
 const headerActions = $computed(() => [{
 	text: i18n.ts.lookup,
-	icon: 'ti ti-search',
+	icon: 'ph-magnifying-glass ph-bold ph-lg',
 	handler: find,
 }, {
 	text: i18n.ts.clearCachedFiles,
-	icon: 'ti ti-trash',
+	icon: 'ph-trash ph-bold ph-lg',
 	handler: clear,
 }]);
 
@@ -109,6 +109,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.files,
-	icon: 'ti ti-cloud',
+	icon: 'ph-cloud ph-bold ph-lg',
 })));
 </script>
diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue
index 944ba7b950..ab4394eac2 100644
--- a/packages/frontend/src/pages/admin/index.vue
+++ b/packages/frontend/src/pages/admin/index.vue
@@ -44,7 +44,7 @@ const router = useRouter();
 
 const indexInfo = {
 	title: i18n.ts.controlPanel,
-	icon: 'ti ti-settings',
+	icon: 'ph-gear ph-bold pg-lg',
 	hideHeader: true,
 };
 
@@ -79,74 +79,74 @@ const menuDef = $computed(() => [{
 	title: i18n.ts.quickAction,
 	items: [{
 		type: 'button',
-		icon: 'ti ti-search',
+		icon: 'ph-magnifying-glass ph-bold ph-lg',
 		text: i18n.ts.lookup,
 		action: lookup,
 	}, ...(instance.disableRegistration ? [{
 		type: 'button',
-		icon: 'ti ti-user-plus',
+		icon: 'ph-user-plus ph-bold ph-lg',
 		text: i18n.ts.createInviteCode,
 		action: invite,
 	}] : [])],
 }, {
 	title: i18n.ts.administration,
 	items: [{
-		icon: 'ti ti-dashboard',
+		icon: 'ph-gauge ph-bold pg-lg',
 		text: i18n.ts.dashboard,
 		to: '/admin/overview',
 		active: currentPage?.route.name === 'overview',
 	}, {
-		icon: 'ti ti-users',
+		icon: 'ph-users ph-bold pg-lg',
 		text: i18n.ts.users,
 		to: '/admin/users',
 		active: currentPage?.route.name === 'users',
 	}, {
-		icon: 'ti ti-user-plus',
+		icon: 'ph-user-plus ph-bold ph-lg',
 		text: i18n.ts.invite,
 		to: '/admin/invites',
 		active: currentPage?.route.name === 'invites',
 	}, {
-		icon: 'ti ti-badges',
+		icon: 'ph-seal-check ph-bold pg-lg',
 		text: i18n.ts.roles,
 		to: '/admin/roles',
 		active: currentPage?.route.name === 'roles',
 	}, {
-		icon: 'ti ti-icons',
+		icon: 'ph-smiley ph-bold pg-lg',
 		text: i18n.ts.customEmojis,
 		to: '/admin/emojis',
 		active: currentPage?.route.name === 'emojis',
 	}, {
-		icon: 'ti ti-whirl',
+		icon: 'ph-globe-hemisphere-west ph-bold ph-lg',
 		text: i18n.ts.federation,
 		to: '/admin/federation',
 		active: currentPage?.route.name === 'federation',
 	}, {
-		icon: 'ti ti-clock-play',
+		icon: 'ph-clock ph-bold ph-lg-play',
 		text: i18n.ts.jobQueue,
 		to: '/admin/queue',
 		active: currentPage?.route.name === 'queue',
 	}, {
-		icon: 'ti ti-cloud',
+		icon: 'ph-cloud ph-bold ph-lg',
 		text: i18n.ts.files,
 		to: '/admin/files',
 		active: currentPage?.route.name === 'files',
 	}, {
-		icon: 'ti ti-speakerphone',
+		icon: 'ph-megaphone ph-bold ph-lg',
 		text: i18n.ts.announcements,
 		to: '/admin/announcements',
 		active: currentPage?.route.name === 'announcements',
 	}, {
-		icon: 'ti ti-ad',
+		icon: 'ph-flag ph-bold ph-lg',
 		text: i18n.ts.ads,
 		to: '/admin/ads',
 		active: currentPage?.route.name === 'ads',
 	}, {
-		icon: 'ti ti-exclamation-circle',
+		icon: 'ph-warning-circle ph-bold ph-lg',
 		text: i18n.ts.abuseReports,
 		to: '/admin/abuses',
 		active: currentPage?.route.name === 'abuses',
 	}, {
-		icon: 'ti ti-list-search',
+		icon: 'ph-list ph-bold pg-lg-search',
 		text: i18n.ts.moderationLogs,
 		to: '/admin/modlog',
 		active: currentPage?.route.name === 'modlog',
@@ -154,52 +154,52 @@ const menuDef = $computed(() => [{
 }, {
 	title: i18n.ts.settings,
 	items: [{
-		icon: 'ti ti-settings',
+		icon: 'ph-gear ph-bold pg-lg',
 		text: i18n.ts.general,
 		to: '/admin/settings',
 		active: currentPage?.route.name === 'settings',
 	}, {
-		icon: 'ti ti-paint',
+		icon: 'ph-paint-roller ph-bold ph-lg',
 		text: i18n.ts.branding,
 		to: '/admin/branding',
 		active: currentPage?.route.name === 'branding',
 	}, {
-		icon: 'ti ti-shield',
+		icon: 'ph-shield ph-bold ph-lg',
 		text: i18n.ts.moderation,
 		to: '/admin/moderation',
 		active: currentPage?.route.name === 'moderation',
 	}, {
-		icon: 'ti ti-mail',
+		icon: 'ph-envelope ph-bold ph-lg',
 		text: i18n.ts.emailServer,
 		to: '/admin/email-settings',
 		active: currentPage?.route.name === 'email-settings',
 	}, {
-		icon: 'ti ti-cloud',
+		icon: 'ph-cloud ph-bold ph-lg',
 		text: i18n.ts.objectStorage,
 		to: '/admin/object-storage',
 		active: currentPage?.route.name === 'object-storage',
 	}, {
-		icon: 'ti ti-lock',
+		icon: 'ph-lock ph-bold ph-lg',
 		text: i18n.ts.security,
 		to: '/admin/security',
 		active: currentPage?.route.name === 'security',
 	}, {
-		icon: 'ti ti-planet',
+		icon: 'ph-planet ph-bold pg-lg',
 		text: i18n.ts.relays,
 		to: '/admin/relays',
 		active: currentPage?.route.name === 'relays',
 	}, {
-		icon: 'ti ti-ban',
+		icon: 'ph-prohibit ph-bold ph-lg',
 		text: i18n.ts.instanceBlocking,
 		to: '/admin/instance-block',
 		active: currentPage?.route.name === 'instance-block',
 	}, {
-		icon: 'ti ti-ghost',
+		icon: 'ph-ghost ph-bold ph-lg',
 		text: i18n.ts.proxyAccount,
 		to: '/admin/proxy-account',
 		active: currentPage?.route.name === 'proxy-account',
 	}, {
-		icon: 'ti ti-adjustments',
+		icon: 'ph-faders ph-bold ph-lg',
 		text: i18n.ts.other,
 		to: '/admin/other-settings',
 		active: currentPage?.route.name === 'other-settings',
@@ -207,7 +207,7 @@ const menuDef = $computed(() => [{
 }, {
 	title: i18n.ts.info,
 	items: [{
-		icon: 'ti ti-database',
+		icon: 'ph-database ph-bold pg-lg',
 		text: i18n.ts.database,
 		to: '/admin/database',
 		active: currentPage?.route.name === 'database',
@@ -271,25 +271,25 @@ const invite = () => {
 const lookup = (ev) => {
 	os.popupMenu([{
 		text: i18n.ts.user,
-		icon: 'ti ti-user',
+		icon: 'ph-user ph-bold ph-lg',
 		action: () => {
 			lookupUser();
 		},
 	}, {
 		text: i18n.ts.note,
-		icon: 'ti ti-pencil',
+		icon: 'ph-pencil ph-bold ph-lg',
 		action: () => {
 			alert('TODO');
 		},
 	}, {
 		text: i18n.ts.file,
-		icon: 'ti ti-cloud',
+		icon: 'ph-cloud ph-bold ph-lg',
 		action: () => {
 			alert('TODO');
 		},
 	}, {
 		text: i18n.ts.instance,
-		icon: 'ti ti-planet',
+		icon: 'ph-planet ph-bold pg-lg',
 		action: () => {
 			alert('TODO');
 		},
@@ -344,7 +344,7 @@ defineExpose({
 					display: block;
 					margin: auto;
 					height: 42px;
-					border-radius: 8px;
+					border-radius: 5px;
 				}
 			}
 		}
diff --git a/packages/frontend/src/pages/admin/instance-block.vue b/packages/frontend/src/pages/admin/instance-block.vue
index 9a0f5e026b..5d17ea8099 100644
--- a/packages/frontend/src/pages/admin/instance-block.vue
+++ b/packages/frontend/src/pages/admin/instance-block.vue
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<template #caption>{{ i18n.ts.blockedInstancesDescription }}</template>
 			</MkTextarea>
 
-			<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+			<MkButton primary @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 		</FormSuspense>
 	</MkSpacer>
 </MkStickyContainer>
@@ -51,6 +51,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.instanceBlocking,
-	icon: 'ti ti-ban',
+	icon: 'ph-prohibit ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/invites.vue b/packages/frontend/src/pages/admin/invites.vue
index 74dc2e4c36..406317f660 100644
--- a/packages/frontend/src/pages/admin/invites.vue
+++ b/packages/frontend/src/pages/admin/invites.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<MkSpacer :contentMax="800">
 		<div class="_gaps_m">
 			<MkFolder :expanded="false">
-				<template #icon><i class="ti ti-plus"></i></template>
+				<template #icon><i class="ph-plus ph-bold ph-lg"></i></template>
 				<template #label>{{ i18n.ts.createInviteCode }}</template>
 
 				<div class="_gaps_m">
@@ -114,7 +114,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.invite,
-	icon: 'ti ti-user-plus',
+	icon: 'ph-user-plus ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/moderation.vue b/packages/frontend/src/pages/admin/moderation.vue
index 46f92729e8..c163c2032b 100644
--- a/packages/frontend/src/pages/admin/moderation.vue
+++ b/packages/frontend/src/pages/admin/moderation.vue
@@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<FormLink to="/admin/server-rules">{{ i18n.ts.serverRules }}</FormLink>
 
 					<MkInput v-model="tosUrl">
-						<template #prefix><i class="ti ti-link"></i></template>
+						<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.tosUrl }}</template>
 					</MkInput>
 
@@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<template #footer>
 			<div :class="$style.footer">
 				<MkSpacer :contentMax="700" :marginMin="16" :marginMax="16">
-					<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton primary rounded @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 				</MkSpacer>
 			</div>
 		</template>
@@ -95,7 +95,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.moderation,
-	icon: 'ti ti-shield',
+	icon: 'ph-shield ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/modlog.ModLog.vue b/packages/frontend/src/pages/admin/modlog.ModLog.vue
index 8d83b32fa1..761a5b7020 100644
--- a/packages/frontend/src/pages/admin/modlog.ModLog.vue
+++ b/packages/frontend/src/pages/admin/modlog.ModLog.vue
@@ -111,7 +111,7 @@ const props = defineProps<{
 .diff {
 	background: #fff;
 	color: #000;
-	border-radius: 6px;
+	border-radius: 5px;
 	overflow: clip;
 }
 </style>
diff --git a/packages/frontend/src/pages/admin/modlog.vue b/packages/frontend/src/pages/admin/modlog.vue
index 4b5ef5f771..d958e16525 100644
--- a/packages/frontend/src/pages/admin/modlog.vue
+++ b/packages/frontend/src/pages/admin/modlog.vue
@@ -62,6 +62,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.moderationLogs,
-	icon: 'ti ti-list-search',
+	icon: 'ph-list ph-bold pg-lg-search',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/object-storage.vue b/packages/frontend/src/pages/admin/object-storage.vue
index dbcf135c80..71900fd307 100644
--- a/packages/frontend/src/pages/admin/object-storage.vue
+++ b/packages/frontend/src/pages/admin/object-storage.vue
@@ -40,12 +40,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 					<FormSplit :minWidth="280">
 						<MkInput v-model="objectStorageAccessKey">
-							<template #prefix><i class="ti ti-key"></i></template>
+							<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 							<template #label>Access key</template>
 						</MkInput>
 
 						<MkInput v-model="objectStorageSecretKey" type="password">
-							<template #prefix><i class="ti ti-key"></i></template>
+							<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 							<template #label>Secret key</template>
 						</MkInput>
 					</FormSplit>
@@ -75,7 +75,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template #footer>
 		<div :class="$style.footer">
 			<MkSpacer :contentMax="700" :marginMin="16" :marginMax="16">
-				<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+				<MkButton primary rounded @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 			</MkSpacer>
 		</div>
 	</template>
@@ -150,7 +150,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.objectStorage,
-	icon: 'ti ti-cloud',
+	icon: 'ph-cloud ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/other-settings.vue b/packages/frontend/src/pages/admin/other-settings.vue
index 1eadf54c70..ee24bf0fdb 100644
--- a/packages/frontend/src/pages/admin/other-settings.vue
+++ b/packages/frontend/src/pages/admin/other-settings.vue
@@ -88,7 +88,7 @@ function save() {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-check',
+	icon: 'ph-check ph-bold ph-lg',
 	text: i18n.ts.save,
 	handler: save,
 }]);
@@ -97,6 +97,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.other,
-	icon: 'ti ti-adjustments',
+	icon: 'ph-faders ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/overview.federation.vue b/packages/frontend/src/pages/admin/overview.federation.vue
index 346a9c0258..16bf6985ea 100644
--- a/packages/frontend/src/pages/admin/overview.federation.vue
+++ b/packages/frontend/src/pages/admin/overview.federation.vue
@@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 		<div v-if="!fetching" class="items">
 			<div class="item _panel sub">
-				<div class="icon"><i class="ti ti-world-download"></i></div>
+				<div class="icon"><i class="ph-globe-hemisphere-west ph-bold ph-lg-download"></i></div>
 				<div class="body">
 					<div class="value">
 						{{ number(federationSubActive) }}
@@ -31,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 			<div class="item _panel pub">
-				<div class="icon"><i class="ti ti-world-upload"></i></div>
+				<div class="icon"><i class="ph-globe-hemisphere-west ph-bold ph-lg-upload"></i></div>
 				<div class="body">
 					<div class="value">
 						{{ number(federationPubActive) }}
@@ -146,7 +146,7 @@ onMounted(async () => {
 					margin-right: 12px;
 					background: var(--accentedBg);
 					color: var(--accent);
-					border-radius: 10px;
+					border-radius: 5px;
 				}
 
 				&.sub {
diff --git a/packages/frontend/src/pages/admin/overview.stats.vue b/packages/frontend/src/pages/admin/overview.stats.vue
index 5899177efa..580bfb780b 100644
--- a/packages/frontend/src/pages/admin/overview.stats.vue
+++ b/packages/frontend/src/pages/admin/overview.stats.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<MkLoading v-if="fetching"/>
 		<div v-else :class="$style.root">
 			<div class="item _panel users">
-				<div class="icon"><i class="ti ti-users"></i></div>
+				<div class="icon"><i class="ph-users ph-bold pg-lg"></i></div>
 				<div class="body">
 					<div class="value">
 						<MkNumber :value="stats.originalUsersCount" style="margin-right: 0.5em;"/>
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 			<div class="item _panel notes">
-				<div class="icon"><i class="ti ti-pencil"></i></div>
+				<div class="icon"><i class="ph-pencil ph-bold ph-lg"></i></div>
 				<div class="body">
 					<div class="value">
 						<MkNumber :value="stats.originalNotesCount" style="margin-right: 0.5em;"/>
@@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 			<div class="item _panel instances">
-				<div class="icon"><i class="ti ti-planet"></i></div>
+				<div class="icon"><i class="ph-planet ph-bold pg-lg"></i></div>
 				<div class="body">
 					<div class="value">
 						<MkNumber :value="stats.instances" style="margin-right: 0.5em;"/>
@@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 			<div class="item _panel emojis">
-				<div class="icon"><i class="ti ti-icons"></i></div>
+				<div class="icon"><i class="ph-smiley ph-bold pg-lg"></i></div>
 				<div class="body">
 					<div class="value">
 						<MkNumber :value="customEmojis.length" style="margin-right: 0.5em;"/>
@@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 			<div class="item _panel online">
-				<div class="icon"><i class="ti ti-access-point"></i></div>
+				<div class="icon"><i class="ph-broadcast ph-bold ph-lg"></i></div>
 				<div class="body">
 					<div class="value">
 						<MkNumber :value="onlineUsersCount" style="margin-right: 0.5em;"/>
@@ -115,7 +115,7 @@ onMounted(async () => {
 				margin-right: 12px;
 				background: var(--accentedBg);
 				color: var(--accent);
-				border-radius: 10px;
+				border-radius: 5px;
 			}
 
 			&.users {
diff --git a/packages/frontend/src/pages/admin/overview.vue b/packages/frontend/src/pages/admin/overview.vue
index 170dc0d212..becbbf17d9 100644
--- a/packages/frontend/src/pages/admin/overview.vue
+++ b/packages/frontend/src/pages/admin/overview.vue
@@ -177,7 +177,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.dashboard,
-	icon: 'ti ti-dashboard',
+	icon: 'ph-gauge ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/proxy-account.vue b/packages/frontend/src/pages/admin/proxy-account.vue
index 9681215aa1..3e2a8bdf38 100644
--- a/packages/frontend/src/pages/admin/proxy-account.vue
+++ b/packages/frontend/src/pages/admin/proxy-account.vue
@@ -64,6 +64,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.proxyAccount,
-	icon: 'ti ti-ghost',
+	icon: 'ph-ghost ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/queue.chart.vue b/packages/frontend/src/pages/admin/queue.chart.vue
index d9f4af454d..4746f9de1b 100644
--- a/packages/frontend/src/pages/admin/queue.chart.vue
+++ b/packages/frontend/src/pages/admin/queue.chart.vue
@@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 	</div>
 	<MkFolder :defaultOpen="true" :max-height="250">
-		<template #icon><i class="ti ti-alert-triangle"></i></template>
+		<template #icon><i class="ph-warning ph-bold ph-lg"></i></template>
 		<template #label>Errored instances</template>
 		<template #suffix>({{ number(jobs.reduce((a, b) => a + b[1], 0)) }} jobs)</template>
 
diff --git a/packages/frontend/src/pages/admin/queue.vue b/packages/frontend/src/pages/admin/queue.vue
index ece54ab12b..62a8aa1e22 100644
--- a/packages/frontend/src/pages/admin/queue.vue
+++ b/packages/frontend/src/pages/admin/queue.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<XQueue v-if="tab === 'deliver'" domain="deliver"/>
 		<XQueue v-else-if="tab === 'inbox'" domain="inbox"/>
 		<br>
-		<MkButton @click="promoteAllQueues"><i class="ti ti-reload"></i> {{ i18n.ts.retryAllQueuesNow }}</MkButton>
+		<MkButton @click="promoteAllQueues"><i class="ph-arrow-clockwise ph-bold ph-lg"></i> {{ i18n.ts.retryAllQueuesNow }}</MkButton>
 	</MkSpacer>
 </MkStickyContainer>
 </template>
@@ -52,7 +52,7 @@ function promoteAllQueues() {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-external-link',
+	icon: 'ph-arrow-square-out ph-bold ph-lg',
 	text: i18n.ts.dashboard,
 	handler: () => {
 		window.open(config.url + '/queue', '_blank');
@@ -69,6 +69,6 @@ const headerTabs = $computed(() => [{
 
 definePageMetadata({
 	title: i18n.ts.jobQueue,
-	icon: 'ti ti-clock-play',
+	icon: 'ph-clock ph-bold ph-lg-play',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/relays.vue b/packages/frontend/src/pages/admin/relays.vue
index 8100d8188b..689b43ded1 100644
--- a/packages/frontend/src/pages/admin/relays.vue
+++ b/packages/frontend/src/pages/admin/relays.vue
@@ -11,12 +11,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div v-for="relay in relays" :key="relay.inbox" class="relaycxt _panel" style="padding: 16px;">
 				<div>{{ relay.inbox }}</div>
 				<div style="margin: 8px 0;">
-					<i v-if="relay.status === 'accepted'" class="ti ti-check" :class="$style.icon" style="color: var(--success);"></i>
-					<i v-else-if="relay.status === 'rejected'" class="ti ti-ban" :class="$style.icon" style="color: var(--error);"></i>
-					<i v-else class="ti ti-clock" :class="$style.icon"></i>
+					<i v-if="relay.status === 'accepted'" class="ph-check ph-bold ph-lg" :class="$style.icon" style="color: var(--success);"></i>
+					<i v-else-if="relay.status === 'rejected'" class="ph-prohibit ph-bold ph-lg" :class="$style.icon" style="color: var(--error);"></i>
+					<i v-else class="ph-clock ph-bold ph-lg" :class="$style.icon"></i>
 					<span>{{ i18n.t(`_relayStatus.${relay.status}`) }}</span>
 				</div>
-				<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
+				<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.remove }}</MkButton>
 			</div>
 		</div>
 	</MkSpacer>
@@ -75,7 +75,7 @@ refresh();
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.addRelay,
 	handler: addRelay,
 }]);
@@ -84,7 +84,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.relays,
-	icon: 'ti ti-planet',
+	icon: 'ph-planet ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/roles.edit.vue b/packages/frontend/src/pages/admin/roles.edit.vue
index 29726e805b..fa37d0432b 100644
--- a/packages/frontend/src/pages/admin/roles.edit.vue
+++ b/packages/frontend/src/pages/admin/roles.edit.vue
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<template #footer>
 			<div :class="$style.footer">
 				<MkSpacer :contentMax="600" :marginMin="16" :marginMax="16">
-					<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton primary rounded @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 				</MkSpacer>
 			</div>
 		</template>
@@ -87,10 +87,10 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => role ? {
 	title: i18n.ts._role.edit + ': ' + role.name,
-	icon: 'ti ti-badge',
+	icon: 'ph-seal-check ph-bold pg-lg',
 } : {
 	title: i18n.ts._role.new,
-	icon: 'ti ti-badge',
+	icon: 'ph-seal-check ph-bold pg-lg',
 }));
 </script>
 
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index 2ef3e254cd..fbd938f742 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -31,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkInput>
 
 	<MkSelect v-model="rolePermission" :readonly="readonly">
-		<template #label><i class="ti ti-shield-lock"></i> {{ i18n.ts._role.permission }}</template>
+		<template #label><i class="ph-shield ph-bold ph-lg-lock"></i> {{ i18n.ts._role.permission }}</template>
 		<template #caption><div v-html="i18n.ts._role.descriptionOfPermission.replaceAll('\n', '<br>')"></div></template>
 		<option value="normal">{{ i18n.ts.normalUser }}</option>
 		<option value="moderator">{{ i18n.ts.moderator }}</option>
@@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkSelect>
 
 	<MkSelect v-model="role.target" :readonly="readonly">
-		<template #label><i class="ti ti-users"></i> {{ i18n.ts._role.assignTarget }}</template>
+		<template #label><i class="ph-users ph-bold pg-lg"></i> {{ i18n.ts._role.assignTarget }}</template>
 		<template #caption><div v-html="i18n.ts._role.descriptionOfAssignTarget.replaceAll('\n', '<br>')"></div></template>
 		<option value="manual">{{ i18n.ts._role.manual }}</option>
 		<option value="conditional">{{ i18n.ts._role.conditional }}</option>
@@ -73,10 +73,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkSwitch>
 
 	<FormSlot>
-		<template #label><i class="ti ti-license"></i> {{ i18n.ts._role.policies }}</template>
+		<template #label><i class="ph-scroll ph-bold ph-lg"></i> {{ i18n.ts._role.policies }}</template>
 		<div class="_gaps_s">
 			<MkInput v-model="q" type="search">
-				<template #prefix><i class="ti ti-search"></i></template>
+				<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 			</MkInput>
 
 			<MkFolder v-if="matchQuery([i18n.ts._role._options.rateLimitFactor, 'rateLimitFactor'])">
@@ -546,9 +546,9 @@ let rolePermission = $computed({
 let q = $ref('');
 
 function getPriorityIcon(option) {
-	if (option.priority === 2) return 'ti ti-arrows-up';
-	if (option.priority === 1) return 'ti ti-arrow-narrow-up';
-	return 'ti ti-point';
+	if (option.priority === 2) return 'ph-arrow-up ph-bold ph-lg';
+	if (option.priority === 1) return 'ph-arrow-up ph-bold ph-lg';
+	return 'ph-circle ph-bold pg-lg';
 }
 
 function matchQuery(keywords: string[]): boolean {
diff --git a/packages/frontend/src/pages/admin/roles.role.vue b/packages/frontend/src/pages/admin/roles.role.vue
index 0b02f419bc..d83bb0615b 100644
--- a/packages/frontend/src/pages/admin/roles.role.vue
+++ b/packages/frontend/src/pages/admin/roles.role.vue
@@ -10,20 +10,20 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<MkSpacer :contentMax="700">
 			<div class="_gaps">
 				<div class="_buttons">
-					<MkButton primary rounded @click="edit"><i class="ti ti-pencil"></i> {{ i18n.ts.edit }}</MkButton>
-					<MkButton danger rounded @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+					<MkButton primary rounded @click="edit"><i class="ph-pencil ph-bold ph-lg"></i> {{ i18n.ts.edit }}</MkButton>
+					<MkButton danger rounded @click="del"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 				</div>
 				<MkFolder>
-					<template #icon><i class="ti ti-info-circle"></i></template>
+					<template #icon><i class="ph-info ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.info }}</template>
 					<XEditor :modelValue="role" readonly/>
 				</MkFolder>
 				<MkFolder v-if="role.target === 'manual'" defaultOpen>
-					<template #icon><i class="ti ti-users"></i></template>
+					<template #icon><i class="ph-users ph-bold pg-lg"></i></template>
 					<template #label>{{ i18n.ts.users }}</template>
 					<template #suffix>{{ role.usersCount }}</template>
 					<div class="_gaps">
-						<MkButton primary rounded @click="assign"><i class="ti ti-plus"></i> {{ i18n.ts.assign }}</MkButton>
+						<MkButton primary rounded @click="assign"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.assign }}</MkButton>
 
 						<MkPagination :pagination="usersPagination">
 							<template #empty>
@@ -40,8 +40,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 											<MkA :class="$style.userItemMainBody" :to="`/admin/user/${item.user.id}`">
 												<MkUserCardMini :user="item.user"/>
 											</MkA>
-											<button class="_button" :class="$style.userToggle" @click="toggleItem(item)"><i :class="$style.chevron" class="ti ti-chevron-down"></i></button>
-											<button class="_button" :class="$style.unassign" @click="unassign(item.user, $event)"><i class="ti ti-x"></i></button>
+											<button class="_button" :class="$style.userToggle" @click="toggleItem(item)"><i :class="$style.chevron" class="ph-caret-down ph-bold ph-lg"></i></button>
+											<button class="_button" :class="$style.unassign" @click="unassign(item.user, $event)"><i class="ph-x ph-bold ph-lg"></i></button>
 										</div>
 										<div v-if="expandedItems.includes(item.id)" :class="$style.userItemSub">
 											<div>Assigned: <MkTime :time="item.createdAt" mode="detail"/></div>
@@ -150,7 +150,7 @@ async function assign() {
 async function unassign(user, ev) {
 	os.popupMenu([{
 		text: i18n.ts.unassign,
-		icon: 'ti ti-x',
+		icon: 'ph-x ph-bold ph-lg',
 		danger: true,
 		action: async () => {
 			await os.apiWithDialog('admin/roles/unassign', { roleId: role.id, userId: user.id });
@@ -173,7 +173,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.role + ': ' + role.name,
-	icon: 'ti ti-badge',
+	icon: 'ph-seal-check ph-bold pg-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index 8d23335430..39e5fd5c33 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<template #label>{{ i18n.ts._role.baseRole }}</template>
 					<div class="_gaps_s">
 						<MkInput v-model="baseRoleQ" type="search">
-							<template #prefix><i class="ti ti-search"></i></template>
+							<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 						</MkInput>
 
 						<MkFolder v-if="matchQuery([i18n.ts._role._options.rateLimitFactor, 'rateLimitFactor'])">
@@ -179,7 +179,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<MkButton primary rounded @click="updateBaseRole">{{ i18n.ts.save }}</MkButton>
 					</div>
 				</MkFolder>
-				<MkButton primary rounded @click="create"><i class="ti ti-plus"></i> {{ i18n.ts._role.new }}</MkButton>
+				<MkButton primary rounded @click="create"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts._role.new }}</MkButton>
 				<div class="_gaps_s">
 					<MkFoldableSection>
 						<template #header>Manual roles</template>
@@ -248,7 +248,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.roles,
-	icon: 'ti ti-badges',
+	icon: 'ph-seal-check ph-bold pg-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/admin/security.vue b/packages/frontend/src/pages/admin/security.vue
index a2594ee6c5..c2b6dc139b 100644
--- a/packages/frontend/src/pages/admin/security.vue
+++ b/packages/frontend/src/pages/admin/security.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<FormSuspense :p="init">
 			<div class="_gaps_m">
 				<MkFolder>
-					<template #icon><i class="ti ti-shield"></i></template>
+					<template #icon><i class="ph-shield ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts.botProtection }}</template>
 					<template v-if="enableHcaptcha" #suffix>hCaptcha</template>
 					<template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template>
@@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</MkFolder>
 
 				<MkFolder>
-					<template #icon><i class="ti ti-eye-off"></i></template>
+					<template #icon><i class="ph-eye-slash ph-bold ph-lg"></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>
@@ -59,7 +59,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						</MkSwitch>
 						-->
 
-						<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+						<MkButton primary @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 					</div>
 				</MkFolder>
 
@@ -93,11 +93,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 					<div class="_gaps_m">
 						<MkInput v-model="summalyProxy">
-							<template #prefix><i class="ti ti-link"></i></template>
+							<template #prefix><i class="ph-link ph-bold ph-lg"></i></template>
 							<template #label>Summaly Proxy URL</template>
 						</MkInput>
 
-						<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+						<MkButton primary @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 					</div>
 				</MkFolder>
 			</div>
@@ -178,6 +178,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.security,
-	icon: 'ti ti-lock',
+	icon: 'ph-lock ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/admin/server-rules.vue b/packages/frontend/src/pages/admin/server-rules.vue
index 4cd1f6cbec..af1caa87c1 100644
--- a/packages/frontend/src/pages/admin/server-rules.vue
+++ b/packages/frontend/src/pages/admin/server-rules.vue
@@ -23,16 +23,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<div :class="$style.item">
 							<div :class="$style.itemHeader">
 								<div :class="$style.itemNumber" v-text="String(index + 1)"/>
-								<span :class="$style.itemHandle"><i class="ti ti-menu"/></span>
-								<button class="_button" :class="$style.itemRemove" @click="remove(index)"><i class="ti ti-x"></i></button>
+								<span :class="$style.itemHandle"><i class="ph-list ph-bold ph-lg"/></span>
+								<button class="_button" :class="$style.itemRemove" @click="remove(index)"><i class="ph-x ph-bold ph-lg"></i></button>
 							</div>
 							<MkInput v-model="serverRules[index]"/>
 						</div>
 					</template>
 				</Sortable>
 				<div :class="$style.commands">
-					<MkButton rounded @click="serverRules.push('')"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
-					<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton rounded @click="serverRules.push('')"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
+					<MkButton primary rounded @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 				</div>
 			</div>
 		</MkSpacer>
@@ -69,7 +69,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.serverRules,
-	icon: 'ti ti-checkbox',
+	icon: 'ph-check ph-bold ph-lgbox',
 });
 </script>
 
@@ -104,7 +104,7 @@ definePageMetadata({
 	height: 28px;
 	align-items: center;
 	justify-content: center;
-	border-radius: 999px;
+	border-radius: 4px;
 	margin-right: 8px;
 }
 
@@ -119,7 +119,7 @@ definePageMetadata({
 	height: 40px;
 	color: var(--error);
 	margin-left: auto;
-	border-radius: 6px;
+	border-radius: 5px;
 
 	&:hover {
 		background: var(--X5);
diff --git a/packages/frontend/src/pages/admin/settings.vue b/packages/frontend/src/pages/admin/settings.vue
index f93678d728..f355b0c857 100644
--- a/packages/frontend/src/pages/admin/settings.vue
+++ b/packages/frontend/src/pages/admin/settings.vue
@@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						</MkInput>
 
 						<MkInput v-model="maintainerEmail" type="email">
-							<template #prefix><i class="ti ti-mail"></i></template>
+							<template #prefix><i class="ph-envelope ph-bold ph-lg"></i></template>
 							<template #label>{{ i18n.ts.maintainerEmail }}</template>
 						</MkInput>
 					</FormSplit>
@@ -68,12 +68,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 							<template v-if="enableServiceWorker">
 								<MkInput v-model="swPublicKey">
-									<template #prefix><i class="ti ti-key"></i></template>
+									<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 									<template #label>Public key</template>
 								</MkInput>
 
 								<MkInput v-model="swPrivateKey">
-									<template #prefix><i class="ti ti-key"></i></template>
+									<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 									<template #label>Private key</template>
 								</MkInput>
 							</template>
@@ -85,7 +85,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 						<div class="_gaps_m">
 							<MkInput v-model="deeplAuthKey">
-								<template #prefix><i class="ti ti-key"></i></template>
+								<template #prefix><i class="ph-key ph-bold ph-lg"></i></template>
 								<template #label>DeepL Auth Key</template>
 							</MkInput>
 							<MkSwitch v-model="deeplIsPro">
@@ -99,7 +99,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<template #footer>
 			<div :class="$style.footer">
 				<MkSpacer :contentMax="700" :marginMin="16" :marginMax="16">
-					<MkButton primary rounded @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton primary rounded @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 				</MkSpacer>
 			</div>
 		</template>
@@ -177,7 +177,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.general,
-	icon: 'ti ti-settings',
+	icon: 'ph-gear ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/admin/users.vue b/packages/frontend/src/pages/admin/users.vue
index fcf41de734..c3203fef2f 100644
--- a/packages/frontend/src/pages/admin/users.vue
+++ b/packages/frontend/src/pages/admin/users.vue
@@ -120,17 +120,17 @@ function show(user) {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'ti ti-search',
+	icon: 'ph-magnifying-glass ph-bold ph-lg',
 	text: i18n.ts.search,
 	handler: searchUser,
 }, {
 	asFullButton: true,
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.addUser,
 	handler: addUser,
 }, {
 	asFullButton: true,
-	icon: 'ti ti-search',
+	icon: 'ph-magnifying-glass ph-bold ph-lg',
 	text: i18n.ts.lookup,
 	handler: lookupUser,
 }]);
@@ -139,7 +139,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.users,
-	icon: 'ti ti-users',
+	icon: 'ph-users ph-bold pg-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/ads.vue b/packages/frontend/src/pages/ads.vue
index ee58049554..bee3af39ef 100644
--- a/packages/frontend/src/pages/ads.vue
+++ b/packages/frontend/src/pages/ads.vue
@@ -24,7 +24,7 @@ import { instance } from '@/instance.js';
 
 definePageMetadata({
 	title: i18n.ts.ads,
-	icon: 'ti ti-ad',
+	icon: 'ph-flag ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/announcements.vue b/packages/frontend/src/pages/announcements.vue
index babac9d805..7ac37adfbf 100644
--- a/packages/frontend/src/pages/announcements.vue
+++ b/packages/frontend/src/pages/announcements.vue
@@ -11,14 +11,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkInfo v-if="$i && $i.hasUnreadAnnouncement && tab === 'current'" warn>{{ i18n.ts.youHaveUnreadAnnouncements }}</MkInfo>
 			<MkPagination ref="paginationEl" :key="tab" v-slot="{items}" :pagination="tab === 'current' ? paginationCurrent : paginationPast" class="_gaps">
 				<section v-for="announcement in items" :key="announcement.id" class="_panel" :class="$style.announcement">
-					<div v-if="announcement.forYou" :class="$style.forYou"><i class="ti ti-pin"></i> {{ i18n.ts.forYou }}</div>
+					<div v-if="announcement.forYou" :class="$style.forYou"><i class="ph-push-pin ph-bold ph-lg"></i> {{ i18n.ts.forYou }}</div>
 					<div :class="$style.header">
 						<span v-if="$i && !announcement.isRead" style="margin-right: 0.5em;">🆕</span>
 						<span style="margin-right: 0.5em;">
-							<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
-							<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
-							<i v-else-if="announcement.icon === 'error'" class="ti ti-circle-x" style="color: var(--error);"></i>
-							<i v-else-if="announcement.icon === 'success'" class="ti ti-check" style="color: var(--success);"></i>
+							<i v-if="announcement.icon === 'info'" class="ph-info ph-bold ph-lg"></i>
+							<i v-else-if="announcement.icon === 'warning'" class="ph-warning ph-bold ph-lg" style="color: var(--warn);"></i>
+							<i v-else-if="announcement.icon === 'error'" class="ph-x-circle ph-bold ph-lg" style="color: var(--error);"></i>
+							<i v-else-if="announcement.icon === 'success'" class="ph-check ph-bold ph-lg" style="color: var(--success);"></i>
 						</span>
 						<span>{{ announcement.title }}</span>
 					</div>
@@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						</div>
 					</div>
 					<div v-if="tab !== 'past' && $i && !announcement.isRead" :class="$style.footer">
-						<MkButton primary @click="read(announcement)"><i class="ti ti-check"></i> {{ i18n.ts.gotIt }}</MkButton>
+						<MkButton primary @click="read(announcement)"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.gotIt }}</MkButton>
 					</div>
 				</section>
 			</MkPagination>
@@ -95,16 +95,16 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'current',
 	title: i18n.ts.currentAnnouncements,
-	icon: 'ti ti-flare',
+	icon: 'ph-fire ph-bold pg-lg',
 }, {
 	key: 'past',
 	title: i18n.ts.pastAnnouncements,
-	icon: 'ti ti-point',
+	icon: 'ph-circle ph-bold pg-lg',
 }]);
 
 definePageMetadata({
 	title: i18n.ts.announcements,
-	icon: 'ti ti-speakerphone',
+	icon: 'ph-megaphone ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/antenna-timeline.vue b/packages/frontend/src/pages/antenna-timeline.vue
index 4ea91796d5..299974527d 100644
--- a/packages/frontend/src/pages/antenna-timeline.vue
+++ b/packages/frontend/src/pages/antenna-timeline.vue
@@ -78,11 +78,11 @@ watch(() => props.antennaId, async () => {
 }, { immediate: true });
 
 const headerActions = $computed(() => antenna ? [{
-	icon: 'ti ti-calendar-time',
+	icon: 'ph-calendar ph-bold ph-lg',
 	text: i18n.ts.jumpToSpecifiedDate,
 	handler: timetravel,
 }, {
-	icon: 'ti ti-settings',
+	icon: 'ph-gear ph-bold pg-lg',
 	text: i18n.ts.settings,
 	handler: settings,
 }] : []);
@@ -91,7 +91,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => antenna ? {
 	title: antenna.name,
-	icon: 'ti ti-antenna',
+	icon: 'ph-flying-saucer ph-bold pg-lg',
 } : null));
 </script>
 
diff --git a/packages/frontend/src/pages/api-console.vue b/packages/frontend/src/pages/api-console.vue
index 01657c4c2a..93ecbdf0cc 100644
--- a/packages/frontend/src/pages/api-console.vue
+++ b/packages/frontend/src/pages/api-console.vue
@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</MkSwitch>
 				<MkButton primary :disabled="sending" @click="send">
 					<template v-if="sending"><MkEllipsis/></template>
-					<template v-else><i class="ti ti-send"></i> Send</template>
+					<template v-else><i class="ph-paper-plane-tilt ph-bold ph-lg"></i> Send</template>
 				</MkButton>
 			</div>
 			<div v-if="res">
@@ -89,6 +89,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'API console',
-	icon: 'ti ti-terminal-2',
+	icon: 'ph-terminal-window ph-bold ph-lg-2',
 });
 </script>
diff --git a/packages/frontend/src/pages/auth.vue b/packages/frontend/src/pages/auth.vue
index b81abd56a9..81b97eebbf 100644
--- a/packages/frontend/src/pages/auth.vue
+++ b/packages/frontend/src/pages/auth.vue
@@ -120,7 +120,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts._auth.shareAccessTitle,
-	icon: 'ti ti-apps',
+	icon: 'ph-squares-four ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/channel-editor.vue b/packages/frontend/src/pages/channel-editor.vue
index 39ce093cf2..0417f2b0cd 100644
--- a/packages/frontend/src/pages/channel-editor.vue
+++ b/packages/frontend/src/pages/channel-editor.vue
@@ -25,10 +25,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkSwitch>
 
 			<div>
-				<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="ti ti-plus"></i> {{ i18n.ts._channel.setBanner }}</MkButton>
+				<MkButton v-if="bannerId == null" @click="setBannerImage"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts._channel.setBanner }}</MkButton>
 				<div v-else-if="bannerUrl">
 					<img :src="bannerUrl" style="width: 100%;"/>
-					<MkButton @click="removeBannerImage()"><i class="ti ti-trash"></i> {{ i18n.ts._channel.removeBanner }}</MkButton>
+					<MkButton @click="removeBannerImage()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts._channel.removeBanner }}</MkButton>
 				</div>
 			</div>
 
@@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<template #label>{{ i18n.ts.pinnedNotes }}</template>
 
 				<div class="_gaps">
-					<MkButton primary rounded @click="addPinnedNote()"><i class="ti ti-plus"></i></MkButton>
+					<MkButton primary rounded @click="addPinnedNote()"><i class="ph-plus ph-bold ph-lg"></i></MkButton>
 
 					<Sortable
 						v-model="pinnedNotes"
@@ -46,9 +46,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 					>
 						<template #item="{element,index}">
 							<div :class="$style.pinnedNote">
-								<button class="_button" :class="$style.pinnedNoteHandle"><i class="ti ti-menu"></i></button>
+								<button class="_button" :class="$style.pinnedNoteHandle"><i class="ph-list ph-bold ph-lg"></i></button>
 								{{ element.id }}
-								<button class="_button" :class="$style.pinnedNoteRemove" @click="removePinnedNote(index)"><i class="ti ti-x"></i></button>
+								<button class="_button" :class="$style.pinnedNoteRemove" @click="removePinnedNote(index)"><i class="ph-x ph-bold ph-lg"></i></button>
 							</div>
 						</template>
 					</Sortable>
@@ -56,8 +56,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkFolder>
 
 			<div class="_buttons">
-				<MkButton primary @click="save()"><i class="ti ti-device-floppy"></i> {{ channelId ? i18n.ts.save : i18n.ts.create }}</MkButton>
-				<MkButton v-if="channelId" danger @click="archive()"><i class="ti ti-trash"></i> {{ i18n.ts.archive }}</MkButton>
+				<MkButton primary @click="save()"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ channelId ? i18n.ts.save : i18n.ts.create }}</MkButton>
+				<MkButton v-if="channelId" danger @click="archive()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.archive }}</MkButton>
 			</div>
 		</div>
 	</MkSpacer>
@@ -198,10 +198,10 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => props.channelId ? {
 	title: i18n.ts._channel.edit,
-	icon: 'ti ti-device-tv',
+	icon: 'ph-television ph-bold ph-lg',
 } : {
 	title: i18n.ts._channel.create,
-	icon: 'ti ti-device-tv',
+	icon: 'ph-television ph-bold ph-lg',
 }));
 </script>
 
diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue
index 00e88cbbfb..ef7b1c0d7e 100644
--- a/packages/frontend/src/pages/channel.vue
+++ b/packages/frontend/src/pages/channel.vue
@@ -10,12 +10,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div v-if="channel && tab === 'overview'" class="_gaps">
 			<div class="_panel" :class="$style.bannerContainer">
 				<XChannelFollowButton :channel="channel" :full="true" :class="$style.subscribe"/>
-				<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike class="button" rounded primary :class="$style.favorite" @click="unfavorite()"><i class="ti ti-star"></i></MkButton>
-				<MkButton v-else v-tooltip="i18n.ts.favorite" asLike class="button" rounded :class="$style.favorite" @click="favorite()"><i class="ti ti-star"></i></MkButton>
+				<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike class="button" rounded primary :class="$style.favorite" @click="unfavorite()"><i class="ph-star ph-bold pg-lg"></i></MkButton>
+				<MkButton v-else v-tooltip="i18n.ts.favorite" asLike class="button" rounded :class="$style.favorite" @click="favorite()"><i class="ph-star ph-bold pg-lg"></i></MkButton>
 				<div :style="{ backgroundImage: channel.bannerUrl ? `url(${channel.bannerUrl})` : null }" :class="$style.banner">
 					<div :class="$style.bannerStatus">
-						<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><i class="ph-users ph-bold pg-lg 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="ph-pencil ph-bold ph-lg 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 v-if="channel.isSensitive" :class="$style.sensitiveIndicator">{{ i18n.ts.sensitive }}</div>
 					<div :class="$style.bannerFade"></div>
@@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 
 			<MkFoldableSection>
-				<template #header><i class="ti ti-pin ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedNotes }}</template>
+				<template #header><i class="ph-push-pin ph-bold ph-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedNotes }}</template>
 				<div v-if="channel.pinnedNotes.length > 0" class="_gaps">
 					<MkNote v-for="note in channel.pinnedNotes" :key="note.id" class="_panel" :note="note"/>
 				</div>
@@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div class="_gaps">
 				<div>
 					<MkInput v-model="searchQuery">
-						<template #prefix><i class="ti ti-search"></i></template>
+						<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 					</MkInput>
 					<MkButton primary rounded style="margin-top: 8px;" @click="search()">{{ i18n.ts.search }}</MkButton>
 				</div>
@@ -59,7 +59,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.footer">
 			<MkSpacer :contentMax="700" :marginMin="16" :marginMax="16">
 				<div class="_buttonsCenter">
-					<MkButton inline rounded primary gradate @click="openPostForm()"><i class="ti ti-pencil"></i> {{ i18n.ts.postToTheChannel }}</MkButton>
+					<MkButton inline rounded primary gradate @click="openPostForm()"><i class="ph-pencil ph-bold ph-lg"></i> {{ i18n.ts.postToTheChannel }}</MkButton>
 				</div>
 			</MkSpacer>
 		</div>
@@ -169,7 +169,7 @@ async function search() {
 const headerActions = $computed(() => {
 	if (channel && channel.userId) {
 		const share = {
-			icon: 'ti ti-share',
+			icon: 'ph-share-network ph-bold pg-lg',
 			text: i18n.ts.share,
 			handler: async (): Promise<void> => {
 				navigator.share({
@@ -182,7 +182,7 @@ const headerActions = $computed(() => {
 
 		const canEdit = ($i && $i.id === channel.userId) || iAmModerator;
 		return canEdit ? [share, {
-			icon: 'ti ti-settings',
+			icon: 'ph-gear ph-bold pg-lg',
 			text: i18n.ts.edit,
 			handler: edit,
 		}] : [share];
@@ -194,24 +194,24 @@ const headerActions = $computed(() => {
 const headerTabs = $computed(() => [{
 	key: 'overview',
 	title: i18n.ts.overview,
-	icon: 'ti ti-info-circle',
+	icon: 'ph-info ph-bold ph-lg',
 }, {
 	key: 'timeline',
 	title: i18n.ts.timeline,
-	icon: 'ti ti-home',
+	icon: 'ph-house ph-bold ph-lg',
 }, {
 	key: 'featured',
 	title: i18n.ts.featured,
-	icon: 'ti ti-bolt',
+	icon: 'ph-lightning ph-bold pg-lg',
 }, {
 	key: 'search',
 	title: i18n.ts.search,
-	icon: 'ti ti-search',
+	icon: 'ph-magnifying-glass ph-bold ph-lg',
 }]);
 
 definePageMetadata(computed(() => channel ? {
 	title: channel.name,
-	icon: 'ti ti-device-tv',
+	icon: 'ph-television ph-bold ph-lg',
 } : null));
 </script>
 
@@ -268,7 +268,7 @@ definePageMetadata(computed(() => channel ? {
 	padding: 8px 12px;
 	font-size: 80%;
 	background: rgba(0, 0, 0, 0.7);
-	border-radius: 6px;
+	border-radius: 5px;
 	color: #fff;
 }
 
@@ -283,7 +283,7 @@ definePageMetadata(computed(() => channel ? {
 	left: 16px;
 	background: rgba(0, 0, 0, 0.7);
 	color: var(--warn);
-	border-radius: 6px;
+	border-radius: 5px;
 	font-weight: bold;
 	font-size: 1em;
 	padding: 4px 7px;
diff --git a/packages/frontend/src/pages/channels.vue b/packages/frontend/src/pages/channels.vue
index 8219a947f2..16acaae2a7 100644
--- a/packages/frontend/src/pages/channels.vue
+++ b/packages/frontend/src/pages/channels.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div v-if="tab === 'search'">
 			<div class="_gaps">
 				<MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search">
-					<template #prefix><i class="ti ti-search"></i></template>
+					<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 				</MkInput>
 				<MkRadios v-model="searchType" @update:modelValue="search()">
 					<option value="nameAndDescription">{{ i18n.ts._channel.nameAndDescription }}</option>
@@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkPagination>
 		</div>
 		<div v-else-if="tab === 'owned'">
-			<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
+			<MkButton class="new" @click="create()"><i class="ph-plus ph-bold ph-lg"></i></MkButton>
 			<MkPagination v-slot="{items}" :pagination="ownedPagination">
 				<MkChannelPreview v-for="channel in items" :key="channel.id" class="_margin" :channel="channel"/>
 			</MkPagination>
@@ -122,7 +122,7 @@ function create() {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.create,
 	handler: create,
 }]);
@@ -130,27 +130,27 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'search',
 	title: i18n.ts.search,
-	icon: 'ti ti-search',
+	icon: 'ph-magnifying-glass ph-bold ph-lg',
 }, {
 	key: 'featured',
 	title: i18n.ts._channel.featured,
-	icon: 'ti ti-comet',
+	icon: 'ph-shooting-star ph-bold ph-lg',
 }, {
 	key: 'favorites',
 	title: i18n.ts.favorites,
-	icon: 'ti ti-star',
+	icon: 'ph-star ph-bold pg-lg',
 }, {
 	key: 'following',
 	title: i18n.ts._channel.following,
-	icon: 'ti ti-eye',
+	icon: 'ph-eye ph-bold ph-lg',
 }, {
 	key: 'owned',
 	title: i18n.ts._channel.owned,
-	icon: 'ti ti-edit',
+	icon: 'ph-pencil-line ph-bold pg-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.channel,
-	icon: 'ti ti-device-tv',
+	icon: 'ph-television ph-bold ph-lg',
 })));
 </script>
diff --git a/packages/frontend/src/pages/clicker.vue b/packages/frontend/src/pages/clicker.vue
index 5b194881d1..19f9d5752f 100644
--- a/packages/frontend/src/pages/clicker.vue
+++ b/packages/frontend/src/pages/clicker.vue
@@ -18,7 +18,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
 
 definePageMetadata({
 	title: '🍪👈',
-	icon: 'ti ti-cookie',
+	icon: 'ph-cookie ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/clip.vue b/packages/frontend/src/pages/clip.vue
index 80b94acb6b..bc712ddfb8 100644
--- a/packages/frontend/src/pages/clip.vue
+++ b/packages/frontend/src/pages/clip.vue
@@ -12,8 +12,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div v-if="clip.description" :class="$style.description">
 					<Mfm :text="clip.description" :isNote="false" :i="$i"/>
 				</div>
-				<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike rounded primary @click="unfavorite()"><i class="ti ti-heart"></i><span v-if="clip.favoritedCount > 0" style="margin-left: 6px;">{{ clip.favoritedCount }}</span></MkButton>
-				<MkButton v-else v-tooltip="i18n.ts.favorite" asLike rounded @click="favorite()"><i class="ti ti-heart"></i><span v-if="clip.favoritedCount > 0" style="margin-left: 6px;">{{ clip.favoritedCount }}</span></MkButton>
+				<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" asLike rounded primary @click="unfavorite()"><i class="ph-heart ph-bold ph-lg"></i><span v-if="clip.favoritedCount > 0" style="margin-left: 6px;">{{ clip.favoritedCount }}</span></MkButton>
+				<MkButton v-else v-tooltip="i18n.ts.favorite" asLike rounded @click="favorite()"><i class="ph-heart ph-bold ph-lg"></i><span v-if="clip.favoritedCount > 0" style="margin-left: 6px;">{{ clip.favoritedCount }}</span></MkButton>
 				<div :class="$style.user">
 					<MkAvatar :user="clip.user" :class="$style.avatar" indicator link preview/> <MkUserName :user="clip.user" :nowrap="false"/>
 				</div>
@@ -86,7 +86,7 @@ async function unfavorite() {
 }
 
 const headerActions = $computed(() => clip && isOwned ? [{
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	text: i18n.ts.edit,
 	handler: async (): Promise<void> => {
 		const { canceled, result } = await os.form(clip.name, {
@@ -118,7 +118,7 @@ const headerActions = $computed(() => clip && isOwned ? [{
 		clipsCache.delete();
 	},
 }, ...(clip.isPublic ? [{
-	icon: 'ti ti-share',
+	icon: 'ph-share-network ph-bold pg-lg',
 	text: i18n.ts.share,
 	handler: async (): Promise<void> => {
 		navigator.share({
@@ -128,7 +128,7 @@ const headerActions = $computed(() => clip && isOwned ? [{
 		});
 	},
 }] : []), {
-	icon: 'ti ti-trash',
+	icon: 'ph-trash ph-bold ph-lg',
 	text: i18n.ts.delete,
 	danger: true,
 	handler: async (): Promise<void> => {
@@ -148,7 +148,7 @@ const headerActions = $computed(() => clip && isOwned ? [{
 
 definePageMetadata(computed(() => clip ? {
 	title: clip.name,
-	icon: 'ti ti-paperclip',
+	icon: 'ph-paperclip ph-bold ph-lg',
 } : null));
 </script>
 
diff --git a/packages/frontend/src/pages/custom-emojis-manager.vue b/packages/frontend/src/pages/custom-emojis-manager.vue
index a8d9dd3a34..d45e26408c 100644
--- a/packages/frontend/src/pages/custom-emojis-manager.vue
+++ b/packages/frontend/src/pages/custom-emojis-manager.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div class="ogwlenmc">
 				<div v-if="tab === 'local'" class="local">
 					<MkInput v-model="query" :debounce="true" type="search">
-						<template #prefix><i class="ti ti-search"></i></template>
+						<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 						<template #label>{{ i18n.ts.search }}</template>
 					</MkInput>
 					<MkSwitch v-model="selectMode" style="margin: 8px 0;">
@@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div v-else-if="tab === 'remote'" class="remote">
 					<FormSplit>
 						<MkInput v-model="queryRemote" :debounce="true" type="search">
-							<template #prefix><i class="ti ti-search"></i></template>
+							<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 							<template #label>{{ i18n.ts.search }}</template>
 						</MkInput>
 						<MkInput v-model="host" :debounce="true">
@@ -168,12 +168,12 @@ const remoteMenu = (emoji, ev: MouseEvent) => {
 	},
 	{
 		text: i18n.ts.import,
-		icon: 'ti ti-plus',
+		icon: 'ph-plus ph-bold ph-lg',
 		action: () => { im(emoji); },
 	},
 	{
 		text: i18n.ts.delete,
-		icon: "ti ti-trash",
+		icon: "ph-trash ph-bold ph-lg",
 		action: () => {
 			os.apiWithDialog("admin/emoji/delete", {
 				id: emoji.id,
@@ -184,7 +184,7 @@ const remoteMenu = (emoji, ev: MouseEvent) => {
 
 const menu = (ev: MouseEvent) => {
 	os.popupMenu([{
-		icon: 'ti ti-download',
+		icon: 'ph-download ph-bold ph-lg',
 		text: i18n.ts.export,
 		action: async () => {
 			os.api('export-custom-emojis', {
@@ -202,7 +202,7 @@ const menu = (ev: MouseEvent) => {
 				});
 		},
 	}, {
-		icon: 'ti ti-upload',
+		icon: 'ph-upload ph-bold ph-lg',
 		text: i18n.ts.import,
 		action: async () => {
 			const file = await selectFile(ev.currentTarget ?? ev.target);
@@ -298,11 +298,11 @@ const delBulk = async () => {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.addEmoji,
 	handler: add,
 }, {
-	icon: 'ti ti-dots',
+	icon: 'ph-dots-three ph-bold ph-lg',
 	handler: menu,
 }]);
 
@@ -316,7 +316,7 @@ const headerTabs = $computed(() => [{
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.customEmojis,
-	icon: 'ti ti-icons',
+	icon: 'ph-smiley ph-bold pg-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/drive.vue b/packages/frontend/src/pages/drive.vue
index 54fb83fc1d..b92dc8b470 100644
--- a/packages/frontend/src/pages/drive.vue
+++ b/packages/frontend/src/pages/drive.vue
@@ -23,7 +23,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: folder ? folder.name : i18n.ts.drive,
-	icon: 'ti ti-cloud',
+	icon: 'ph-cloud ph-bold ph-lg',
 	hideHeader: true,
 })));
 </script>
diff --git a/packages/frontend/src/pages/emoji-edit-dialog.vue b/packages/frontend/src/pages/emoji-edit-dialog.vue
index 2e6050490e..b9dd3e6e8f 100644
--- a/packages/frontend/src/pages/emoji-edit-dialog.vue
+++ b/packages/frontend/src/pages/emoji-edit-dialog.vue
@@ -49,12 +49,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<template #suffix>{{ rolesThatCanBeUsedThisEmojiAsReaction.length === 0 ? i18n.ts.all : rolesThatCanBeUsedThisEmojiAsReaction.length }}</template>
 
 					<div class="_gaps">
-						<MkButton rounded @click="addRole"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
+						<MkButton rounded @click="addRole"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
 
 						<div v-for="role in rolesThatCanBeUsedThisEmojiAsReaction" :key="role.id" :class="$style.roleItem">
 							<MkRolePreview :class="$style.role" :role="role" :forModeration="true" :detailed="false" style="pointer-events: none;"/>
-							<button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="removeRole(role, $event)"><i class="ti ti-x"></i></button>
-							<button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ti ti-ban"></i></button>
+							<button v-if="role.target === 'manual'" class="_button" :class="$style.roleUnassign" @click="removeRole(role, $event)"><i class="ph-x ph-bold ph-lg"></i></button>
+							<button v-else class="_button" :class="$style.roleUnassign" disabled><i class="ph-prohibit ph-bold ph-lg"></i></button>
 						</div>
 
 						<MkInfo>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReactionEmptyDescription }}</MkInfo>
@@ -63,11 +63,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</MkFolder>
 				<MkSwitch v-model="isSensitive">isSensitive</MkSwitch>
 				<MkSwitch v-model="localOnly">{{ i18n.ts.localOnly }}</MkSwitch>
-				<MkButton v-if="emoji" danger @click="del()"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+				<MkButton v-if="emoji" danger @click="del()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 			</div>
 		</MkSpacer>
 		<div :class="$style.footer">
-			<MkButton primary rounded style="margin: 0 auto;" @click="done"><i class="ti ti-check"></i> {{ props.emoji ? i18n.ts.update : i18n.ts.create }}</MkButton>
+			<MkButton primary rounded style="margin: 0 auto;" @click="done"><i class="ph-check ph-bold ph-lg"></i> {{ props.emoji ? i18n.ts.update : i18n.ts.create }}</MkButton>
 		</div>
 	</div>
 </MkModalWindow>
@@ -206,7 +206,7 @@ async function del() {
 
 .imgContainer {
 	padding: 8px;
-	border-radius: 6px;
+	border-radius: 5px;
 }
 
 .img {
diff --git a/packages/frontend/src/pages/emojis.emoji.vue b/packages/frontend/src/pages/emojis.emoji.vue
index 9aaa7890a9..210a0fcf8f 100644
--- a/packages/frontend/src/pages/emojis.emoji.vue
+++ b/packages/frontend/src/pages/emojis.emoji.vue
@@ -34,14 +34,14 @@ function menu(ev) {
 		text: ':' + props.emoji.name + ':',
 	}, {
 		text: i18n.ts.copy,
-		icon: 'ti ti-copy',
+		icon: 'ph-copy ph-bold ph-lg',
 		action: () => {
 			copyToClipboard(`:${props.emoji.name}:`);
 			os.success();
 		},
 	}, {
 		text: i18n.ts.info,
-		icon: 'ti ti-info-circle',
+		icon: 'ph-info ph-bold ph-lg',
 		action: () => {
 			os.apiGet('emoji', { name: props.emoji.name }).then(res => {
 				os.alert({
@@ -61,7 +61,7 @@ function menu(ev) {
 	padding: 12px;
 	text-align: left;
 	background: var(--panel);
-	border-radius: 8px;
+	border-radius: 5px;
 
 	&:hover {
 		border-color: var(--accent);
diff --git a/packages/frontend/src/pages/explore.users.vue b/packages/frontend/src/pages/explore.users.vue
index 1f187d6b8a..20bd74fb40 100644
--- a/packages/frontend/src/pages/explore.users.vue
+++ b/packages/frontend/src/pages/explore.users.vue
@@ -12,26 +12,26 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div v-if="origin === 'local'">
 		<template v-if="tag == null">
 			<MkFoldableSection class="_margin" persistKey="explore-pinned-users">
-				<template #header><i class="ti ti-bookmark ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedUsers }}</template>
+				<template #header><i class="ph-bookmark ph-bold ph-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.pinnedUsers }}</template>
 				<MkUserList :pagination="pinnedUsers"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin" persistKey="explore-popular-users">
-				<template #header><i class="ti ti-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
+				<template #header><i class="ph-chart-line ph-bold pg-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
 				<MkUserList :pagination="popularUsers"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin" persistKey="explore-recently-updated-users">
-				<template #header><i class="ti ti-message ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
+				<template #header><i class="ph-chat-text ph-bold ph-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
 				<MkUserList :pagination="recentlyUpdatedUsers"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin" persistKey="explore-recently-registered-users">
-				<template #header><i class="ti ti-plus ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyRegisteredUsers }}</template>
+				<template #header><i class="ph-plus ph-bold ph-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyRegisteredUsers }}</template>
 				<MkUserList :pagination="recentlyRegisteredUsers"/>
 			</MkFoldableSection>
 		</template>
 	</div>
 	<div v-else>
 		<MkFoldableSection ref="tagsEl" :foldable="true" :expanded="false" class="_margin">
-			<template #header><i class="ti ti-hash ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularTags }}</template>
+			<template #header><i class="ph-hash ph-bold ph-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularTags }}</template>
 
 			<div>
 				<MkA v-for="tag in tagsLocal" :key="'local:' + tag.tag" :to="`/user-tags/${tag.tag}`" style="margin-right: 16px; font-weight: bold;">{{ tag.tag }}</MkA>
@@ -40,21 +40,21 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</MkFoldableSection>
 
 		<MkFoldableSection v-if="tag != null" :key="`${tag}`" class="_margin">
-			<template #header><i class="ti ti-hash ti-fw" style="margin-right: 0.5em;"></i>{{ tag }}</template>
+			<template #header><i class="ph-hash ph-bold ph-lg ti-fw" style="margin-right: 0.5em;"></i>{{ tag }}</template>
 			<MkUserList :pagination="tagUsers"/>
 		</MkFoldableSection>
 
 		<template v-if="tag == null">
 			<MkFoldableSection class="_margin">
-				<template #header><i class="ti ti-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
+				<template #header><i class="ph-chart-line ph-bold pg-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularUsers }}</template>
 				<MkUserList :pagination="popularUsersF"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin">
-				<template #header><i class="ti ti-message ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
+				<template #header><i class="ph-chat-text ph-bold ph-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyUpdatedUsers }}</template>
 				<MkUserList :pagination="recentlyUpdatedUsersF"/>
 			</MkFoldableSection>
 			<MkFoldableSection class="_margin">
-				<template #header><i class="ti ti-rocket ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyDiscoveredUsers }}</template>
+				<template #header><i class="ph-rocket-launch ph-bold pg-lg ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.recentlyDiscoveredUsers }}</template>
 				<MkUserList :pagination="recentlyRegisteredUsersF"/>
 			</MkFoldableSection>
 		</template>
diff --git a/packages/frontend/src/pages/explore.vue b/packages/frontend/src/pages/explore.vue
index fd846d979a..58d7aca92d 100644
--- a/packages/frontend/src/pages/explore.vue
+++ b/packages/frontend/src/pages/explore.vue
@@ -47,20 +47,20 @@ const headerActions = $computed(() => []);
 
 const headerTabs = $computed(() => [{
 	key: 'featured',
-	icon: 'ti ti-bolt',
+	icon: 'ph-lightning ph-bold pg-lg',
 	title: i18n.ts.featured,
 }, {
 	key: 'users',
-	icon: 'ti ti-users',
+	icon: 'ph-users ph-bold pg-lg',
 	title: i18n.ts.users,
 }, {
 	key: 'roles',
-	icon: 'ti ti-badges',
+	icon: 'ph-seal-check ph-bold pg-lg',
 	title: i18n.ts.roles,
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.explore,
-	icon: 'ti ti-hash',
+	icon: 'ph-hash ph-bold ph-lg',
 })));
 </script>
diff --git a/packages/frontend/src/pages/favorites.vue b/packages/frontend/src/pages/favorites.vue
index 63a0057b74..cb7390cf6a 100644
--- a/packages/frontend/src/pages/favorites.vue
+++ b/packages/frontend/src/pages/favorites.vue
@@ -40,7 +40,7 @@ const pagination = {
 
 definePageMetadata({
 	title: i18n.ts.favorites,
-	icon: 'ti ti-star',
+	icon: 'ph-star ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/flash/flash-edit.vue b/packages/frontend/src/pages/flash/flash-edit.vue
index f494218c18..ce25ad63a8 100644
--- a/packages/frontend/src/pages/flash/flash-edit.vue
+++ b/packages/frontend/src/pages/flash/flash-edit.vue
@@ -14,14 +14,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkTextarea v-model="summary">
 				<template #label>{{ i18n.ts._play.summary }}</template>
 			</MkTextarea>
-			<MkButton primary @click="selectPreset">{{ i18n.ts.selectFromPresets }}<i class="ti ti-chevron-down"></i></MkButton>
+			<MkButton primary @click="selectPreset">{{ i18n.ts.selectFromPresets }}<i class="ph-caret-down ph-bold ph-lg"></i></MkButton>
 			<MkTextarea v-model="script" class="_monospace" tall spellcheck="false">
 				<template #label>{{ i18n.ts._play.script }}</template>
 			</MkTextarea>
 			<div class="_buttons">
-				<MkButton primary @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
-				<MkButton @click="show"><i class="ti ti-eye"></i> {{ i18n.ts.show }}</MkButton>
-				<MkButton v-if="flash" danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+				<MkButton primary @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
+				<MkButton @click="show"><i class="ph-eye ph-bold ph-lg"></i> {{ i18n.ts.show }}</MkButton>
+				<MkButton v-if="flash" danger @click="del"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 			</div>
 			<MkSelect v-model="visibility">
 				<template #label>{{ i18n.ts.visibility }}</template>
diff --git a/packages/frontend/src/pages/flash/flash-index.vue b/packages/frontend/src/pages/flash/flash-index.vue
index 4a686efd45..a9438fd917 100644
--- a/packages/frontend/src/pages/flash/flash-index.vue
+++ b/packages/frontend/src/pages/flash/flash-index.vue
@@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 		<div v-else-if="tab === 'my'">
 			<div class="_gaps">
-				<MkButton gradate rounded style="margin: 0 auto;" @click="create()"><i class="ti ti-plus"></i></MkButton>
+				<MkButton gradate rounded style="margin: 0 auto;" @click="create()"><i class="ph-plus ph-bold ph-lg"></i></MkButton>
 				<MkPagination v-slot="{items}" :pagination="myFlashsPagination">
 					<div class="_gaps_s">
 						<MkFlashPreview v-for="flash in items" :key="flash.id" :flash="flash"/>
@@ -68,7 +68,7 @@ function create() {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.create,
 	handler: create,
 }]);
@@ -76,19 +76,19 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'featured',
 	title: i18n.ts._play.featured,
-	icon: 'ti ti-flare',
+	icon: 'ph-fire ph-bold pg-lg',
 }, {
 	key: 'my',
 	title: i18n.ts._play.my,
-	icon: 'ti ti-edit',
+	icon: 'ph-pencil-line ph-bold pg-lg',
 }, {
 	key: 'liked',
 	title: i18n.ts._play.liked,
-	icon: 'ti ti-heart',
+	icon: 'ph-heart ph-bold ph-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: 'Play',
-	icon: 'ti ti-player-play',
+	icon: 'ph-play ph-bold pg-lg',
 })));
 </script>
diff --git a/packages/frontend/src/pages/flash/flash.vue b/packages/frontend/src/pages/flash/flash.vue
index 32a835831c..8bb293eebf 100644
--- a/packages/frontend/src/pages/flash/flash.vue
+++ b/packages/frontend/src/pages/flash/flash.vue
@@ -15,10 +15,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<MkAsUi v-if="root" :component="root" :components="components"/>
 						</div>
 						<div class="actions _panel">
-							<MkButton v-if="flash.isLiked" v-tooltip="i18n.ts.unlike" asLike class="button" rounded primary @click="unlike()"><i class="ti ti-heart"></i><span v-if="flash.likedCount > 0" style="margin-left: 6px;">{{ flash.likedCount }}</span></MkButton>
-							<MkButton v-else v-tooltip="i18n.ts.like" asLike class="button" rounded @click="like()"><i class="ti ti-heart"></i><span v-if="flash.likedCount > 0" style="margin-left: 6px;">{{ flash.likedCount }}</span></MkButton>
-							<MkButton v-tooltip="i18n.ts.shareWithNote" class="button" rounded @click="shareWithNote"><i class="ti ti-repeat ti-fw"></i></MkButton>
-							<MkButton v-tooltip="i18n.ts.share" class="button" rounded @click="share"><i class="ti ti-share ti-fw"></i></MkButton>
+							<MkButton v-if="flash.isLiked" v-tooltip="i18n.ts.unlike" asLike class="button" rounded primary @click="unlike()"><i class="ph-heart ph-bold ph-lg"></i><span v-if="flash.likedCount > 0" style="margin-left: 6px;">{{ flash.likedCount }}</span></MkButton>
+							<MkButton v-else v-tooltip="i18n.ts.like" asLike class="button" rounded @click="like()"><i class="ph-heart ph-bold ph-lg"></i><span v-if="flash.likedCount > 0" style="margin-left: 6px;">{{ flash.likedCount }}</span></MkButton>
+							<MkButton v-tooltip="i18n.ts.shareWithNote" class="button" rounded @click="shareWithNote"><i class="ph-repeat ph-bold ph-lg ti-fw"></i></MkButton>
+							<MkButton v-tooltip="i18n.ts.share" class="button" rounded @click="share"><i class="ph-share-network ph-bold pg-lg ti-fw"></i></MkButton>
 						</div>
 					</div>
 					<div v-else :class="$style.ready">
@@ -27,13 +27,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<div class="summary">{{ flash.summary }}</div>
 							<MkButton class="start" gradate rounded large @click="start">Play</MkButton>
 							<div class="info">
-								<span v-tooltip="i18n.ts.numberOfLikes"><i class="ti ti-heart"></i> {{ flash.likedCount }}</span>
+								<span v-tooltip="i18n.ts.numberOfLikes"><i class="ph-heart ph-bold ph-lg"></i> {{ flash.likedCount }}</span>
 							</div>
 						</div>
 					</div>
 				</Transition>
 				<MkFolder :defaultOpen="false" :max-height="280" class="_margin">
-					<template #icon><i class="ti ti-code"></i></template>
+					<template #icon><i class="ph-code ph-bold pg-lg"></i></template>
 					<template #label>{{ i18n.ts._play.viewSource }}</template>
 
 					<MkCode :code="flash.script" :inline="false" class="_monospace"/>
@@ -41,8 +41,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div :class="$style.footer">
 					<Mfm :text="`By @${flash.user.username}`"/>
 					<div class="date">
-						<div v-if="flash.createdAt != flash.updatedAt"><i class="ti ti-clock"></i> {{ i18n.ts.updatedAt }}: <MkTime :time="flash.updatedAt" mode="detail"/></div>
-						<div><i class="ti ti-clock"></i> {{ i18n.ts.createdAt }}: <MkTime :time="flash.createdAt" mode="detail"/></div>
+						<div v-if="flash.createdAt != flash.updatedAt"><i class="ph-clock ph-bold ph-lg"></i> {{ i18n.ts.updatedAt }}: <MkTime :time="flash.updatedAt" mode="detail"/></div>
+						<div><i class="ph-clock ph-bold ph-lg"></i> {{ i18n.ts.createdAt }}: <MkTime :time="flash.createdAt" mode="detail"/></div>
 					</div>
 				</div>
 				<MkA v-if="$i && $i.id === flash.userId" :to="`/play/${flash.id}/edit`" style="color: var(--accent);">{{ i18n.ts._play.editThisPage }}</MkA>
diff --git a/packages/frontend/src/pages/follow-requests.vue b/packages/frontend/src/pages/follow-requests.vue
index 4f7fdef0ba..1686718f2c 100644
--- a/packages/frontend/src/pages/follow-requests.vue
+++ b/packages/frontend/src/pages/follow-requests.vue
@@ -24,8 +24,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 								<p class="acct">@{{ acct(req.follower) }}</p>
 							</div>
 							<div class="commands">
-								<MkButton class="command" rounded primary @click="accept(req.follower)"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
-								<MkButton class="command" rounded danger @click="reject(req.follower)"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
+								<MkButton class="command" rounded primary @click="accept(req.follower)"><i class="ph-check ph-bold ph-lg"/> {{ i18n.ts.accept }}</MkButton>
+								<MkButton class="command" rounded danger @click="reject(req.follower)"><i class="ph-x ph-bold ph-lg"/> {{ i18n.ts.reject }}</MkButton>
 							</div>
 						</div>
 					</div>
@@ -71,7 +71,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.followRequests,
-	icon: 'ti ti-user-plus',
+	icon: 'ph-user-plus ph-bold ph-lg',
 })));
 </script>
 
@@ -87,7 +87,7 @@ definePageMetadata(computed(() => ({
 			margin: 0 12px 0 0;
 			width: 42px;
 			height: 42px;
-			border-radius: 8px;
+			border-radius: 5px;
 		}
 
 		> .body {
diff --git a/packages/frontend/src/pages/gallery/edit.vue b/packages/frontend/src/pages/gallery/edit.vue
index f3cbd4947c..0d43eee613 100644
--- a/packages/frontend/src/pages/gallery/edit.vue
+++ b/packages/frontend/src/pages/gallery/edit.vue
@@ -19,18 +19,18 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div class="_gaps_s">
 				<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="ti ti-x"></i></button>
+					<button v-tooltip="i18n.ts.remove" class="remove _button" @click="remove(file)"><i class="ph-x ph-bold ph-lg"></i></button>
 				</div>
-				<MkButton primary @click="selectFile"><i class="ti ti-plus"></i> {{ i18n.ts.attachFile }}</MkButton>
+				<MkButton primary @click="selectFile"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.attachFile }}</MkButton>
 			</div>
 
 			<MkSwitch v-model="isSensitive">{{ i18n.ts.markAsSensitive }}</MkSwitch>
 
 			<div class="_buttons">
-				<MkButton v-if="postId" primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
-				<MkButton v-else primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.publish }}</MkButton>
+				<MkButton v-if="postId" primary @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
+				<MkButton v-else primary @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.publish }}</MkButton>
 
-				<MkButton v-if="postId" danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+				<MkButton v-if="postId" danger @click="del"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 			</div>
 		</FormSuspense>
 	</MkSpacer>
@@ -122,10 +122,10 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => props.postId ? {
 	title: i18n.ts.edit,
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 } : {
 	title: i18n.ts.postToGallery,
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 }));
 </script>
 
diff --git a/packages/frontend/src/pages/gallery/index.vue b/packages/frontend/src/pages/gallery/index.vue
index 43bb7c496d..21b27d1c59 100644
--- a/packages/frontend/src/pages/gallery/index.vue
+++ b/packages/frontend/src/pages/gallery/index.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div class="_root">
 			<div v-if="tab === 'explore'">
 				<MkFoldableSection class="_margin">
-					<template #header><i class="ti ti-clock"></i>{{ i18n.ts.recentPosts }}</template>
+					<template #header><i class="ph-clock ph-bold ph-lg"></i>{{ i18n.ts.recentPosts }}</template>
 					<MkPagination v-slot="{items}" :pagination="recentPostsPagination" :disableAutoLoad="true">
 						<div :class="$style.items">
 							<MkGalleryPostPreview v-for="post in items" :key="post.id" :post="post" class="post"/>
@@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</MkPagination>
 				</MkFoldableSection>
 				<MkFoldableSection class="_margin">
-					<template #header><i class="ti ti-comet"></i>{{ i18n.ts.popularPosts }}</template>
+					<template #header><i class="ph-shooting-star ph-bold ph-lg"></i>{{ i18n.ts.popularPosts }}</template>
 					<MkPagination v-slot="{items}" :pagination="popularPostsPagination" :disableAutoLoad="true">
 						<div :class="$style.items">
 							<MkGalleryPostPreview v-for="post in items" :key="post.id" :post="post" class="post"/>
@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</MkPagination>
 			</div>
 			<div v-else-if="tab === 'my'">
-				<MkA to="/gallery/new" class="_link" style="margin: 16px;"><i class="ti ti-plus"></i> {{ i18n.ts.postToGallery }}</MkA>
+				<MkA to="/gallery/new" class="_link" style="margin: 16px;"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.postToGallery }}</MkA>
 				<MkPagination v-slot="{items}" :pagination="myPostsPagination">
 					<div :class="$style.items">
 						<MkGalleryPostPreview v-for="post in items" :key="post.id" :post="post" class="post"/>
@@ -97,7 +97,7 @@ watch(() => props.tag, () => {
 });
 
 const headerActions = $computed(() => [{
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.create,
 	handler: () => {
 		router.push('/gallery/new');
@@ -107,20 +107,20 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'explore',
 	title: i18n.ts.gallery,
-	icon: 'ti ti-icons',
+	icon: 'ph-images-square ph-bold pg-lg',
 }, {
 	key: 'liked',
 	title: i18n.ts._gallery.liked,
-	icon: 'ti ti-heart',
+	icon: 'ph-heart ph-bold ph-lg',
 }, {
 	key: 'my',
 	title: i18n.ts._gallery.my,
-	icon: 'ti ti-edit',
+	icon: 'ph-pencil-line ph-bold pg-lg',
 }]);
 
 definePageMetadata({
 	title: i18n.ts.gallery,
-	icon: 'ti ti-icons',
+	icon: 'ph-images-square ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/gallery/post.vue b/packages/frontend/src/pages/gallery/post.vue
index 3f4f657e94..4de05644b2 100644
--- a/packages/frontend/src/pages/gallery/post.vue
+++ b/packages/frontend/src/pages/gallery/post.vue
@@ -19,17 +19,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<div class="title">{{ post.title }}</div>
 						<div class="description"><Mfm :text="post.description"/></div>
 						<div class="info">
-							<i class="ti ti-clock"></i> <MkTime :time="post.createdAt" mode="detail"/>
+							<i class="ph-clock ph-bold ph-lg"></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="ti ti-heart-off"></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="ti ti-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="ph-heart-break ph-bold ph-lg"></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="ph-heart ph-bold ph-lg"></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="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>
+								<button v-if="$i && $i.id === post.user.id" v-tooltip="i18n.ts.edit" v-click-anime class="_button" @click="edit"><i class="ph-pencil ph-bold ph-lg ti-fw"></i></button>
+								<button v-tooltip="i18n.ts.shareWithNote" v-click-anime class="_button" @click="shareWithNote"><i class="ph-repeat ph-bold ph-lg ti-fw"></i></button>
+								<button v-tooltip="i18n.ts.share" v-click-anime class="_button" @click="share"><i class="ph-share-network ph-bold pg-lg ti-fw"></i></button>
 							</div>
 						</div>
 						<div class="user">
@@ -43,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</div>
 					<MkAd :prefer="['horizontal', 'horizontal-big']"/>
 					<MkContainer :max-height="300" :foldable="true" class="other">
-						<template #icon><i class="ti ti-clock"></i></template>
+						<template #icon><i class="ph-clock ph-bold ph-lg"></i></template>
 						<template #header>{{ i18n.ts.recentPosts }}</template>
 						<MkPagination v-slot="{items}" :pagination="otherPostsPagination">
 							<div class="sdrarzaf">
@@ -146,7 +146,7 @@ function edit() {
 watch(() => props.postId, fetchPost, { immediate: true });
 
 const headerActions = $computed(() => [{
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	text: i18n.ts.edit,
 	handler: edit,
 }]);
diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue
index 2285e4c88e..b4d2fcf0d9 100644
--- a/packages/frontend/src/pages/instance-info.vue
+++ b/packages/frontend/src/pages/instance-info.vue
@@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div class="_gaps_s">
 					<MkSwitch v-model="suspended" :disabled="!instance" @update:modelValue="toggleSuspend">{{ i18n.ts.stopActivityDelivery }}</MkSwitch>
 					<MkSwitch v-model="isBlocked" :disabled="!meta || !instance" @update:modelValue="toggleBlock">{{ i18n.ts.blockThisInstance }}</MkSwitch>
-					<MkButton @click="refreshMetadata"><i class="ti ti-refresh"></i> Refresh metadata</MkButton>
+					<MkButton @click="refreshMetadata"><i class="ph-arrows-counter-clockwise ph-bold pg-lg"></i> Refresh metadata</MkButton>
 				</div>
 			</FormSection>
 
@@ -203,7 +203,7 @@ fetch();
 
 const headerActions = $computed(() => [{
 	text: `https://${props.host}`,
-	icon: 'ti ti-external-link',
+	icon: 'ph-arrow-square-out ph-bold ph-lg',
 	handler: () => {
 		window.open(`https://${props.host}`, '_blank');
 	},
@@ -212,24 +212,24 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'overview',
 	title: i18n.ts.overview,
-	icon: 'ti ti-info-circle',
+	icon: 'ph-info ph-bold ph-lg',
 }, {
 	key: 'chart',
 	title: i18n.ts.charts,
-	icon: 'ti ti-chart-line',
+	icon: 'ph-chart-line ph-bold pg-lg',
 }, {
 	key: 'users',
 	title: i18n.ts.users,
-	icon: 'ti ti-users',
+	icon: 'ph-users ph-bold pg-lg',
 }, {
 	key: 'raw',
 	title: 'Raw',
-	icon: 'ti ti-code',
+	icon: 'ph-code ph-bold pg-lg',
 }]);
 
 definePageMetadata({
 	title: props.host,
-	icon: 'ti ti-server',
+	icon: 'ph-hard-drives ph-bold ph-lg',
 });
 </script>
 
@@ -242,7 +242,7 @@ definePageMetadata({
 		display: block;
 		margin: 0 16px 0 0;
 		height: 64px;
-		border-radius: 8px;
+		border-radius: 5px;
 	}
 
 	> .name {
diff --git a/packages/frontend/src/pages/invite.vue b/packages/frontend/src/pages/invite.vue
index b44b580e86..2c0ed41450 100644
--- a/packages/frontend/src/pages/invite.vue
+++ b/packages/frontend/src/pages/invite.vue
@@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.root">
 			<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
 			<div :class="$style.text">
-				<i class="ti ti-alert-triangle"></i>
+				<i class="ph-warning ph-bold ph-lg"></i>
 				{{ i18n.ts.nothing }}
 			</div>
 		</div>
@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<MkSpacer v-else :contentMax="800">
 		<div class="_gaps_m" style="text-align: center;">
 			<div v-if="resetCycle && inviteLimit">{{ i18n.t('inviteLimitResetCycle', { time: resetCycle, limit: inviteLimit }) }}</div>
-			<MkButton inline primary rounded :disabled="currentInviteLimit !== null && currentInviteLimit <= 0" @click="create"><i class="ti ti-user-plus"></i> {{ i18n.ts.createInviteCode }}</MkButton>
+			<MkButton inline primary rounded :disabled="currentInviteLimit !== null && currentInviteLimit <= 0" @click="create"><i class="ph-user-plus ph-bold ph-lg"></i> {{ i18n.ts.createInviteCode }}</MkButton>
 			<div v-if="currentInviteLimit !== null">{{ i18n.t('createLimitRemaining', { limit: currentInviteLimit }) }}</div>
 
 			<MkPagination ref="pagingComponent" :pagination="pagination">
@@ -94,7 +94,7 @@ update();
 
 definePageMetadata({
 	title: i18n.ts.invite,
-	icon: 'ti ti-user-plus',
+	icon: 'ph-user-plus ph-bold ph-lg',
 });
 </script>
 
@@ -114,6 +114,6 @@ definePageMetadata({
 	width: 128px;
 	height: 128px;
 	margin-bottom: 16px;
-	border-radius: 16px;
+	border-radius: 4px;
 }
 </style>
diff --git a/packages/frontend/src/pages/list.vue b/packages/frontend/src/pages/list.vue
index db0b201b73..9309ebc08f 100644
--- a/packages/frontend/src/pages/list.vue
+++ b/packages/frontend/src/pages/list.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.root">
 			<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
 			<p :class="$style.text">
-				<i class="ti ti-alert-triangle"></i>
+				<i class="ph-warning ph-bold ph-lg"></i>
 				{{ i18n.ts.nothing }}
 			</p>
 		</div>
@@ -26,9 +26,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 		</div>
-		<MkButton v-if="list.isLiked" v-tooltip="i18n.ts.unlike" inline :class="$style.button" asLike primary @click="unlike()"><i class="ti ti-heart-off"></i><span v-if="list.likedCount > 0" class="count">{{ list.likedCount }}</span></MkButton>
-		<MkButton v-if="!list.isLiked" v-tooltip="i18n.ts.like" inline :class="$style.button" asLike @click="like()"><i class="ti ti-heart"></i><span v-if="1 > 0" class="count">{{ list.likedCount }}</span></MkButton>
-		<MkButton inline @click="create()"><i class="ti ti-download" :class="$style.import"></i>{{ i18n.ts.import }}</MkButton>
+		<MkButton v-if="list.isLiked" v-tooltip="i18n.ts.unlike" inline :class="$style.button" asLike primary @click="unlike()"><i class="ph-heart-break ph-bold ph-lg"></i><span v-if="list.likedCount > 0" class="count">{{ list.likedCount }}</span></MkButton>
+		<MkButton v-if="!list.isLiked" v-tooltip="i18n.ts.like" inline :class="$style.button" asLike @click="like()"><i class="ph-heart ph-bold ph-lg"></i><span v-if="1 > 0" class="count">{{ list.likedCount }}</span></MkButton>
+		<MkButton inline @click="create()"><i class="ph-download ph-bold ph-lg" :class="$style.import"></i>{{ i18n.ts.import }}</MkButton>
 	</MkSpacer>
 </MkStickyContainer>
 </template>
@@ -101,7 +101,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => list ? {
 	title: list.name,
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 } : null));
 </script>
 <style lang="scss" module>
@@ -141,7 +141,7 @@ definePageMetadata(computed(() => list ? {
   width: 128px;
 	height: 128px;
 	margin-bottom: 16px;
-	border-radius: 16px;
+	border-radius: 4px;
 }
 
 .button {
diff --git a/packages/frontend/src/pages/miauth.vue b/packages/frontend/src/pages/miauth.vue
index 1572d27aab..e3cbcab080 100644
--- a/packages/frontend/src/pages/miauth.vue
+++ b/packages/frontend/src/pages/miauth.vue
@@ -95,7 +95,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'MiAuth',
-	icon: 'ti ti-apps',
+	icon: 'ph-squares-four ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/my-antennas/create.vue b/packages/frontend/src/pages/my-antennas/create.vue
index 2e08c13f1b..d3d4f6480f 100644
--- a/packages/frontend/src/pages/my-antennas/create.vue
+++ b/packages/frontend/src/pages/my-antennas/create.vue
@@ -38,6 +38,6 @@ function onAntennaCreated() {
 
 definePageMetadata({
 	title: i18n.ts.manageAntennas,
-	icon: 'ti ti-antenna',
+	icon: 'ph-flying-saucer ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/my-antennas/edit.vue b/packages/frontend/src/pages/my-antennas/edit.vue
index 6600ebcc64..8d17c8c5e0 100644
--- a/packages/frontend/src/pages/my-antennas/edit.vue
+++ b/packages/frontend/src/pages/my-antennas/edit.vue
@@ -36,6 +36,6 @@ os.api('antennas/show', { antennaId: props.antennaId }).then((antennaResponse) =
 
 definePageMetadata({
 	title: i18n.ts.manageAntennas,
-	icon: 'ti ti-antenna',
+	icon: 'ph-flying-saucer ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/my-antennas/editor.vue b/packages/frontend/src/pages/my-antennas/editor.vue
index 4add66c396..50b3b7ee36 100644
--- a/packages/frontend/src/pages/my-antennas/editor.vue
+++ b/packages/frontend/src/pages/my-antennas/editor.vue
@@ -40,8 +40,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkSwitch v-model="notify">{{ i18n.ts.notifyAntenna }}</MkSwitch>
 		</div>
 		<div :class="$style.actions">
-			<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>
+			<MkButton inline primary @click="saveAntenna()"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
+			<MkButton v-if="antenna.id != null" inline danger @click="deleteAntenna()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 		</div>
 	</div>
 </MkSpacer>
diff --git a/packages/frontend/src/pages/my-antennas/index.vue b/packages/frontend/src/pages/my-antennas/index.vue
index 2d9cd05b45..b1d92e42e8 100644
--- a/packages/frontend/src/pages/my-antennas/index.vue
+++ b/packages/frontend/src/pages/my-antennas/index.vue
@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 
-			<MkButton :link="true" to="/my/antennas/create" primary :class="$style.add"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
+			<MkButton :link="true" to="/my/antennas/create" primary :class="$style.add"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
 
 			<div v-if="antennas.length > 0" class="_gaps">
 				<MkA v-for="antenna in antennas" :key="antenna.id" :class="$style.antenna" :to="`/my/antennas/${antenna.id}`">
@@ -45,7 +45,7 @@ fetch();
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-refresh',
+	icon: 'ph-arrows-counter-clockwise ph-bold pg-lg',
 	text: i18n.ts.reload,
 	handler: () => {
 		antennasCache.delete();
@@ -57,7 +57,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.manageAntennas,
-	icon: 'ti ti-antenna',
+	icon: 'ph-flying-saucer ph-bold pg-lg',
 });
 
 onActivated(() => {
@@ -74,7 +74,7 @@ onActivated(() => {
 	display: block;
 	padding: 16px;
 	border: solid 1px var(--divider);
-	border-radius: 6px;
+	border-radius: 5px;
 
 	&:hover {
 		border: solid 1px var(--accent);
diff --git a/packages/frontend/src/pages/my-clips/index.vue b/packages/frontend/src/pages/my-clips/index.vue
index 8289d65a4b..eb84112c69 100644
--- a/packages/frontend/src/pages/my-clips/index.vue
+++ b/packages/frontend/src/pages/my-clips/index.vue
@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
 	<MkSpacer :contentMax="700">
 		<div v-if="tab === 'my'" class="_gaps">
-			<MkButton primary rounded class="add" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
+			<MkButton primary rounded class="add" @click="create"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
 
 			<MkPagination v-slot="{items}" ref="pagingComponent" :pagination="pagination" class="_gaps">
 				<MkA v-for="item in items" :key="item.id" :to="`/clips/${item.id}`">
@@ -90,18 +90,18 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'my',
 	title: i18n.ts.myClips,
-	icon: 'ti ti-paperclip',
+	icon: 'ph-paperclip ph-bold ph-lg',
 }, {
 	key: 'favorites',
 	title: i18n.ts.favorites,
-	icon: 'ti ti-heart',
+	icon: 'ph-heart ph-bold ph-lg',
 }]);
 
 definePageMetadata({
 	title: i18n.ts.clip,
-	icon: 'ti ti-paperclip',
+	icon: 'ph-paperclip ph-bold ph-lg',
 	action: {
-		icon: 'ti ti-plus',
+		icon: 'ph-plus ph-bold ph-lg',
 		handler: create,
 	},
 });
diff --git a/packages/frontend/src/pages/my-lists/index.vue b/packages/frontend/src/pages/my-lists/index.vue
index 3e7efb5a7c..01cd0d8aa9 100644
--- a/packages/frontend/src/pages/my-lists/index.vue
+++ b/packages/frontend/src/pages/my-lists/index.vue
@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 			</div>
 
-			<MkButton primary rounded style="margin: 0 auto;" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.createList }}</MkButton>
+			<MkButton primary rounded style="margin: 0 auto;" @click="create"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.createList }}</MkButton>
 
 			<div v-if="items.length > 0" class="_gaps">
 				<MkA v-for="list in items" :key="list.id" class="_panel" :class="$style.list" :to="`/my/lists/${ list.id }`">
@@ -59,7 +59,7 @@ async function create() {
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-refresh',
+	icon: 'ph-arrows-counter-clockwise ph-bold pg-lg',
 	text: i18n.ts.reload,
 	handler: () => {
 		userListsCache.delete();
@@ -71,7 +71,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.manageLists,
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 });
 
 onActivated(() => {
@@ -84,7 +84,7 @@ onActivated(() => {
 	display: block;
 	padding: 16px;
 	border: solid 1px var(--divider);
-	border-radius: 6px;
+	border-radius: 5px;
 	margin-bottom: 8px;
 
 	&:hover {
diff --git a/packages/frontend/src/pages/my-lists/list.vue b/packages/frontend/src/pages/my-lists/list.vue
index df13998f6b..41f3a9c23f 100644
--- a/packages/frontend/src/pages/my-lists/list.vue
+++ b/packages/frontend/src/pages/my-lists/list.vue
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<MkA :class="$style.userItemBody" :to="`${userPage(user)}`">
 							<MkUserCardMini :user="user"/>
 						</MkA>
-						<button class="_button" :class="$style.remove" @click="removeUser(user, $event)"><i class="ti ti-x"></i></button>
+						<button class="_button" :class="$style.remove" @click="removeUser(user, $event)"><i class="ph-x ph-bold ph-lg"></i></button>
 					</div>
 					<MkButton v-if="!fetching && queueUserIds.length !== 0" v-appear="enableInfiniteScroll ? fetchMoreUsers : null" :class="$style.more" :style="{ cursor: 'pointer' }" primary rounded @click="fetchMoreUsers">
 						{{ i18n.ts.loadMore }}
@@ -122,7 +122,7 @@ function addUser() {
 async function removeUser(user, ev) {
 	os.popupMenu([{
 		text: i18n.ts.remove,
-		icon: 'ti ti-x',
+		icon: 'ph-x ph-bold ph-lg',
 		danger: true,
 		action: async () => {
 			if (!list) return;
@@ -173,7 +173,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => list ? {
 	title: list.name,
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 } : null));
 </script>
 
diff --git a/packages/frontend/src/pages/not-found.vue b/packages/frontend/src/pages/not-found.vue
index b3d40e3ef8..410979bdc6 100644
--- a/packages/frontend/src/pages/not-found.vue
+++ b/packages/frontend/src/pages/not-found.vue
@@ -32,6 +32,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.notFound,
-	icon: 'ti ti-alert-triangle',
+	icon: 'ph-warning ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/note.vue b/packages/frontend/src/pages/note.vue
index 066a3042ba..1de610e282 100644
--- a/packages/frontend/src/pages/note.vue
+++ b/packages/frontend/src/pages/note.vue
@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</div>
 
 					<div class="_margin">
-						<MkButton v-if="!showNext" :class="$style.loadNext" @click="showNext = true"><i class="ti ti-chevron-up"></i></MkButton>
+						<MkButton v-if="!showNext" :class="$style.loadNext" @click="showNext = true"><i class="ph-caret-up ph-bold ph-lg"></i></MkButton>
 						<div class="_margin _gaps_s">
 							<MkRemoteCaution v-if="note.user.host != null" :href="note.url ?? note.uri"/>
 							<MkNoteDetailed :key="note.id" v-model:note="note" :class="$style.note"/>
@@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 								</MkA>
 							</div>
 						</div>
-						<MkButton v-if="!showPrev" :class="$style.loadPrev" @click="showPrev = true"><i class="ti ti-chevron-down"></i></MkButton>
+						<MkButton v-if="!showPrev" :class="$style.loadPrev" @click="showPrev = true"><i class="ph-caret-down ph-bold ph-lg"></i></MkButton>
 					</div>
 
 					<div v-if="showPrev" class="_margin">
@@ -141,7 +141,7 @@ definePageMetadata(computed(() => note ? {
 .loadPrev {
 	min-width: 0;
 	margin: 0 auto;
-	border-radius: 999px;
+	border-radius: 4px;
 }
 
 .loadNext {
diff --git a/packages/frontend/src/pages/notifications.vue b/packages/frontend/src/pages/notifications.vue
index 3ae6319c7e..bee1acd2c7 100644
--- a/packages/frontend/src/pages/notifications.vue
+++ b/packages/frontend/src/pages/notifications.vue
@@ -54,7 +54,7 @@ function setFilter(ev) {
 		},
 	}));
 	const items = includeTypes != null ? [{
-		icon: 'ti ti-x',
+		icon: 'ph-x ph-bold ph-lg',
 		text: i18n.ts.clear,
 		action: () => {
 			includeTypes = null;
@@ -65,12 +65,12 @@ function setFilter(ev) {
 
 const headerActions = $computed(() => [tab === 'all' ? {
 	text: i18n.ts.filter,
-	icon: 'ti ti-filter',
+	icon: 'ph-funnel ph-bold ph-lg',
 	highlighted: includeTypes != null,
 	handler: setFilter,
 } : undefined, tab === 'all' ? {
 	text: i18n.ts.markAllAsRead,
-	icon: 'ti ti-check',
+	icon: 'ph-check ph-bold ph-lg',
 	handler: () => {
 		os.apiWithDialog('notifications/mark-all-as-read');
 	},
@@ -79,19 +79,19 @@ const headerActions = $computed(() => [tab === 'all' ? {
 const headerTabs = $computed(() => [{
 	key: 'all',
 	title: i18n.ts.all,
-	icon: 'ti ti-point',
+	icon: 'ph-circle ph-bold pg-lg',
 }, {
 	key: 'mentions',
 	title: i18n.ts.mentions,
-	icon: 'ti ti-at',
+	icon: 'ph-at ph-bold ph-lg',
 }, {
 	key: 'directNotes',
 	title: i18n.ts.directNotes,
-	icon: 'ti ti-mail',
+	icon: 'ph-envelope ph-bold ph-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.notifications,
-	icon: 'ti ti-bell',
+	icon: 'ph-bell ph-bold pg-lg',
 })));
 </script>
diff --git a/packages/frontend/src/pages/oauth.vue b/packages/frontend/src/pages/oauth.vue
index 878fa6be4e..a03a8f75a6 100644
--- a/packages/frontend/src/pages/oauth.vue
+++ b/packages/frontend/src/pages/oauth.vue
@@ -53,7 +53,7 @@ function onLogin(res): void {
 
 definePageMetadata({
 	title: 'OAuth',
-	icon: 'ti ti-apps',
+	icon: 'ph-squares-four ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue
index 4fffd311b2..2cb126c80f 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.image.vue
@@ -6,10 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="ti ti-photo"></i> {{ i18n.ts._pages.blocks.image }}</template>
+	<template #header><i class="ph-image-square ph-bold ph-lg"></i> {{ i18n.ts._pages.blocks.image }}</template>
 	<template #func>
 		<button @click="choose()">
-			<i class="ti ti-folder"></i>
+			<i class="ph-folder ph-bold ph-lg"></i>
 		</button>
 	</template>
 
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue
index fc436aad75..0ed6c9bfa4 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.note.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="ti ti-note"></i> {{ i18n.ts._pages.blocks.note }}</template>
+	<template #header><i class="ph-note ph-bold ph-lg"></i> {{ i18n.ts._pages.blocks.note }}</template>
 
 	<section style="padding: 0 16px 0 16px;">
 		<MkInput v-model="id">
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue
index 31c2c96d7c..f24131ebb7 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.section.vue
@@ -6,16 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="ti ti-note"></i> {{ props.modelValue.title }}</template>
+	<template #header><i class="ph-note ph-bold ph-lg"></i> {{ props.modelValue.title }}</template>
 	<template #func>
 		<button class="_button" @click="rename()">
-			<i class="ti ti-pencil"></i>
+			<i class="ph-pencil ph-bold ph-lg"></i>
 		</button>
 	</template>
 
 	<section class="ilrvjyvi">
 		<XBlocks v-model="children" class="children"/>
-		<MkButton rounded class="add" @click="add()"><i class="ti ti-plus"></i></MkButton>
+		<MkButton rounded class="add" @click="add()"><i class="ph-plus ph-bold ph-lg"></i></MkButton>
 	</section>
 </XContainer>
 </template>
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
index 2ecf5790b8..8df74374b2 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <!-- eslint-disable vue/no-mutating-props -->
 <XContainer :draggable="true" @remove="() => $emit('remove')">
-	<template #header><i class="ti ti-align-left"></i> {{ i18n.ts._pages.blocks.text }}</template>
+	<template #header><i class="ph-text-align-left ph-bold ph-lg"></i> {{ i18n.ts._pages.blocks.text }}</template>
 
 	<section>
 		<textarea v-model="text" :class="$style.textarea"></textarea>
diff --git a/packages/frontend/src/pages/page-editor/page-editor.container.vue b/packages/frontend/src/pages/page-editor/page-editor.container.vue
index c1bc0c61c9..cb0af1d548 100644
--- a/packages/frontend/src/pages/page-editor/page-editor.container.vue
+++ b/packages/frontend/src/pages/page-editor/page-editor.container.vue
@@ -10,14 +10,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div class="buttons">
 			<slot name="func"></slot>
 			<button v-if="removable" class="_button" @click="remove()">
-				<i class="ti ti-trash"></i>
+				<i class="ph-trash ph-bold ph-lg"></i>
 			</button>
 			<button v-if="draggable" class="drag-handle _button">
-				<i class="ti ti-menu-2"></i>
+				<i class="ph-list ph-bold ph-lg-2"></i>
 			</button>
 			<button class="_button" @click="toggleContent(!showBody)">
-				<template v-if="showBody"><i class="ti ti-chevron-up"></i></template>
-				<template v-else><i class="ti ti-chevron-down"></i></template>
+				<template v-if="showBody"><i class="ph-caret-up ph-bold ph-lg"></i></template>
+				<template v-else><i class="ph-caret-down ph-bold ph-lg"></i></template>
 			</button>
 		</div>
 	</header>
@@ -63,7 +63,7 @@ function remove() {
 	overflow: hidden;
 	background: var(--panel);
 	border: solid 2px var(--X12);
-	border-radius: 8px;
+	border-radius: 5px;
 
 	&:hover {
 		border: solid 2px var(--X13);
diff --git a/packages/frontend/src/pages/page-editor/page-editor.vue b/packages/frontend/src/pages/page-editor/page-editor.vue
index 377267bdbc..396ee68f5a 100644
--- a/packages/frontend/src/pages/page-editor/page-editor.vue
+++ b/packages/frontend/src/pages/page-editor/page-editor.vue
@@ -8,10 +8,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
 	<MkSpacer :contentMax="700">
 		<div class="jqqmcavi">
-			<MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="ti ti-external-link"></i> {{ i18n.ts._pages.viewPage }}</MkButton>
-			<MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
-			<MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="ti ti-copy"></i> {{ i18n.ts.duplicate }}</MkButton>
-			<MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+			<MkButton v-if="pageId" class="button" inline link :to="`/@${ author.username }/pages/${ currentName }`"><i class="ph-arrow-square-out ph-bold ph-lg"></i> {{ i18n.ts._pages.viewPage }}</MkButton>
+			<MkButton v-if="!readonly" inline primary class="button" @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
+			<MkButton v-if="pageId" inline class="button" @click="duplicate"><i class="ph-copy ph-bold ph-lg"></i> {{ i18n.ts.duplicate }}</MkButton>
+			<MkButton v-if="pageId && !readonly" inline class="button" danger @click="del"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 		</div>
 
 		<div v-if="tab === 'settings'">
@@ -40,10 +40,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<MkSwitch v-model="hideTitleWhenPinned">{{ i18n.ts._pages.hideTitleWhenPinned }}</MkSwitch>
 
 				<div class="eyeCatch">
-					<MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><i class="ti ti-plus"></i> {{ i18n.ts._pages.eyeCatchingImageSet }}</MkButton>
+					<MkButton v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.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="ti ti-trash"></i> {{ i18n.ts._pages.eyeCatchingImageRemove }}</MkButton>
+						<MkButton v-if="!readonly" @click="removeEyeCatchingImage()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts._pages.eyeCatchingImageRemove }}</MkButton>
 					</div>
 				</div>
 			</div>
@@ -53,7 +53,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div :class="$style.contents">
 				<XBlocks v-model="content" class="content"/>
 
-				<MkButton v-if="!readonly" rounded class="add" @click="add()"><i class="ti ti-plus"></i></MkButton>
+				<MkButton v-if="!readonly" rounded class="add" @click="add()"><i class="ph-plus ph-bold ph-lg"></i></MkButton>
 			</div>
 		</div>
 	</MkSpacer>
@@ -275,11 +275,11 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'settings',
 	title: i18n.ts._pages.pageSetting,
-	icon: 'ti ti-settings',
+	icon: 'ph-gear ph-bold pg-lg',
 }, {
 	key: 'contents',
 	title: i18n.ts._pages.contents,
-	icon: 'ti ti-note',
+	icon: 'ph-note ph-bold ph-lg',
 }]);
 
 definePageMetadata(computed(() => {
@@ -292,7 +292,7 @@ definePageMetadata(computed(() => {
 	}
 	return {
 		title: title,
-		icon: 'ti ti-pencil',
+		icon: 'ph-pencil ph-bold ph-lg',
 	};
 }));
 </script>
diff --git a/packages/frontend/src/pages/page.vue b/packages/frontend/src/pages/page.vue
index 98cbaab2bb..d106216bf4 100644
--- a/packages/frontend/src/pages/page.vue
+++ b/packages/frontend/src/pages/page.vue
@@ -29,12 +29,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</div>
 					<div class="actions">
 						<div class="like">
-							<MkButton v-if="page.isLiked" v-tooltip="i18n.ts._pages.unlike" class="button" asLike primary @click="unlike()"><i class="ti ti-heart-off"></i><span v-if="page.likedCount > 0" class="count">{{ page.likedCount }}</span></MkButton>
-							<MkButton v-else v-tooltip="i18n.ts._pages.like" class="button" asLike @click="like()"><i class="ti ti-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" asLike primary @click="unlike()"><i class="ph-heart-break ph-bold ph-lg"></i><span v-if="page.likedCount > 0" class="count">{{ page.likedCount }}</span></MkButton>
+							<MkButton v-else v-tooltip="i18n.ts._pages.like" class="button" asLike @click="like()"><i class="ph-heart ph-bold ph-lg"></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="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>
+							<button v-tooltip="i18n.ts.shareWithNote" v-click-anime class="_button" @click="shareWithNote"><i class="ph-repeat ph-bold ph-lg ti-fw"></i></button>
+							<button v-tooltip="i18n.ts.share" v-click-anime class="_button" @click="share"><i class="ph-share-network ph-bold pg-lg ti-fw"></i></button>
 						</div>
 					</div>
 					<div class="user">
@@ -55,12 +55,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</div>
 				</div>
 				<div class="footer">
-					<div><i class="ti ti-clock"></i> {{ i18n.ts.createdAt }}: <MkTime :time="page.createdAt" mode="detail"/></div>
-					<div v-if="page.createdAt != page.updatedAt"><i class="ti ti-clock"></i> {{ i18n.ts.updatedAt }}: <MkTime :time="page.updatedAt" mode="detail"/></div>
+					<div><i class="ph-clock ph-bold ph-lg"></i> {{ i18n.ts.createdAt }}: <MkTime :time="page.createdAt" mode="detail"/></div>
+					<div v-if="page.createdAt != page.updatedAt"><i class="ph-clock ph-bold ph-lg"></i> {{ i18n.ts.updatedAt }}: <MkTime :time="page.updatedAt" mode="detail"/></div>
 				</div>
 				<MkAd :prefer="['horizontal', 'horizontal-big']"/>
 				<MkContainer :max-height="300" :foldable="true" class="other">
-					<template #icon><i class="ti ti-clock"></i></template>
+					<template #icon><i class="ph-clock ph-bold ph-lg"></i></template>
 					<template #header>{{ i18n.ts.recentPosts }}</template>
 					<MkPagination v-slot="{items}" :pagination="otherPostsPagination" :class="$style.relatedPagesRoot" class="_gaps">
 						<MkPagePreview v-for="page in items" :key="page.id" :page="page" :class="$style.relatedPagesItem"/>
diff --git a/packages/frontend/src/pages/pages.vue b/packages/frontend/src/pages/pages.vue
index 6f40b24771..ce136133d8 100644
--- a/packages/frontend/src/pages/pages.vue
+++ b/packages/frontend/src/pages/pages.vue
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 
 		<div v-else-if="tab === 'my'" class="_gaps">
-			<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
+			<MkButton class="new" @click="create()"><i class="ph-plus ph-bold ph-lg"></i></MkButton>
 			<MkPagination v-slot="{items}" :pagination="myPagesPagination">
 				<div class="_gaps">
 					<MkPagePreview v-for="page in items" :key="page.id" :page="page"/>
@@ -66,7 +66,7 @@ function create() {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'ti ti-plus',
+	icon: 'ph-plus ph-bold ph-lg',
 	text: i18n.ts.create,
 	handler: create,
 }]);
@@ -74,19 +74,19 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [{
 	key: 'featured',
 	title: i18n.ts._pages.featured,
-	icon: 'ti ti-flare',
+	icon: 'ph-fire ph-bold pg-lg',
 }, {
 	key: 'my',
 	title: i18n.ts._pages.my,
-	icon: 'ti ti-edit',
+	icon: 'ph-pencil-line ph-bold pg-lg',
 }, {
 	key: 'liked',
 	title: i18n.ts._pages.liked,
-	icon: 'ti ti-heart',
+	icon: 'ph-heart ph-bold ph-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.pages,
-	icon: 'ti ti-note',
+	icon: 'ph-note ph-bold ph-lg',
 })));
 </script>
diff --git a/packages/frontend/src/pages/registry.keys.vue b/packages/frontend/src/pages/registry.keys.vue
index a1a5fd0cf3..48e83f03a1 100644
--- a/packages/frontend/src/pages/registry.keys.vue
+++ b/packages/frontend/src/pages/registry.keys.vue
@@ -95,6 +95,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.registry,
-	icon: 'ti ti-adjustments',
+	icon: 'ph-faders ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/registry.value.vue b/packages/frontend/src/pages/registry.value.vue
index ebcb04e9f5..613da5a054 100644
--- a/packages/frontend/src/pages/registry.value.vue
+++ b/packages/frontend/src/pages/registry.value.vue
@@ -30,14 +30,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<template #label>{{ i18n.ts.value }} (JSON)</template>
 				</MkTextarea>
 
-				<MkButton primary @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+				<MkButton primary @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 
 				<MkKeyValue>
 					<template #key>{{ i18n.ts.updatedAt }}</template>
 					<template #value><MkTime :time="value.updatedAt" mode="detail"/></template>
 				</MkKeyValue>
 
-				<MkButton danger @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+				<MkButton danger @click="del"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 			</template>
 		</div>
 	</MkSpacer>
@@ -120,6 +120,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.registry,
-	icon: 'ti ti-adjustments',
+	icon: 'ph-faders ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/registry.vue b/packages/frontend/src/pages/registry.vue
index 37a0b52511..9dedc73a76 100644
--- a/packages/frontend/src/pages/registry.vue
+++ b/packages/frontend/src/pages/registry.vue
@@ -70,6 +70,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.registry,
-	icon: 'ti ti-adjustments',
+	icon: 'ph-faders ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/reset-password.vue b/packages/frontend/src/pages/reset-password.vue
index 718ca7d773..c1fdfdbeb6 100644
--- a/packages/frontend/src/pages/reset-password.vue
+++ b/packages/frontend/src/pages/reset-password.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<MkSpacer v-if="token" :contentMax="700" :marginMin="16" :marginMax="32">
 		<div class="_gaps_m">
 			<MkInput v-model="password" type="password">
-				<template #prefix><i class="ti ti-lock"></i></template>
+				<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 				<template #label>{{ i18n.ts.newPassword }}</template>
 			</MkInput>
 
@@ -55,6 +55,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.resetPassword,
-	icon: 'ti ti-lock',
+	icon: 'ph-lock ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/role.vue b/packages/frontend/src/pages/role.vue
index b2a0a931f9..ec58203879 100644
--- a/packages/frontend/src/pages/role.vue
+++ b/packages/frontend/src/pages/role.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div :class="$style.root">
 			<img :class="$style.img" :src="serverErrorImageUrl" class="_ghost"/>
 			<p :class="$style.text">
-				<i class="ti ti-alert-triangle"></i>
+				<i class="ph-warning ph-bold ph-lg"></i>
 				{{ error }}
 			</p>
 		</div>
@@ -74,17 +74,17 @@ const users = $computed(() => ({
 
 const headerTabs = $computed(() => [{
 	key: 'users',
-	icon: 'ti ti-users',
+	icon: 'ph-users ph-bold pg-lg',
 	title: i18n.ts.users,
 }, {
 	key: 'timeline',
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	title: i18n.ts.timeline,
 }]);
 
 definePageMetadata(computed(() => ({
 	title: role?.name,
-	icon: 'ti ti-badge',
+	icon: 'ph-seal-check ph-bold pg-lg',
 })));
 </script>
 
@@ -104,7 +104,7 @@ definePageMetadata(computed(() => ({
   width: 128px;
 	height: 128px;
 	margin-bottom: 16px;
-	border-radius: 16px;
+	border-radius: 4px;
 }
 </style>
 
diff --git a/packages/frontend/src/pages/scratchpad.vue b/packages/frontend/src/pages/scratchpad.vue
index 3dfd2d661f..02bfa949db 100644
--- a/packages/frontend/src/pages/scratchpad.vue
+++ b/packages/frontend/src/pages/scratchpad.vue
@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div :class="$style.root">
 		<div :class="$style.editor" class="_panel">
 			<PrismEditor v-model="code" class="_monospace" :class="$style.code" :highlight="highlighter" :lineNumbers="false"/>
-			<MkButton style="position: absolute; top: 8px; right: 8px;" primary @click="run()"><i class="ti ti-player-play"></i></MkButton>
+			<MkButton style="position: absolute; top: 8px; right: 8px;" primary @click="run()"><i class="ph-play ph-bold pg-lg"></i></MkButton>
 		</div>
 
 		<MkContainer v-if="root && components.length > 1" :key="uiKey" :foldable="true">
@@ -170,7 +170,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.scratchpad,
-	icon: 'ti ti-terminal-2',
+	icon: 'ph-terminal-window ph-bold ph-lg-2',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/search.note.vue b/packages/frontend/src/pages/search.note.vue
index c1692d8be2..22fcb7c24d 100644
--- a/packages/frontend/src/pages/search.note.vue
+++ b/packages/frontend/src/pages/search.note.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="_gaps">
 	<div class="_gaps">
 		<MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search">
-			<template #prefix><i class="ti ti-search"></i></template>
+			<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 		</MkInput>
 		<MkFolder>
 			<template #label>{{ i18n.ts.options }}</template>
diff --git a/packages/frontend/src/pages/search.user.vue b/packages/frontend/src/pages/search.user.vue
index 1a7501adc6..c0b2e55986 100644
--- a/packages/frontend/src/pages/search.user.vue
+++ b/packages/frontend/src/pages/search.user.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="_gaps">
 	<div class="_gaps">
 		<MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search">
-			<template #prefix><i class="ti ti-search"></i></template>
+			<template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
 		</MkInput>
 		<MkRadios v-model="searchOrigin" @update:modelValue="search()">
 			<option value="combined">{{ i18n.ts.all }}</option>
diff --git a/packages/frontend/src/pages/search.vue b/packages/frontend/src/pages/search.vue
index e205fe850f..e3a0b75859 100644
--- a/packages/frontend/src/pages/search.vue
+++ b/packages/frontend/src/pages/search.vue
@@ -43,15 +43,15 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => [{
 	key: 'note',
 	title: i18n.ts.notes,
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 }, {
 	key: 'user',
 	title: i18n.ts.users,
-	icon: 'ti ti-users',
+	icon: 'ph-users ph-bold pg-lg',
 }]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.search,
-	icon: 'ti ti-search',
+	icon: 'ph-magnifying-glass ph-bold ph-lg',
 })));
 </script>
diff --git a/packages/frontend/src/pages/settings/2fa.qrdialog.vue b/packages/frontend/src/pages/settings/2fa.qrdialog.vue
index c2d1694c5b..046e172e10 100644
--- a/packages/frontend/src/pages/settings/2fa.qrdialog.vue
+++ b/packages/frontend/src/pages/settings/2fa.qrdialog.vue
@@ -42,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						</div>
 						<div class="_buttonsCenter" style="margin-top: 16px;">
 							<MkButton rounded @click="cancel">{{ i18n.ts.cancel }}</MkButton>
-							<MkButton primary rounded gradate @click="page++">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
+							<MkButton primary rounded gradate @click="page++">{{ i18n.ts.continue }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 						</div>
 					</MkSpacer>
 				</div>
@@ -56,8 +56,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<div>{{ i18n.ts._2fa.step3 }}</div>
 						</div>
 						<div class="_buttonsCenter" style="margin-top: 16px;">
-							<MkButton rounded @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton>
-							<MkButton primary rounded gradate @click="tokenDone">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
+							<MkButton rounded @click="page--"><i class="ph-arrow-left ph-bold pg-lg"></i> {{ i18n.ts.goBack }}</MkButton>
+							<MkButton primary rounded gradate @click="tokenDone">{{ i18n.ts.continue }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 						</div>
 					</MkSpacer>
 				</div>
@@ -71,7 +71,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<div style="text-align: center; font-weight: bold;">{{ i18n.ts._2fa.checkBackupCodesBeforeCloseThisWizard }}</div>
 
 							<MkFolder :defaultOpen="true">
-								<template #icon><i class="ti ti-key"></i></template>
+								<template #icon><i class="ph-key ph-bold ph-lg"></i></template>
 								<template #label>{{ i18n.ts._2fa.backupCodes }}</template>
 
 								<div class="_gaps">
diff --git a/packages/frontend/src/pages/settings/2fa.vue b/packages/frontend/src/pages/settings/2fa.vue
index 8a89a3a86d..4e2f367374 100644
--- a/packages/frontend/src/pages/settings/2fa.vue
+++ b/packages/frontend/src/pages/settings/2fa.vue
@@ -16,10 +16,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</MkInfo>
 
 		<MkFolder :defaultOpen="true">
-			<template #icon><i class="ti ti-shield-lock"></i></template>
+			<template #icon><i class="ph-shield ph-bold ph-lg-lock"></i></template>
 			<template #label>{{ i18n.ts.totp }}</template>
 			<template #caption>{{ i18n.ts.totpDescription }}</template>
-			<template #suffix><i v-if="$i.twoFactorEnabled" class="ti ti-check" style="color: var(--success)"></i></template>
+			<template #suffix><i v-if="$i.twoFactorEnabled" class="ph-check ph-bold ph-lg" style="color: var(--success)"></i></template>
 
 			<div v-if="$i.twoFactorEnabled" class="_gaps_s">
 				<div v-text="i18n.ts._2fa.alreadyRegistered"/>
@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</MkFolder>
 
 		<MkFolder>
-			<template #icon><i class="ti ti-key"></i></template>
+			<template #icon><i class="ph-key ph-bold ph-lg"></i></template>
 			<template #label>{{ i18n.ts.securityKeyAndPasskey }}</template>
 			<div class="_gaps_s">
 				<MkInfo>
@@ -55,8 +55,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<template #label>{{ key.name }}</template>
 						<template #suffix><I18n :src="i18n.ts.lastUsedAt"><template #t><MkTime :time="key.lastUsed"/></template></I18n></template>
 						<div class="_buttons">
-							<MkButton @click="renameKey(key)"><i class="ti ti-forms"></i> {{ i18n.ts.rename }}</MkButton>
-							<MkButton danger @click="unregisterKey(key)"><i class="ti ti-trash"></i> {{ i18n.ts.unregister }}</MkButton>
+							<MkButton @click="renameKey(key)"><i class="ph-textbox ph-bold ph-lg"></i> {{ i18n.ts.rename }}</MkButton>
+							<MkButton danger @click="unregisterKey(key)"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.unregister }}</MkButton>
 						</div>
 					</MkFolder>
 				</template>
diff --git a/packages/frontend/src/pages/settings/accounts.vue b/packages/frontend/src/pages/settings/accounts.vue
index df8c7b440a..3f63c3dd7f 100644
--- a/packages/frontend/src/pages/settings/accounts.vue
+++ b/packages/frontend/src/pages/settings/accounts.vue
@@ -8,8 +8,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<FormSuspense :p="init">
 		<div class="_gaps">
 			<div class="_buttons">
-				<MkButton primary @click="addAccount"><i class="ti ti-plus"></i> {{ i18n.ts.addAccount }}</MkButton>
-				<MkButton @click="init"><i class="ti ti-refresh"></i> {{ i18n.ts.reloadAccountsList }}</MkButton>
+				<MkButton primary @click="addAccount"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.addAccount }}</MkButton>
+				<MkButton @click="init"><i class="ph-arrows-counter-clockwise ph-bold pg-lg"></i> {{ i18n.ts.reloadAccountsList }}</MkButton>
 			</div>
 
 			<MkUserCardMini v-for="user in accounts" :key="user.id" :user="user" :class="$style.user" @click.prevent="menu(user, $event)"/>
@@ -47,11 +47,11 @@ const init = async () => {
 function menu(account, ev) {
 	os.popupMenu([{
 		text: i18n.ts.switch,
-		icon: 'ti ti-switch-horizontal',
+		icon: 'ph-arrows-left-right ph-bold ph-lg',
 		action: () => switchAccount(account),
 	}, {
 		text: i18n.ts.logout,
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		danger: true,
 		action: () => removeAccount(account),
 	}], ev.currentTarget ?? ev.target);
@@ -107,7 +107,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.accounts,
-	icon: 'ti ti-users',
+	icon: 'ph-users ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/settings/api.vue b/packages/frontend/src/pages/settings/api.vue
index e0266bccba..66de0997ae 100644
--- a/packages/frontend/src/pages/settings/api.vue
+++ b/packages/frontend/src/pages/settings/api.vue
@@ -46,6 +46,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'API',
-	icon: 'ti ti-api',
+	icon: 'ph-webhooks-logo ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/apps.vue b/packages/frontend/src/pages/settings/apps.vue
index 7fd4ed61c9..c06db27245 100644
--- a/packages/frontend/src/pages/settings/apps.vue
+++ b/packages/frontend/src/pages/settings/apps.vue
@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 							</ul>
 						</details>
 						<div>
-							<MkButton inline danger @click="revoke(token)"><i class="ti ti-trash"></i></MkButton>
+							<MkButton inline danger @click="revoke(token)"><i class="ph-trash ph-bold ph-lg"></i></MkButton>
 						</div>
 					</div>
 				</div>
@@ -77,7 +77,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.installedApps,
-	icon: 'ti ti-plug',
+	icon: 'ph-plug ph-bold ph-lg',
 });
 </script>
 
@@ -93,7 +93,7 @@ definePageMetadata({
 	margin: 0 12px 0 0;
 	width: 50px;
 	height: 50px;
-	border-radius: 8px;
+	border-radius: 5px;
 }
 
 .appBody {
diff --git a/packages/frontend/src/pages/settings/custom-css.vue b/packages/frontend/src/pages/settings/custom-css.vue
index d58f959fc5..760c8da9bd 100644
--- a/packages/frontend/src/pages/settings/custom-css.vue
+++ b/packages/frontend/src/pages/settings/custom-css.vue
@@ -47,6 +47,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.customCss,
-	icon: 'ti ti-code',
+	icon: 'ph-code ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/deck.vue b/packages/frontend/src/pages/settings/deck.vue
index 9fecc65d6d..ff9a78cd52 100644
--- a/packages/frontend/src/pages/settings/deck.vue
+++ b/packages/frontend/src/pages/settings/deck.vue
@@ -38,6 +38,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.deck,
-	icon: 'ti ti-columns',
+	icon: 'ph-text-columns ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/drive-cleaner.vue b/packages/frontend/src/pages/settings/drive-cleaner.vue
index 899d824bf9..791d76d1b4 100644
--- a/packages/frontend/src/pages/settings/drive-cleaner.vue
+++ b/packages/frontend/src/pages/settings/drive-cleaner.vue
@@ -119,7 +119,7 @@ function onContextMenu(ev: MouseEvent, file): void {
 
 definePageMetadata({
 	title: i18n.ts.drivecleaner,
-	icon: 'ti ti-trash',
+	icon: 'ph-trash ph-bold ph-lg',
 });
 </script>
 
@@ -152,7 +152,7 @@ definePageMetadata({
 	height: 12px;
 	background: rgba(0, 0, 0, 0.1);
 	overflow: clip;
-	border-radius: 999px;
+	border-radius: 4px;
 }
 
 .meterValue {
diff --git a/packages/frontend/src/pages/settings/drive.vue b/packages/frontend/src/pages/settings/drive.vue
index 01a0711682..0c6effbaa2 100644
--- a/packages/frontend/src/pages/settings/drive.vue
+++ b/packages/frontend/src/pages/settings/drive.vue
@@ -35,7 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<FormLink @click="chooseUploadFolder()">
 				{{ i18n.ts.uploadFolder }}
 				<template #suffix>{{ uploadFolder ? uploadFolder.name : '-' }}</template>
-				<template #suffixIcon><i class="ti ti-folder"></i></template>
+				<template #suffixIcon><i class="ph-folder ph-bold ph-lg"></i></template>
 			</FormLink>
 			<FormLink to="/settings/drive/cleaner">
 				{{ i18n.ts.drivecleaner }}
@@ -140,7 +140,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.drive,
-	icon: 'ti ti-cloud',
+	icon: 'ph-cloud ph-bold ph-lg',
 });
 </script>
 
@@ -148,12 +148,12 @@ definePageMetadata({
 .meter {
 	height: 10px;
 	background: rgba(0, 0, 0, 0.1);
-	border-radius: 999px;
+	border-radius: 4px;
 	overflow: clip;
 }
 
 .meterValue {
 	height: 100%;
-	border-radius: 999px;
+	border-radius: 4px;
 }
 </style>
diff --git a/packages/frontend/src/pages/settings/email.vue b/packages/frontend/src/pages/settings/email.vue
index 82b7f0ae4c..6e7d78292f 100644
--- a/packages/frontend/src/pages/settings/email.vue
+++ b/packages/frontend/src/pages/settings/email.vue
@@ -8,9 +8,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<FormSection first>
 		<template #label>{{ i18n.ts.emailAddress }}</template>
 		<MkInput v-model="emailAddress" type="email" manualSave>
-			<template #prefix><i class="ti ti-mail"></i></template>
+			<template #prefix><i class="ph-envelope ph-bold ph-lg"></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="ti ti-check" style="color: var(--success);"></i> {{ i18n.ts.emailVerified }}</template>
+			<template v-else-if="emailAddress === $i.email && $i.emailVerified" #caption><i class="ph-check ph-bold ph-lg" style="color: var(--success);"></i> {{ i18n.ts.emailVerified }}</template>
 		</MkInput>
 	</FormSection>
 
@@ -112,6 +112,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.email,
-	icon: 'ti ti-mail',
+	icon: 'ph-envelope ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue
index 771f43c66b..f497b2b320 100644
--- a/packages/frontend/src/pages/settings/general.vue
+++ b/packages/frontend/src/pages/settings/general.vue
@@ -20,9 +20,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<MkRadios v-model="overridedDeviceKind">
 		<template #label>{{ i18n.ts.overridedDeviceKind }}</template>
 		<option :value="null">{{ i18n.ts.auto }}</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>
+		<option value="smartphone"><i class="ph-device-mobile ph-bold ph-lg"/> {{ i18n.ts.smartphone }}</option>
+		<option value="tablet"><i class="ph-device-tablet ph-bold ph-lg"/> {{ i18n.ts.tablet }}</option>
+		<option value="desktop"><i class="ph-desktop ph-bold ph-lg"/> {{ i18n.ts.desktop }}</option>
 	</MkRadios>
 
 	<FormSection>
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<template #label>{{ i18n.ts.pinnedList }}</template>
 				<!-- 複数ピン止め管理できるようにしたいけどめんどいので一旦ひとつのみ -->
 				<MkButton v-if="defaultStore.reactiveState.pinnedUserLists.value.length === 0" @click="setPinnedList()">{{ i18n.ts.add }}</MkButton>
-				<MkButton v-else danger @click="removePinnedList()"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
+				<MkButton v-else danger @click="removePinnedList()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.remove }}</MkButton>
 			</MkFolder>
 		</div>
 	</FormSection>
@@ -91,16 +91,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div class="_gaps_m">
 			<MkRadios v-model="notificationPosition">
 				<template #label>{{ i18n.ts.position }}</template>
-				<option value="leftTop"><i class="ti ti-align-box-left-top"></i> {{ i18n.ts.leftTop }}</option>
-				<option value="rightTop"><i class="ti ti-align-box-right-top"></i> {{ i18n.ts.rightTop }}</option>
-				<option value="leftBottom"><i class="ti ti-align-box-left-bottom"></i> {{ i18n.ts.leftBottom }}</option>
-				<option value="rightBottom"><i class="ti ti-align-box-right-bottom"></i> {{ i18n.ts.rightBottom }}</option>
+				<option value="leftTop"><i class="ph-arrow-up-left ph-bold ph-lg"></i> {{ i18n.ts.leftTop }}</option>
+				<option value="rightTop"><i class="ph-arrow-up-right ph-bold ph-lg"></i> {{ i18n.ts.rightTop }}</option>
+				<option value="leftBottom"><i class="ph-arrow-down-left ph-bold ph-lg"></i> {{ i18n.ts.leftBottom }}</option>
+				<option value="rightBottom"><i class="ph-arrow-down-right ph-bold ph-lg"></i> {{ i18n.ts.rightBottom }}</option>
 			</MkRadios>
 
 			<MkRadios v-model="notificationStackAxis">
 				<template #label>{{ i18n.ts.stackAxis }}</template>
-				<option value="vertical"><i class="ti ti-carousel-vertical"></i> {{ i18n.ts.vertical }}</option>
-				<option value="horizontal"><i class="ti ti-carousel-horizontal"></i> {{ i18n.ts.horizontal }}</option>
+				<option value="vertical"><i class="ph-split-vertical ph-bold ph-lg"></i> {{ i18n.ts.vertical }}</option>
+				<option value="horizontal"><i class="ph-split-horizontal ph-bold ph-lg"></i> {{ i18n.ts.horizontal }}</option>
 			</MkRadios>
 
 			<MkButton @click="testNotification">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton>
@@ -172,12 +172,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkFolder>
 				<template #label>{{ i18n.ts.additionalEmojiDictionary }}</template>
 				<div v-for="lang in emojiIndexLangs" class="_buttons">
-					<MkButton @click="downloadEmojiIndex(lang)"><i class="ti ti-download"></i> {{ lang }}{{ defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton>
-					<MkButton v-if="defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
+					<MkButton @click="downloadEmojiIndex(lang)"><i class="ph-download ph-bold ph-lg"></i> {{ lang }}{{ defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton>
+					<MkButton v-if="defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.remove }}</MkButton>
 				</div>
 			</MkFolder>
 			<FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink>
-			<FormLink to="/settings/custom-css"><template #icon><i class="ti ti-code"></i></template>{{ i18n.ts.customCss }}</FormLink>
+			<FormLink to="/settings/custom-css"><template #icon><i class="ph-code ph-bold pg-lg"></i></template>{{ i18n.ts.customCss }}</FormLink>
 		</div>
 	</FormSection>
 </div>
@@ -370,6 +370,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.general,
-	icon: 'ti ti-adjustments',
+	icon: 'ph-faders ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/import-export.vue b/packages/frontend/src/pages/settings/import-export.vue
index 0574a878ae..24dcdeaccf 100644
--- a/packages/frontend/src/pages/settings/import-export.vue
+++ b/packages/frontend/src/pages/settings/import-export.vue
@@ -6,27 +6,27 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div class="_gaps_m">
 	<FormSection first>
-		<template #label><i class="ti ti-pencil"></i> {{ i18n.ts._exportOrImport.allNotes }}</template>
+		<template #label><i class="ph-pencil ph-bold ph-lg"></i> {{ i18n.ts._exportOrImport.allNotes }}</template>
 		<MkFolder>
 			<template #label>{{ i18n.ts.export }}</template>
-			<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>
+			<template #icon><i class="ph-download ph-bold ph-lg"></i></template>
+			<MkButton primary :class="$style.button" inline @click="exportNotes()"><i class="ph-download ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
 		</MkFolder>
 	</FormSection>
 	<FormSection>
-		<template #label><i class="ti ti-star"></i> {{ i18n.ts._exportOrImport.favoritedNotes }}</template>
+		<template #label><i class="ph-star ph-bold pg-lg"></i> {{ i18n.ts._exportOrImport.favoritedNotes }}</template>
 		<MkFolder>
 			<template #label>{{ i18n.ts.export }}</template>
-			<template #icon><i class="ti ti-download"></i></template>
-			<MkButton primary :class="$style.button" inline @click="exportFavorites()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
+			<template #icon><i class="ph-download ph-bold ph-lg"></i></template>
+			<MkButton primary :class="$style.button" inline @click="exportFavorites()"><i class="ph-download ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
 		</MkFolder>
 	</FormSection>
 	<FormSection>
-		<template #label><i class="ti ti-users"></i> {{ i18n.ts._exportOrImport.followingList }}</template>
+		<template #label><i class="ph-users ph-bold pg-lg"></i> {{ i18n.ts._exportOrImport.followingList }}</template>
 		<div class="_gaps_s">
 			<MkFolder>
 				<template #label>{{ i18n.ts.export }}</template>
-				<template #icon><i class="ti ti-download"></i></template>
+				<template #icon><i class="ph-download ph-bold ph-lg"></i></template>
 				<div class="_gaps_s">
 					<MkSwitch v-model="excludeMutingUsers">
 						{{ i18n.ts._exportOrImport.excludeMutingUsers }}
@@ -34,73 +34,73 @@ SPDX-License-Identifier: AGPL-3.0-only
 					<MkSwitch v-model="excludeInactiveUsers">
 						{{ i18n.ts._exportOrImport.excludeInactiveUsers }}
 					</MkSwitch>
-					<MkButton primary :class="$style.button" inline @click="exportFollowing()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
+					<MkButton primary :class="$style.button" inline @click="exportFollowing()"><i class="ph-download ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
 				</div>
 			</MkFolder>
 			<MkFolder v-if="$i && !$i.movedTo">
 				<template #label>{{ i18n.ts.import }}</template>
-				<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>
+				<template #icon><i class="ph-upload ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="importFollowing($event)"><i class="ph-upload ph-bold ph-lg"></i> {{ i18n.ts.import }}</MkButton>
 			</MkFolder>
 		</div>
 	</FormSection>
 	<FormSection>
-		<template #label><i class="ti ti-users"></i> {{ i18n.ts._exportOrImport.userLists }}</template>
+		<template #label><i class="ph-users ph-bold pg-lg"></i> {{ i18n.ts._exportOrImport.userLists }}</template>
 		<div class="_gaps_s">
 			<MkFolder>
 				<template #label>{{ i18n.ts.export }}</template>
-				<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>
+				<template #icon><i class="ph-download ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="exportUserLists()"><i class="ph-download ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
 			</MkFolder>
 			<MkFolder v-if="$i && !$i.movedTo">
 				<template #label>{{ i18n.ts.import }}</template>
-				<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>
+				<template #icon><i class="ph-upload ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="importUserLists($event)"><i class="ph-upload ph-bold ph-lg"></i> {{ i18n.ts.import }}</MkButton>
 			</MkFolder>
 		</div>
 	</FormSection>
 	<FormSection>
-		<template #label><i class="ti ti-user-off"></i> {{ i18n.ts._exportOrImport.muteList }}</template>
+		<template #label><i class="ph-user-minus ph-bold ph-lg"></i> {{ i18n.ts._exportOrImport.muteList }}</template>
 		<div class="_gaps_s">
 			<MkFolder>
 				<template #label>{{ i18n.ts.export }}</template>
-				<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>
+				<template #icon><i class="ph-download ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="exportMuting()"><i class="ph-download ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
 			</MkFolder>
 			<MkFolder v-if="$i && !$i.movedTo">
 				<template #label>{{ i18n.ts.import }}</template>
-				<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>
+				<template #icon><i class="ph-upload ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="importMuting($event)"><i class="ph-upload ph-bold ph-lg"></i> {{ i18n.ts.import }}</MkButton>
 			</MkFolder>
 		</div>
 	</FormSection>
 	<FormSection>
-		<template #label><i class="ti ti-user-off"></i> {{ i18n.ts._exportOrImport.blockingList }}</template>
+		<template #label><i class="ph-user-minus ph-bold ph-lg"></i> {{ i18n.ts._exportOrImport.blockingList }}</template>
 		<div class="_gaps_s">
 			<MkFolder>
 				<template #label>{{ i18n.ts.export }}</template>
-				<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>
+				<template #icon><i class="ph-download ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="exportBlocking()"><i class="ph-download ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
 			</MkFolder>
 			<MkFolder v-if="$i && !$i.movedTo">
 				<template #label>{{ i18n.ts.import }}</template>
-				<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>
+				<template #icon><i class="ph-upload ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="importBlocking($event)"><i class="ph-upload ph-bold ph-lg"></i> {{ i18n.ts.import }}</MkButton>
 			</MkFolder>
 		</div>
 	</FormSection>
 	<FormSection>
-		<template #label><i class="ti ti-antenna"></i> {{ i18n.ts.antennas }}</template>
+		<template #label><i class="ph-flying-saucer ph-bold pg-lg"></i> {{ i18n.ts.antennas }}</template>
 		<div class="_gaps_s">
 			<MkFolder>
 				<template #label>{{ i18n.ts.export }}</template>
-				<template #icon><i class="ti ti-download"></i></template>
-				<MkButton primary :class="$style.button" inline @click="exportAntennas()"><i class="ti ti-download"></i> {{ i18n.ts.export }}</MkButton>
+				<template #icon><i class="ph-download ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="exportAntennas()"><i class="ph-download ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
 			</MkFolder>
 			<MkFolder v-if="$i && !$i.movedTo">
 				<template #label>{{ i18n.ts.import }}</template>
-				<template #icon><i class="ti ti-upload"></i></template>
-				<MkButton primary :class="$style.button" inline @click="importAntennas($event)"><i class="ti ti-upload"></i> {{ i18n.ts.import }}</MkButton>
+				<template #icon><i class="ph-upload ph-bold ph-lg"></i></template>
+				<MkButton primary :class="$style.button" inline @click="importAntennas($event)"><i class="ph-upload ph-bold ph-lg"></i> {{ i18n.ts.import }}</MkButton>
 			</MkFolder>
 		</div>
 	</FormSection>
@@ -206,7 +206,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.importAndExport,
-	icon: 'ti ti-package',
+	icon: 'ph-package ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/settings/index.vue b/packages/frontend/src/pages/settings/index.vue
index f1bd501150..155577b0f8 100644
--- a/packages/frontend/src/pages/settings/index.vue
+++ b/packages/frontend/src/pages/settings/index.vue
@@ -42,7 +42,7 @@ import { fetchCustomEmojis } from '@/custom-emojis.js';
 
 const indexInfo = {
 	title: i18n.ts.settings,
-	icon: 'ti ti-settings',
+	icon: 'ph-gear ph-bold pg-lg',
 	hideHeader: true,
 };
 const INFO = ref(indexInfo);
@@ -64,37 +64,37 @@ const ro = new ResizeObserver((entries, observer) => {
 const menuDef = computed(() => [{
 	title: i18n.ts.basicSettings,
 	items: [{
-		icon: 'ti ti-user',
+		icon: 'ph-user ph-bold ph-lg',
 		text: i18n.ts.profile,
 		to: '/settings/profile',
 		active: currentPage?.route.name === 'profile',
 	}, {
-		icon: 'ti ti-lock-open',
+		icon: 'ph-lock ph-bold ph-lg-open',
 		text: i18n.ts.privacy,
 		to: '/settings/privacy',
 		active: currentPage?.route.name === 'privacy',
 	}, {
-		icon: 'ti ti-mood-happy',
+		icon: 'ph-smiley ph-bold ph-lg',
 		text: i18n.ts.reaction,
 		to: '/settings/reaction',
 		active: currentPage?.route.name === 'reaction',
 	}, {
-		icon: 'ti ti-cloud',
+		icon: 'ph-cloud ph-bold ph-lg',
 		text: i18n.ts.drive,
 		to: '/settings/drive',
 		active: currentPage?.route.name === 'drive',
 	}, {
-		icon: 'ti ti-bell',
+		icon: 'ph-bell ph-bold pg-lg',
 		text: i18n.ts.notifications,
 		to: '/settings/notifications',
 		active: currentPage?.route.name === 'notifications',
 	}, {
-		icon: 'ti ti-mail',
+		icon: 'ph-envelope ph-bold ph-lg',
 		text: i18n.ts.email,
 		to: '/settings/email',
 		active: currentPage?.route.name === 'email',
 	}, {
-		icon: 'ti ti-lock',
+		icon: 'ph-lock ph-bold ph-lg',
 		text: i18n.ts.security,
 		to: '/settings/security',
 		active: currentPage?.route.name === 'security',
@@ -102,32 +102,32 @@ const menuDef = computed(() => [{
 }, {
 	title: i18n.ts.clientSettings,
 	items: [{
-		icon: 'ti ti-adjustments',
+		icon: 'ph-faders ph-bold ph-lg',
 		text: i18n.ts.general,
 		to: '/settings/general',
 		active: currentPage?.route.name === 'general',
 	}, {
-		icon: 'ti ti-palette',
+		icon: 'ph-palette ph-bold ph-lg',
 		text: i18n.ts.theme,
 		to: '/settings/theme',
 		active: currentPage?.route.name === 'theme',
 	}, {
-		icon: 'ti ti-menu-2',
+		icon: 'ph-list ph-bold ph-lg-2',
 		text: i18n.ts.navbar,
 		to: '/settings/navbar',
 		active: currentPage?.route.name === 'navbar',
 	}, {
-		icon: 'ti ti-equal-double',
+		icon: 'ph-equals ph-bold ph-lg',
 		text: i18n.ts.statusbar,
 		to: '/settings/statusbar',
 		active: currentPage?.route.name === 'statusbar',
 	}, {
-		icon: 'ti ti-music',
+		icon: 'ph-music-notes ph-bold pg-lg',
 		text: i18n.ts.sounds,
 		to: '/settings/sounds',
 		active: currentPage?.route.name === 'sounds',
 	}, {
-		icon: 'ti ti-plug',
+		icon: 'ph-plug ph-bold ph-lg',
 		text: i18n.ts.plugins,
 		to: '/settings/plugin',
 		active: currentPage?.route.name === 'plugin',
@@ -135,60 +135,60 @@ const menuDef = computed(() => [{
 }, {
 	title: i18n.ts.otherSettings,
 	items: [{
-		icon: 'ti ti-badges',
+		icon: 'ph-seal-check ph-bold pg-lg',
 		text: i18n.ts.roles,
 		to: '/settings/roles',
 		active: currentPage?.route.name === 'roles',
 	}, {
-		icon: 'ti ti-planet-off',
+		icon: 'ph-prohibit ph-bold pg-lg',
 		text: i18n.ts.instanceMute,
 		to: '/settings/instance-mute',
 		active: currentPage?.route.name === 'instance-mute',
 	}, {
-		icon: 'ti ti-ban',
+		icon: 'ph-prohibit ph-bold ph-lg',
 		text: i18n.ts.muteAndBlock,
 		to: '/settings/mute-block',
 		active: currentPage?.route.name === 'mute-block',
 	}, {
-		icon: 'ti ti-message-off',
+		icon: 'ph-bell-slash ph-bold ph-lg',
 		text: i18n.ts.wordMute,
 		to: '/settings/word-mute',
 		active: currentPage?.route.name === 'word-mute',
 	}, {
-		icon: 'ti ti-api',
+		icon: 'ph-webhooks-logo ph-bold pg-lg',
 		text: 'API',
 		to: '/settings/api',
 		active: currentPage?.route.name === 'api',
 	}, {
-		icon: 'ti ti-webhook',
+		icon: 'ph-webhooks-logo ph-bold ph-lg',
 		text: 'Webhook',
 		to: '/settings/webhook',
 		active: currentPage?.route.name === 'webhook',
 	}, {
-		icon: 'ti ti-package',
+		icon: 'ph-package ph-bold ph-lg',
 		text: i18n.ts.importAndExport,
 		to: '/settings/import-export',
 		active: currentPage?.route.name === 'import-export',
 	}, {
-		icon: 'ti ti-plane',
+		icon: 'ph-airplane ph-bold ph-lg',
 		text: `${i18n.ts.accountMigration}`,
 		to: '/settings/migration',
 		active: currentPage?.route.name === 'migration',
 	}, {
-		icon: 'ti ti-dots',
+		icon: 'ph-dots-three ph-bold ph-lg',
 		text: i18n.ts.other,
 		to: '/settings/other',
 		active: currentPage?.route.name === 'other',
 	}],
 }, {
 	items: [{
-		icon: 'ti ti-device-floppy',
+		icon: 'ph-floppy-disk ph-bold pg-lg',
 		text: i18n.ts.preferencesBackups,
 		to: '/settings/preferences-backups',
 		active: currentPage?.route.name === 'preferences-backups',
 	}, {
 		type: 'button',
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		text: i18n.ts.clearCache,
 		action: async () => {
 			os.waiting();
@@ -201,7 +201,7 @@ const menuDef = computed(() => [{
 		},
 	}, {
 		type: 'button',
-		icon: 'ti ti-power',
+		icon: 'ph-power ph-bold ph-lg',
 		text: i18n.ts.logout,
 		action: async () => {
 			const { canceled } = await os.confirm({
diff --git a/packages/frontend/src/pages/settings/instance-mute.vue b/packages/frontend/src/pages/settings/instance-mute.vue
index b76fd2c906..e6c99423d1 100644
--- a/packages/frontend/src/pages/settings/instance-mute.vue
+++ b/packages/frontend/src/pages/settings/instance-mute.vue
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<template #label>{{ i18n.ts._instanceMute.heading }}</template>
 		<template #caption>{{ i18n.ts._instanceMute.instanceMuteDescription }}<br>{{ i18n.ts._instanceMute.instanceMuteDescription2 }}</template>
 	</MkTextarea>
-	<MkButton primary :disabled="!changed" @click="save()"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton primary :disabled="!changed" @click="save()"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
@@ -53,6 +53,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.instanceMute,
-	icon: 'ti ti-planet-off',
+	icon: 'ph-prohibit ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/migration.vue b/packages/frontend/src/pages/settings/migration.vue
index 15bf4691b2..3b47189eb4 100644
--- a/packages/frontend/src/pages/settings/migration.vue
+++ b/packages/frontend/src/pages/settings/migration.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div class="_gaps_m">
 	<MkFolder :defaultOpen="true">
-		<template #icon><i class="ti ti-plane-arrival"></i></template>
+		<template #icon><i class="ph-airplane-landing ph-bold ph-lg"></i></template>
 		<template #label>{{ i18n.ts._accountMigration.moveFrom }}</template>
 		<template #caption>{{ i18n.ts._accountMigration.moveFromSub }}</template>
 
@@ -15,12 +15,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 				{{ i18n.ts._accountMigration.moveFromDescription }}
 			</FormInfo>
 			<div>
-				<MkButton :disabled="accountAliases.length >= 10" inline style="margin-right: 8px;" @click="add"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
-				<MkButton inline primary @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+				<MkButton :disabled="accountAliases.length >= 10" inline style="margin-right: 8px;" @click="add"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
+				<MkButton inline primary @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 			</div>
 			<div class="_gaps">
 				<MkInput v-for="(_, i) in accountAliases" v-model="accountAliases[i]">
-					<template #prefix><i class="ti ti-plane-arrival"></i></template>
+					<template #prefix><i class="ph-airplane-landing ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.t('_accountMigration.moveFromLabel', { n: i + 1 }) }}</template>
 				</MkInput>
 			</div>
@@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkFolder>
 
 	<MkFolder :defaultOpen="!!$i?.movedTo">
-		<template #icon><i class="ti ti-plane-departure"></i></template>
+		<template #icon><i class="ph-airplane-takeoff ph-bold ph-lg"></i></template>
 		<template #label>{{ i18n.ts._accountMigration.moveTo }}</template>
 
 		<div class="_gaps_m">
@@ -39,11 +39,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<FormInfo warn>{{ i18n.ts._accountMigration.moveCannotBeUndone }}</FormInfo>
 
 				<MkInput v-model="moveToAccount">
-					<template #prefix><i class="ti ti-plane-departure"></i></template>
+					<template #prefix><i class="ph-airplane-takeoff ph-bold ph-lg"></i></template>
 					<template #label>{{ i18n.ts._accountMigration.moveToLabel }}</template>
 				</MkInput>
 				<MkButton inline danger :disabled="!moveToAccount" @click="move">
-					<i class="ti ti-check"></i> {{ i18n.ts._accountMigration.startMigration }}
+					<i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts._accountMigration.startMigration }}
 				</MkButton>
 			</template>
 			<template v-else-if="$i">
@@ -120,7 +120,7 @@ init();
 
 definePageMetadata({
 	title: i18n.ts.accountMigration,
-	icon: 'ti ti-plane',
+	icon: 'ph-airplane ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/settings/mute-block.vue b/packages/frontend/src/pages/settings/mute-block.vue
index 37d3d1773f..54f6237dd4 100644
--- a/packages/frontend/src/pages/settings/mute-block.vue
+++ b/packages/frontend/src/pages/settings/mute-block.vue
@@ -27,8 +27,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<MkA :class="$style.userItemMainBody" :to="userPage(item.mutee)">
 								<MkUserCardMini :user="item.mutee"/>
 							</MkA>
-							<button class="_button" :class="$style.userToggle" @click="toggleRenoteMuteItem(item)"><i :class="$style.chevron" class="ti ti-chevron-down"></i></button>
-							<button class="_button" :class="$style.remove" @click="unrenoteMute(item.mutee, $event)"><i class="ti ti-x"></i></button>
+							<button class="_button" :class="$style.userToggle" @click="toggleRenoteMuteItem(item)"><i :class="$style.chevron" class="ph-caret-down ph-bold ph-lg"></i></button>
+							<button class="_button" :class="$style.remove" @click="unrenoteMute(item.mutee, $event)"><i class="ph-x ph-bold ph-lg"></i></button>
 						</div>
 						<div v-if="expandedRenoteMuteItems.includes(item.id)" :class="$style.userItemSub">
 							<div>Muted at: <MkTime :time="item.createdAt" mode="detail"/></div>
@@ -55,8 +55,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<MkA :class="$style.userItemMainBody" :to="userPage(item.mutee)">
 								<MkUserCardMini :user="item.mutee"/>
 							</MkA>
-							<button class="_button" :class="$style.userToggle" @click="toggleMuteItem(item)"><i :class="$style.chevron" class="ti ti-chevron-down"></i></button>
-							<button class="_button" :class="$style.remove" @click="unmute(item.mutee, $event)"><i class="ti ti-x"></i></button>
+							<button class="_button" :class="$style.userToggle" @click="toggleMuteItem(item)"><i :class="$style.chevron" class="ph-caret-down ph-bold ph-lg"></i></button>
+							<button class="_button" :class="$style.remove" @click="unmute(item.mutee, $event)"><i class="ph-x ph-bold ph-lg"></i></button>
 						</div>
 						<div v-if="expandedMuteItems.includes(item.id)" :class="$style.userItemSub">
 							<div>Muted at: <MkTime :time="item.createdAt" mode="detail"/></div>
@@ -85,8 +85,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<MkA :class="$style.userItemMainBody" :to="userPage(item.blockee)">
 								<MkUserCardMini :user="item.blockee"/>
 							</MkA>
-							<button class="_button" :class="$style.userToggle" @click="toggleBlockItem(item)"><i :class="$style.chevron" class="ti ti-chevron-down"></i></button>
-							<button class="_button" :class="$style.remove" @click="unblock(item.blockee, $event)"><i class="ti ti-x"></i></button>
+							<button class="_button" :class="$style.userToggle" @click="toggleBlockItem(item)"><i :class="$style.chevron" class="ph-caret-down ph-bold ph-lg"></i></button>
+							<button class="_button" :class="$style.remove" @click="unblock(item.blockee, $event)"><i class="ph-x ph-bold ph-lg"></i></button>
 						</div>
 						<div v-if="expandedBlockItems.includes(item.id)" :class="$style.userItemSub">
 							<div>Blocked at: <MkTime :time="item.createdAt" mode="detail"/></div>
@@ -138,7 +138,7 @@ let expandedBlockItems = $ref([]);
 async function unrenoteMute(user, ev) {
 	os.popupMenu([{
 		text: i18n.ts.renoteUnmute,
-		icon: 'ti ti-x',
+		icon: 'ph-x ph-bold ph-lg',
 		action: async () => {
 			await os.apiWithDialog('renote-mute/delete', { userId: user.id });
 			//role.users = role.users.filter(u => u.id !== user.id);
@@ -149,7 +149,7 @@ async function unrenoteMute(user, ev) {
 async function unmute(user, ev) {
 	os.popupMenu([{
 		text: i18n.ts.unmute,
-		icon: 'ti ti-x',
+		icon: 'ph-x ph-bold ph-lg',
 		action: async () => {
 			await os.apiWithDialog('mute/delete', { userId: user.id });
 			//role.users = role.users.filter(u => u.id !== user.id);
@@ -160,7 +160,7 @@ async function unmute(user, ev) {
 async function unblock(user, ev) {
 	os.popupMenu([{
 		text: i18n.ts.unblock,
-		icon: 'ti ti-x',
+		icon: 'ph-x ph-bold ph-lg',
 		action: async () => {
 			await os.apiWithDialog('blocking/delete', { userId: user.id });
 			//role.users = role.users.filter(u => u.id !== user.id);
@@ -198,7 +198,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.muteAndBlock,
-	icon: 'ti ti-ban',
+	icon: 'ph-prohibit ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/settings/navbar.vue b/packages/frontend/src/pages/settings/navbar.vue
index c9cccd7dcb..44d6e12c6a 100644
--- a/packages/frontend/src/pages/settings/navbar.vue
+++ b/packages/frontend/src/pages/settings/navbar.vue
@@ -21,18 +21,18 @@ SPDX-License-Identifier: AGPL-3.0-only
 						v-if="element.type === '-' || navbarItemDef[element.type]"
 						:class="$style.item"
 					>
-						<button class="_button" :class="$style.itemHandle"><i class="ti ti-menu"></i></button>
+						<button class="_button" :class="$style.itemHandle"><i class="ph-list ph-bold ph-lg"></i></button>
 						<i class="ti-fw" :class="[$style.itemIcon, navbarItemDef[element.type]?.icon]"></i><span :class="$style.itemText">{{ navbarItemDef[element.type]?.title ?? i18n.ts.divider }}</span>
-						<button class="_button" :class="$style.itemRemove" @click="removeItem(index)"><i class="ti ti-x"></i></button>
+						<button class="_button" :class="$style.itemRemove" @click="removeItem(index)"><i class="ph-x ph-bold ph-lg"></i></button>
 					</div>
 				</template>
 			</Sortable>
 		</MkContainer>
 	</FormSlot>
 	<div class="_buttons">
-		<MkButton @click="addItem"><i class="ti ti-plus"></i> {{ i18n.ts.addItem }}</MkButton>
-		<MkButton danger @click="reset"><i class="ti ti-reload"></i> {{ i18n.ts.default }}</MkButton>
-		<MkButton primary class="save" @click="save"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+		<MkButton @click="addItem"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.addItem }}</MkButton>
+		<MkButton danger @click="reset"><i class="ph-arrow-clockwise ph-bold ph-lg"></i> {{ i18n.ts.default }}</MkButton>
+		<MkButton primary class="save" @click="save"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 	</div>
 
 	<MkRadios v-model="menuDisplay">
@@ -121,7 +121,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.navbar,
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue
index 5b3c29e7c8..94cff90e00 100644
--- a/packages/frontend/src/pages/settings/notifications.vue
+++ b/packages/frontend/src/pages/settings/notifications.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div class="_gaps_m">
-	<FormLink @click="configure"><template #icon><i class="ti ti-settings"></i></template>{{ i18n.ts.notificationSetting }}</FormLink>
+	<FormLink @click="configure"><template #icon><i class="ph-gear ph-bold pg-lg"></i></template>{{ i18n.ts.notificationSetting }}</FormLink>
 	<FormSection>
 		<div class="_gaps_m">
 			<FormLink @click="readAllNotifications">{{ i18n.ts.markAsReadAllNotifications }}</FormLink>
@@ -98,6 +98,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.notifications,
-	icon: 'ti ti-bell',
+	icon: 'ph-bell ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/other.vue b/packages/frontend/src/pages/settings/other.vue
index e2fc021099..60453d4bc4 100644
--- a/packages/frontend/src/pages/settings/other.vue
+++ b/packages/frontend/src/pages/settings/other.vue
@@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<FormSection first>
 		<div class="_gaps_s">
 			<MkFolder>
-				<template #icon><i class="ti ti-info-circle"></i></template>
+				<template #icon><i class="ph-info ph-bold ph-lg"></i></template>
 				<template #label>{{ i18n.ts.accountInfo }}</template>
 
 				<div class="_gaps_m">
@@ -35,7 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkFolder>
 
 			<MkFolder>
-				<template #icon><i class="ti ti-alert-triangle"></i></template>
+				<template #icon><i class="ph-warning ph-bold ph-lg"></i></template>
 				<template #label>{{ i18n.ts.closeAccount }}</template>
 
 				<div class="_gaps_m">
@@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkFolder>
 
 			<MkFolder>
-				<template #icon><i class="ti ti-flask"></i></template>
+				<template #icon><i class="ph-flask ph-bold ph-lg"></i></template>
 				<template #label>{{ i18n.ts.experimentalFeatures }}</template>
 
 				<div class="_gaps_m">
@@ -58,7 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkFolder>
 
 			<MkFolder>
-				<template #icon><i class="ti ti-code"></i></template>
+				<template #icon><i class="ph-code ph-bold pg-lg"></i></template>
 				<template #label>{{ i18n.ts.developer }}</template>
 
 				<div class="_gaps_m">
@@ -71,7 +71,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</FormSection>
 
 	<FormSection>
-		<FormLink to="/registry"><template #icon><i class="ti ti-adjustments"></i></template>{{ i18n.ts.registry }}</FormLink>
+		<FormLink to="/registry"><template #icon><i class="ph-faders ph-bold ph-lg"></i></template>{{ i18n.ts.registry }}</FormLink>
 	</FormSection>
 </div>
 </template>
@@ -150,6 +150,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.other,
-	icon: 'ti ti-dots',
+	icon: 'ph-dots-three ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/plugin.install.vue b/packages/frontend/src/pages/settings/plugin.install.vue
index 47ebe9cfd6..29ece72994 100644
--- a/packages/frontend/src/pages/settings/plugin.install.vue
+++ b/packages/frontend/src/pages/settings/plugin.install.vue
@@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkTextarea>
 
 	<div>
-		<MkButton :disabled="code == null" primary inline @click="install"><i class="ti ti-check"></i> {{ i18n.ts.install }}</MkButton>
+		<MkButton :disabled="code == null" primary inline @click="install"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.install }}</MkButton>
 	</div>
 </div>
 </template>
@@ -150,6 +150,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts._plugin.install,
-	icon: 'ti ti-download',
+	icon: 'ph-download ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/plugin.vue b/packages/frontend/src/pages/settings/plugin.vue
index 4a2d8d600e..24326ac40b 100644
--- a/packages/frontend/src/pages/settings/plugin.vue
+++ b/packages/frontend/src/pages/settings/plugin.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div class="_gaps_m">
-	<FormLink to="/settings/plugin/install"><template #icon><i class="ti ti-download"></i></template>{{ i18n.ts._plugin.install }}</FormLink>
+	<FormLink to="/settings/plugin/install"><template #icon><i class="ph-download ph-bold ph-lg"></i></template>{{ i18n.ts._plugin.install }}</FormLink>
 
 	<FormSection>
 		<template #label>{{ i18n.ts.manage }}</template>
@@ -37,17 +37,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</div>
 
 				<div class="_buttons">
-					<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>
+					<MkButton v-if="plugin.config" inline @click="config(plugin)"><i class="ph-gear ph-bold pg-lg"></i> {{ i18n.ts.settings }}</MkButton>
+					<MkButton inline danger @click="uninstall(plugin)"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.uninstall }}</MkButton>
 				</div>
 
 				<MkFolder>
-					<template #icon><i class="ti ti-code"></i></template>
+					<template #icon><i class="ph-code ph-bold pg-lg"></i></template>
 					<template #label>{{ i18n.ts._plugin.viewSource }}</template>
 
 					<div class="_gaps_s">
 						<div class="_buttons">
-							<MkButton inline @click="copy(plugin)"><i class="ti ti-copy"></i> {{ i18n.ts.copy }}</MkButton>
+							<MkButton inline @click="copy(plugin)"><i class="ph-copy ph-bold ph-lg"></i> {{ i18n.ts.copy }}</MkButton>
 						</div>
 
 						<MkCode :code="plugin.src ?? ''"/>
@@ -125,6 +125,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.plugins,
-	icon: 'ti ti-plug',
+	icon: 'ph-plug ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue
index 3b3a6bd07d..b347d9555e 100644
--- a/packages/frontend/src/pages/settings/preferences-backups.vue
+++ b/packages/frontend/src/pages/settings/preferences-backups.vue
@@ -377,25 +377,25 @@ function menu(ev: MouseEvent, profileId: string) {
 
 	return os.popupMenu([{
 		text: ts._preferencesBackups.apply,
-		icon: 'ti ti-check',
+		icon: 'ph-check ph-bold ph-lg',
 		action: () => applyProfile(profileId),
 	}, {
 		type: 'a',
 		text: ts.download,
-		icon: 'ti ti-download',
+		icon: 'ph-download ph-bold ph-lg',
 		href: URL.createObjectURL(new Blob([JSON.stringify(profiles.value[profileId], null, 2)], { type: 'application/json' })),
 		download: `${profiles.value[profileId].name}.json`,
 	}, null, {
 		text: ts.rename,
-		icon: 'ti ti-forms',
+		icon: 'ph-textbox ph-bold ph-lg',
 		action: () => rename(profileId),
 	}, {
 		text: ts._preferencesBackups.save,
-		icon: 'ti ti-device-floppy',
+		icon: 'ph-floppy-disk ph-bold pg-lg',
 		action: () => save(profileId),
 	}, null, {
 		text: ts.delete,
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		action: () => deleteProfile(profileId),
 		danger: true,
 	}], (ev.currentTarget ?? ev.target ?? undefined) as unknown as HTMLElement | undefined);
@@ -417,7 +417,7 @@ onUnmounted(() => {
 
 definePageMetadata(computed(() => ({
 	title: ts.preferencesBackups,
-	icon: 'ti ti-device-floppy',
+	icon: 'ph-floppy-disk ph-bold pg-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue
index d195b4142c..1ec8aee0a0 100644
--- a/packages/frontend/src/pages/settings/privacy.vue
+++ b/packages/frontend/src/pages/settings/privacy.vue
@@ -110,6 +110,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.privacy,
-	icon: 'ti ti-lock-open',
+	icon: 'ph-lock ph-bold ph-lg-open',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue
index 8c12fcf359..b6377d8b9b 100644
--- a/packages/frontend/src/pages/settings/profile.vue
+++ b/packages/frontend/src/pages/settings/profile.vue
@@ -24,17 +24,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<MkInput v-model="profile.location" manualSave>
 		<template #label>{{ i18n.ts.location }}</template>
-		<template #prefix><i class="ti ti-map-pin"></i></template>
+		<template #prefix><i class="ph-map-pin ph-bold ph-lg"></i></template>
 	</MkInput>
 
 	<MkInput v-model="profile.birthday" type="date" manualSave>
 		<template #label>{{ i18n.ts.birthday }}</template>
-		<template #prefix><i class="ti ti-cake"></i></template>
+		<template #prefix><i class="ph-cake ph-bold ph-lg"></i></template>
 	</MkInput>
 
 	<MkInput v-model="profile.listenbrainz" manualSave>
 		<template #label>ListenBrainz</template>
-		<template #prefix><i class="ti ti-headphones"></i></template>
+		<template #prefix><i class="ph-headphones ph-bold ph-lg"></i></template>
 	</MkInput>
 
 	<MkSelect v-model="profile.lang">
@@ -44,15 +44,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<FormSlot>
 		<MkFolder>
-			<template #icon><i class="ti ti-list"></i></template>
+			<template #icon><i class="ph-list ph-bold pg-lg"></i></template>
 			<template #label>{{ i18n.ts._profile.metadataEdit }}</template>
 
 			<div :class="$style.metadataRoot">
 				<div :class="$style.metadataMargin">
-					<MkButton :disabled="fields.length >= 16" inline style="margin-right: 8px;" @click="addField"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
-					<MkButton v-if="!fieldEditMode" :disabled="fields.length <= 1" inline danger style="margin-right: 8px;" @click="fieldEditMode = !fieldEditMode"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
-					<MkButton v-else inline style="margin-right: 8px;" @click="fieldEditMode = !fieldEditMode"><i class="ti ti-arrows-sort"></i> {{ i18n.ts.rearrange }}</MkButton>
-					<MkButton inline primary @click="saveFields"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+					<MkButton :disabled="fields.length >= 16" inline style="margin-right: 8px;" @click="addField"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.add }}</MkButton>
+					<MkButton v-if="!fieldEditMode" :disabled="fields.length <= 1" inline danger style="margin-right: 8px;" @click="fieldEditMode = !fieldEditMode"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
+					<MkButton v-else inline style="margin-right: 8px;" @click="fieldEditMode = !fieldEditMode"><i class="ph-arrows-down-up ph-bold ph-lg"></i> {{ i18n.ts.rearrange }}</MkButton>
+					<MkButton inline primary @click="saveFields"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 				</div>
 
 				<Sortable
@@ -66,8 +66,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 				>
 					<template #item="{element, index}">
 						<div :class="$style.fieldDragItem">
-							<button v-if="!fieldEditMode" class="_button" :class="$style.dragItemHandle" tabindex="-1"><i class="ti ti-menu"></i></button>
-							<button v-if="fieldEditMode" :disabled="fields.length <= 1" class="_button" :class="$style.dragItemRemove" @click="deleteField(index)"><i class="ti ti-x"></i></button>
+							<button v-if="!fieldEditMode" class="_button" :class="$style.dragItemHandle" tabindex="-1"><i class="ph-list ph-bold ph-lg"></i></button>
+							<button v-if="fieldEditMode" :disabled="fields.length <= 1" class="_button" :class="$style.dragItemRemove" @click="deleteField(index)"><i class="ph-x ph-bold ph-lg"></i></button>
 							<div :class="$style.dragItemForm">
 								<FormSplit :minWidth="200">
 									<MkInput v-model="element.name" small>
@@ -257,7 +257,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.profile,
-	icon: 'ti ti-user',
+	icon: 'ph-user ph-bold ph-lg',
 });
 </script>
 
@@ -267,7 +267,7 @@ definePageMetadata({
 	background-size: cover;
 	background-position: center;
 	border: solid 1px var(--divider);
-	border-radius: 10px;
+	border-radius: 5px;
 	overflow: clip;
 }
 
diff --git a/packages/frontend/src/pages/settings/reaction.vue b/packages/frontend/src/pages/settings/reaction.vue
index fb0f975212..12d37c9da2 100644
--- a/packages/frontend/src/pages/settings/reaction.vue
+++ b/packages/frontend/src/pages/settings/reaction.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="_gaps_m">
 	<FromSlot>
 		<template #label>{{ i18n.ts.reactionSettingDescription }}</template>
-		<div v-panel style="border-radius: 6px;">
+		<div v-panel style="border-radius: 5px;">
 			<Sortable v-model="reactions" :class="$style.reactions" :itemKey="item => item" :animation="150" :delay="100" :delayOnTouchOnly="true">
 				<template #item="{element}">
 					<button class="_button" :class="$style.reactionsItem" @click="remove(element, $event)">
@@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</button>
 				</template>
 				<template #footer>
-					<button class="_button" :class="$style.reactionsAdd" @click="chooseEmoji"><i class="ti ti-plus"></i></button>
+					<button class="_button" :class="$style.reactionsAdd" @click="chooseEmoji"><i class="ph-plus ph-bold ph-lg"></i></button>
 				</template>
 			</Sortable>
 		</div>
@@ -52,8 +52,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<FormSection>
 		<div class="_buttons">
-			<MkButton inline @click="preview"><i class="ti ti-eye"></i> {{ i18n.ts.preview }}</MkButton>
-			<MkButton inline danger @click="setDefault"><i class="ti ti-reload"></i> {{ i18n.ts.default }}</MkButton>
+			<MkButton inline @click="preview"><i class="ph-eye ph-bold ph-lg"></i> {{ i18n.ts.preview }}</MkButton>
+			<MkButton inline danger @click="setDefault"><i class="ph-arrow-clockwise ph-bold ph-lg"></i> {{ i18n.ts.default }}</MkButton>
 		</div>
 	</FormSection>
 </div>
@@ -132,9 +132,9 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.reaction,
-	icon: 'ti ti-mood-happy',
+	icon: 'ph-smiley ph-bold ph-lg',
 	action: {
-		icon: 'ti ti-eye',
+		icon: 'ph-eye ph-bold ph-lg',
 		handler: preview,
 	},
 });
diff --git a/packages/frontend/src/pages/settings/roles.vue b/packages/frontend/src/pages/settings/roles.vue
index 71238af72e..efa654226e 100644
--- a/packages/frontend/src/pages/settings/roles.vue
+++ b/packages/frontend/src/pages/settings/roles.vue
@@ -52,7 +52,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.roles,
-	icon: 'ti ti-badges',
+	icon: 'ph-seal-check ph-bold pg-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/settings/security.vue b/packages/frontend/src/pages/settings/security.vue
index eacd34778d..c07ad5117b 100644
--- a/packages/frontend/src/pages/settings/security.vue
+++ b/packages/frontend/src/pages/settings/security.vue
@@ -19,8 +19,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div>
 					<div v-for="item in items" :key="item.id" v-panel class="timnmucd">
 						<header>
-							<i v-if="item.success" class="ti ti-check icon succ"></i>
-							<i v-else class="ti ti-circle-x icon fail"></i>
+							<i v-if="item.success" class="ph-check ph-bold ph-lg icon succ"></i>
+							<i v-else class="ph-x-circle ph-bold ph-lg icon fail"></i>
 							<code class="ip _monospace">{{ item.ip }}</code>
 							<MkTime :time="item.createdAt" class="time"/>
 						</header>
@@ -32,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<FormSection>
 		<FormSlot>
-			<MkButton danger @click="regenerateToken"><i class="ti ti-refresh"></i> {{ i18n.ts.regenerateLoginToken }}</MkButton>
+			<MkButton danger @click="regenerateToken"><i class="ph-arrows-counter-clockwise ph-bold pg-lg"></i> {{ i18n.ts.regenerateLoginToken }}</MkButton>
 			<template #caption>{{ i18n.ts.regenerateLoginTokenDescription }}</template>
 		</FormSlot>
 	</FormSection>
@@ -103,7 +103,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.security,
-	icon: 'ti ti-lock',
+	icon: 'ph-lock ph-bold ph-lg',
 });
 </script>
 
diff --git a/packages/frontend/src/pages/settings/sounds.sound.vue b/packages/frontend/src/pages/settings/sounds.sound.vue
index 08a923e104..0de2c8c679 100644
--- a/packages/frontend/src/pages/settings/sounds.sound.vue
+++ b/packages/frontend/src/pages/settings/sounds.sound.vue
@@ -14,8 +14,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkRange>
 
 	<div class="_buttons">
-		<MkButton inline @click="listen"><i class="ti ti-player-play"></i> {{ i18n.ts.listen }}</MkButton>
-		<MkButton inline primary @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
+		<MkButton inline @click="listen"><i class="ph-play ph-bold pg-lg"></i> {{ i18n.ts.listen }}</MkButton>
+		<MkButton inline primary @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
 	</div>
 </div>
 </template>
diff --git a/packages/frontend/src/pages/settings/sounds.vue b/packages/frontend/src/pages/settings/sounds.vue
index b6ac17ed4f..8c5833af38 100644
--- a/packages/frontend/src/pages/settings/sounds.vue
+++ b/packages/frontend/src/pages/settings/sounds.vue
@@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 	</FormSection>
 
-	<MkButton danger @click="reset()"><i class="ti ti-reload"></i> {{ i18n.ts.default }}</MkButton>
+	<MkButton danger @click="reset()"><i class="ph-arrow-clockwise ph-bold ph-lg"></i> {{ i18n.ts.default }}</MkButton>
 </div>
 </template>
 
@@ -74,6 +74,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.sounds,
-	icon: 'ti ti-music',
+	icon: 'ph-music-notes ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/statusbar.vue b/packages/frontend/src/pages/settings/statusbar.vue
index 7103c2582a..02d678a2b4 100644
--- a/packages/frontend/src/pages/settings/statusbar.vue
+++ b/packages/frontend/src/pages/settings/statusbar.vue
@@ -51,6 +51,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.statusbar,
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/theme.install.vue b/packages/frontend/src/pages/settings/theme.install.vue
index 155ce9d9da..428dc16f63 100644
--- a/packages/frontend/src/pages/settings/theme.install.vue
+++ b/packages/frontend/src/pages/settings/theme.install.vue
@@ -10,8 +10,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkTextarea>
 
 	<div class="_buttons">
-		<MkButton :disabled="installThemeCode == null" inline @click="() => preview(installThemeCode)"><i class="ti ti-eye"></i> {{ i18n.ts.preview }}</MkButton>
-		<MkButton :disabled="installThemeCode == null" primary inline @click="() => install(installThemeCode)"><i class="ti ti-check"></i> {{ i18n.ts.install }}</MkButton>
+		<MkButton :disabled="installThemeCode == null" inline @click="() => preview(installThemeCode)"><i class="ph-eye ph-bold ph-lg"></i> {{ i18n.ts.preview }}</MkButton>
+		<MkButton :disabled="installThemeCode == null" primary inline @click="() => install(installThemeCode)"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.install }}</MkButton>
 	</div>
 </div>
 </template>
@@ -80,6 +80,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts._theme.install,
-	icon: 'ti ti-download',
+	icon: 'ph-download ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/theme.manage.vue b/packages/frontend/src/pages/settings/theme.manage.vue
index 8c90c175f0..484e83be4b 100644
--- a/packages/frontend/src/pages/settings/theme.manage.vue
+++ b/packages/frontend/src/pages/settings/theme.manage.vue
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<template #label>{{ i18n.ts._theme.code }}</template>
 			<template #caption><button class="_textButton" @click="copyThemeCode()">{{ i18n.ts.copy }}</button></template>
 		</MkTextarea>
-		<MkButton v-if="!builtinThemes.some(t => t.id == selectedTheme.id)" danger @click="uninstall()"><i class="ti ti-trash"></i> {{ i18n.ts.uninstall }}</MkButton>
+		<MkButton v-if="!builtinThemes.some(t => t.id == selectedTheme.id)" danger @click="uninstall()"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.uninstall }}</MkButton>
 	</template>
 </div>
 </template>
@@ -78,6 +78,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts._theme.manage,
-	icon: 'ti ti-tool',
+	icon: 'ph-wrench ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/theme.vue b/packages/frontend/src/pages/settings/theme.vue
index 9e55a8fd8d..1f67d37855 100644
--- a/packages/frontend/src/pages/settings/theme.vue
+++ b/packages/frontend/src/pages/settings/theme.vue
@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div class="selects">
 		<MkSelect v-model="lightThemeId" large class="select">
 			<template #label>{{ i18n.ts.themeForLightMode }}</template>
-			<template #prefix><i class="ti ti-sun"></i></template>
+			<template #prefix><i class="ph-sun ph-bold ph-lg"></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>
@@ -45,7 +45,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</MkSelect>
 		<MkSelect v-model="darkThemeId" large class="select">
 			<template #label>{{ i18n.ts.themeForDarkMode }}</template>
-			<template #prefix><i class="ti ti-moon"></i></template>
+			<template #prefix><i class="ph-moon ph-bold ph-lg"></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>
@@ -58,10 +58,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<FormSection>
 		<div class="_formLinksGrid">
-			<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>
+			<FormLink to="/settings/theme/manage"><template #icon><i class="ph-wrench ph-bold ph-lg"></i></template>{{ i18n.ts._theme.manage }}<template #suffix>{{ themesCount }}</template></FormLink>
+			<FormLink to="https://assets.misskey.io/theme/list" external><template #icon><i class="ph-globe-hemisphere-west ph-bold ph-lg"></i></template>{{ i18n.ts._theme.explore }}</FormLink>
+			<FormLink to="/settings/theme/install"><template #icon><i class="ph-download ph-bold ph-lg"></i></template>{{ i18n.ts._theme.install }}</FormLink>
+			<FormLink to="/theme-editor"><template #icon><i class="ph-paint-roller ph-bold ph-lg"></i></template>{{ i18n.ts._theme.make }}</FormLink>
 		</div>
 	</FormSection>
 
@@ -166,13 +166,13 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.theme,
-	icon: 'ti ti-palette',
+	icon: 'ph-palette ph-bold ph-lg',
 });
 </script>
 
 <style lang="scss" scoped>
 .rfqxtzch {
-	border-radius: 6px;
+	border-radius: 5px;
 
 	> .toggle {
 		position: relative;
diff --git a/packages/frontend/src/pages/settings/webhook.edit.vue b/packages/frontend/src/pages/settings/webhook.edit.vue
index 86b8f60c99..5353f60b0d 100644
--- a/packages/frontend/src/pages/settings/webhook.edit.vue
+++ b/packages/frontend/src/pages/settings/webhook.edit.vue
@@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkInput>
 
 	<MkInput v-model="secret">
-		<template #prefix><i class="ti ti-lock"></i></template>
+		<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 		<template #label>{{ i18n.ts._webhookSettings.secret }}</template>
 	</MkInput>
 
@@ -35,8 +35,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<MkSwitch v-model="active">{{ i18n.ts._webhookSettings.active }}</MkSwitch>
 
 	<div class="_buttons">
-		<MkButton primary inline @click="save"><i class="ti ti-check"></i> {{ i18n.ts.save }}</MkButton>
-		<MkButton danger inline @click="del"><i class="ti ti-trash"></i> {{ i18n.ts.delete }}</MkButton>
+		<MkButton primary inline @click="save"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.save }}</MkButton>
+		<MkButton danger inline @click="del"><i class="ph-trash ph-bold ph-lg"></i> {{ i18n.ts.delete }}</MkButton>
 	</div>
 </div>
 </template>
@@ -114,6 +114,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'Edit webhook',
-	icon: 'ti ti-webhook',
+	icon: 'ph-webhooks-logo ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/webhook.new.vue b/packages/frontend/src/pages/settings/webhook.new.vue
index ed56126548..f08f143d46 100644
--- a/packages/frontend/src/pages/settings/webhook.new.vue
+++ b/packages/frontend/src/pages/settings/webhook.new.vue
@@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</MkInput>
 
 	<MkInput v-model="secret">
-		<template #prefix><i class="ti ti-lock"></i></template>
+		<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 		<template #label>{{ i18n.ts._webhookSettings.secret }}</template>
 	</MkInput>
 
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</FormSection>
 
 	<div class="_buttons">
-		<MkButton primary inline @click="create"><i class="ti ti-check"></i> {{ i18n.ts.create }}</MkButton>
+		<MkButton primary inline @click="create"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.create }}</MkButton>
 	</div>
 </div>
 </template>
@@ -84,6 +84,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'Create new webhook',
-	icon: 'ti ti-webhook',
+	icon: 'ph-webhooks-logo ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/webhook.vue b/packages/frontend/src/pages/settings/webhook.vue
index 33841d7f8d..e9a7f9a02e 100644
--- a/packages/frontend/src/pages/settings/webhook.vue
+++ b/packages/frontend/src/pages/settings/webhook.vue
@@ -15,10 +15,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<div class="_gaps">
 					<FormLink v-for="webhook in items" :key="webhook.id" :to="`/settings/webhook/edit/${webhook.id}`">
 						<template #icon>
-							<i v-if="webhook.active === false" class="ti ti-player-pause"></i>
-							<i v-else-if="webhook.latestStatus === null" class="ti ti-circle"></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>
+							<i v-if="webhook.active === false" class="ph-pause ph-bold ph-lg"></i>
+							<i v-else-if="webhook.latestStatus === null" class="ph-circle ph-bold ph-lg"></i>
+							<i v-else-if="[200, 201, 204].includes(webhook.latestStatus)" class="ph-check ph-bold ph-lg" :style="{ color: 'var(--success)' }"></i>
+							<i v-else class="ph-warning ph-bold ph-lg" :style="{ color: 'var(--error)' }"></i>
 						</template>
 						{{ webhook.name || webhook.url }}
 						<template #suffix>
@@ -52,6 +52,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: 'Webhook',
-	icon: 'ti ti-webhook',
+	icon: 'ph-webhooks-logo ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/settings/word-mute.vue b/packages/frontend/src/pages/settings/word-mute.vue
index 1fefbdc92b..cfac5a4fd1 100644
--- a/packages/frontend/src/pages/settings/word-mute.vue
+++ b/packages/frontend/src/pages/settings/word-mute.vue
@@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkKeyValue>
 		</div>
 	</div>
-	<MkButton primary inline :disabled="!changed" @click="save()"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
+	<MkButton primary inline :disabled="!changed" @click="save()"><i class="ph-floppy-disk ph-bold pg-lg"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
@@ -128,6 +128,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.wordMute,
-	icon: 'ti ti-message-off',
+	icon: 'ph-bell-slash ph-bold ph-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/share.vue b/packages/frontend/src/pages/share.vue
index d66457e823..ed08bb1330 100644
--- a/packages/frontend/src/pages/share.vue
+++ b/packages/frontend/src/pages/share.vue
@@ -168,6 +168,6 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.share,
-	icon: 'ti ti-share',
+	icon: 'ph-share-network ph-bold pg-lg',
 });
 </script>
diff --git a/packages/frontend/src/pages/signup-complete.vue b/packages/frontend/src/pages/signup-complete.vue
index e9c89fa3bb..4ebd0e15b3 100644
--- a/packages/frontend/src/pages/signup-complete.vue
+++ b/packages/frontend/src/pages/signup-complete.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div :class="$style.formContainer">
 		<form :class="$style.form" class="_panel" @submit.prevent="submit()">
 			<div :class="$style.banner">
-				<i class="ti ti-user-check"></i>
+				<i class="ph-check ph-bold ph-lg"></i>
 			</div>
 			<div class="_gaps_m" style="padding: 32px;">
 				<div>{{ i18n.t('clickToFinishEmailVerification', { ok: i18n.ts.gotIt }) }}</div>
diff --git a/packages/frontend/src/pages/tag.vue b/packages/frontend/src/pages/tag.vue
index 85c571ecd6..7ac485685e 100644
--- a/packages/frontend/src/pages/tag.vue
+++ b/packages/frontend/src/pages/tag.vue
@@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template v-if="$i" #footer>
 		<div :class="$style.footer">
 			<MkSpacer :contentMax="800" :marginMin="16" :marginMax="16">
-				<MkButton rounded primary :class="$style.button" @click="post()"><i class="ti ti-pencil"></i>{{ i18n.ts.postToHashtag }}</MkButton>
+				<MkButton rounded primary :class="$style.button" @click="post()"><i class="ph-pencil ph-bold ph-lg"></i>{{ i18n.ts.postToHashtag }}</MkButton>
 			</MkSpacer>
 		</div>
 	</template>
@@ -57,7 +57,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => ({
 	title: props.tag,
-	icon: 'ti ti-hash',
+	icon: 'ph-hash ph-bold ph-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/theme-editor.vue b/packages/frontend/src/pages/theme-editor.vue
index 740fd5c4eb..80a5946180 100644
--- a/packages/frontend/src/pages/theme-editor.vue
+++ b/packages/frontend/src/pages/theme-editor.vue
@@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</MkFolder>
 
 			<MkFolder :defaultOpen="false">
-				<template #icon><i class="ti ti-code"></i></template>
+				<template #icon><i class="ph-code ph-bold pg-lg"></i></template>
 				<template #label>{{ i18n.ts.editCode }}</template>
 
 				<div class="_gaps_m">
@@ -215,12 +215,12 @@ watch($$(theme), apply, { deep: true });
 
 const headerActions = $computed(() => [{
 	asFullButton: true,
-	icon: 'ti ti-eye',
+	icon: 'ph-eye ph-bold ph-lg',
 	text: i18n.ts.preview,
 	handler: showPreview,
 }, {
 	asFullButton: true,
-	icon: 'ti ti-check',
+	icon: 'ph-check ph-bold ph-lg',
 	text: i18n.ts.saveAs,
 	handler: saveAs,
 }]);
@@ -229,7 +229,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata({
 	title: i18n.ts.themeEditor,
-	icon: 'ti ti-palette',
+	icon: 'ph-palette ph-bold ph-lg',
 });
 </script>
 
@@ -244,7 +244,7 @@ definePageMetadata({
 				position: relative;
 				width: 64px;
 				height: 64px;
-				border-radius: 8px;
+				border-radius: 5px;
 
 				> .preview {
 					position: absolute;
@@ -271,10 +271,10 @@ definePageMetadata({
 				}
 
 				&.rounded {
-					border-radius: 999px;
+					border-radius: 4px;
 
 					> .preview {
-						border-radius: 999px;
+						border-radius: 4px;
 					}
 				}
 
diff --git a/packages/frontend/src/pages/timeline.tutorial.vue b/packages/frontend/src/pages/timeline.tutorial.vue
index 66b8e796e5..fb085fcd30 100644
--- a/packages/frontend/src/pages/timeline.tutorial.vue
+++ b/packages/frontend/src/pages/timeline.tutorial.vue
@@ -6,14 +6,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div :class="$style.container">
 	<div :class="$style.title">
-		<div :class="$style.titleText"><i class="ti ti-info-circle"></i> {{ i18n.ts._timelineTutorial.title }}</div>
+		<div :class="$style.titleText"><i class="ph-info ph-bold ph-lg"></i> {{ i18n.ts._timelineTutorial.title }}</div>
 		<div :class="$style.step">
 			<button class="_button" :class="$style.stepArrow" :disabled="tutorial === 0" @click="tutorial--">
-				<i class="ti ti-chevron-left"></i>
+				<i class="ph-caret-left ph-bold ph-lg"></i>
 			</button>
 			<span :class="$style.stepNumber">{{ tutorial + 1 }} / {{ tutorialsNumber }}</span>
 			<button class="_button" :class="$style.stepArrow" :disabled="tutorial === tutorialsNumber - 1" @click="tutorial++">
-				<i class="ti ti-chevron-right"></i>
+				<i class="ph-caret-right ph-bold ph-lg"></i>
 			</button>
 		</div>
 	</div>
@@ -37,10 +37,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<div :class="$style.footer">
 		<template v-if="tutorial === tutorialsNumber - 1">
-			<MkButton :class="$style.footerItem" primary rounded gradate @click="tutorial = -1">{{ i18n.ts.done }} <i class="ti ti-check"></i></MkButton>
+			<MkButton :class="$style.footerItem" primary rounded gradate @click="tutorial = -1">{{ i18n.ts.done }} <i class="ph-check ph-bold ph-lg"></i></MkButton>
 		</template>
 		<template v-else>
-			<MkButton :class="$style.footerItem" primary rounded gradate @click="tutorial++">{{ i18n.ts.next }} <i class="ti ti-arrow-right"></i></MkButton>
+			<MkButton :class="$style.footerItem" primary rounded gradate @click="tutorial++">{{ i18n.ts.next }} <i class="ph-arrow-right ph-bold pg-lg"></i></MkButton>
 		</template>
 	</div>
 </div>
diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue
index 5fc43dc650..962a3aa4e4 100644
--- a/packages/frontend/src/pages/timeline.vue
+++ b/packages/frontend/src/pages/timeline.vue
@@ -134,18 +134,18 @@ function focus(): void {
 }
 
 const headerActions = $computed(() => [{
-	icon: 'ti ti-dots',
+	icon: 'ph-dots-three ph-bold ph-lg',
 	text: i18n.ts.options,
 	handler: (ev) => {
 		os.popupMenu([{
 			type: 'switch',
 			text: i18n.ts.showRenotes,
-			icon: 'ti ti-repeat',
+			icon: 'ph-repeat ph-bold ph-lg',
 			ref: $$(withRenotes),
 		}, {
 			type: 'switch',
 			text: i18n.ts.withReplies,
-			icon: 'ti ti-arrow-back-up',
+			icon: 'ph-arrow-u-up-left ph-bold pg-lg',
 			ref: $$(withReplies),
 		}], ev.currentTarget ?? ev.target);
 	},
@@ -154,40 +154,40 @@ const headerActions = $computed(() => [{
 const headerTabs = $computed(() => [...(defaultStore.reactiveState.pinnedUserLists.value.map(l => ({
 	key: 'list:' + l.id,
 	title: l.name,
-	icon: 'ti ti-star',
+	icon: 'ph-star ph-bold pg-lg',
 	iconOnly: true,
 }))), {
 	key: 'home',
 	title: i18n.ts._timelines.home,
-	icon: 'ti ti-home',
+	icon: 'ph-house ph-bold ph-lg',
 	iconOnly: true,
 }, ...(isLocalTimelineAvailable ? [{
 	key: 'local',
 	title: i18n.ts._timelines.local,
-	icon: 'ti ti-planet',
+	icon: 'ph-planet ph-bold pg-lg',
 	iconOnly: true,
 }, {
 	key: 'social',
 	title: i18n.ts._timelines.social,
-	icon: 'ti ti-rocket',
+	icon: 'ph-rocket-launch ph-bold pg-lg',
 	iconOnly: true,
 }] : []), ...(isGlobalTimelineAvailable ? [{
 	key: 'global',
 	title: i18n.ts._timelines.global,
-	icon: 'ti ti-whirl',
+	icon: 'ph-globe-hemisphere-west ph-bold ph-lg',
 	iconOnly: true,
 }] : []), {
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 	title: i18n.ts.lists,
 	iconOnly: true,
 	onClick: chooseList,
 }, {
-	icon: 'ti ti-antenna',
+	icon: 'ph-flying-saucer ph-bold pg-lg',
 	title: i18n.ts.antennas,
 	iconOnly: true,
 	onClick: chooseAntenna,
 }, {
-	icon: 'ti ti-device-tv',
+	icon: 'ph-television ph-bold ph-lg',
 	title: i18n.ts.channel,
 	iconOnly: true,
 	onClick: chooseChannel,
@@ -197,20 +197,20 @@ const headerTabsWhenNotLogin = $computed(() => [
 	...(isLocalTimelineAvailable ? [{
 		key: 'local',
 		title: i18n.ts._timelines.local,
-		icon: 'ti ti-planet',
+		icon: 'ph-planet ph-bold pg-lg',
 		iconOnly: true,
 	}] : []),
 	...(isGlobalTimelineAvailable ? [{
 		key: 'global',
 		title: i18n.ts._timelines.global,
-		icon: 'ti ti-whirl',
+		icon: 'ph-globe-hemisphere-west ph-bold ph-lg',
 		iconOnly: true,
 	}] : []),
 ] as Tab[]);
 
 definePageMetadata(computed(() => ({
 	title: i18n.ts.timeline,
-	icon: src === 'local' ? 'ti ti-planet' : src === 'social' ? 'ti ti-rocket' : src === 'global' ? 'ti ti-whirl' : 'ti ti-home',
+	icon: src === 'local' ? 'ph-planet ph-bold pg-lg' : src === 'social' ? 'ph-rocket-launch ph-bold pg-lg' : src === 'global' ? 'ph-globe-hemisphere-west ph-bold ph-lg' : 'ph-house ph-bold ph-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/user-list-timeline.vue b/packages/frontend/src/pages/user-list-timeline.vue
index 83244876fe..b2e18fc5ed 100644
--- a/packages/frontend/src/pages/user-list-timeline.vue
+++ b/packages/frontend/src/pages/user-list-timeline.vue
@@ -71,11 +71,11 @@ async function timetravel() {
 }
 
 const headerActions = $computed(() => list ? [{
-	icon: 'ti ti-calendar-time',
+	icon: 'ph-calendar ph-bold ph-lg',
 	text: i18n.ts.jumpToSpecifiedDate,
 	handler: timetravel,
 }, {
-	icon: 'ti ti-settings',
+	icon: 'ph-gear ph-bold pg-lg',
 	text: i18n.ts.settings,
 	handler: settings,
 }] : []);
@@ -84,7 +84,7 @@ const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => list ? {
 	title: list.name,
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 } : null));
 </script>
 
diff --git a/packages/frontend/src/pages/user-tag.vue b/packages/frontend/src/pages/user-tag.vue
index 71f8d31924..21ad7e7e5e 100644
--- a/packages/frontend/src/pages/user-tag.vue
+++ b/packages/frontend/src/pages/user-tag.vue
@@ -37,7 +37,7 @@ const tagUsers = $computed(() => ({
 
 definePageMetadata(computed(() => ({
 	title: props.tag,
-	icon: 'ti ti-user-search',
+	icon: 'ph-user-circle ph-bold ph-lg',
 })));
 </script>
 
diff --git a/packages/frontend/src/pages/user/activity.vue b/packages/frontend/src/pages/user/activity.vue
index 6703890893..45eb2f72aa 100644
--- a/packages/frontend/src/pages/user/activity.vue
+++ b/packages/frontend/src/pages/user/activity.vue
@@ -7,19 +7,19 @@ SPDX-License-Identifier: AGPL-3.0-only
 <MkSpacer :contentMax="700">
 	<div class="_gaps">
 		<MkFoldableSection class="item">
-			<template #header><i class="ti ti-activity"></i> Heatmap</template>
+			<template #header><i class="ph-pulse ph-bold ph-lg"></i> Heatmap</template>
 			<XHeatmap :user="user" :src="'notes'"/>
 		</MkFoldableSection>
 		<MkFoldableSection class="item">
-			<template #header><i class="ti ti-pencil"></i> Notes</template>
+			<template #header><i class="ph-pencil ph-bold ph-lg"></i> Notes</template>
 			<XNotes :user="user"/>
 		</MkFoldableSection>
 		<MkFoldableSection class="item">
-			<template #header><i class="ti ti-users"></i> Following</template>
+			<template #header><i class="ph-users ph-bold pg-lg"></i> Following</template>
 			<XFollowing :user="user"/>
 		</MkFoldableSection>
 		<MkFoldableSection class="item">
-			<template #header><i class="ti ti-eye"></i> PV</template>
+			<template #header><i class="ph-eye ph-bold ph-lg"></i> PV</template>
 			<XPv :user="user"/>
 		</MkFoldableSection>
 	</div>
diff --git a/packages/frontend/src/pages/user/followers.vue b/packages/frontend/src/pages/user/followers.vue
index b744f6aeec..b41edc74a1 100644
--- a/packages/frontend/src/pages/user/followers.vue
+++ b/packages/frontend/src/pages/user/followers.vue
@@ -53,7 +53,7 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => user ? {
-	icon: 'ti ti-user',
+	icon: 'ph-user ph-bold ph-lg',
 	title: user.name ? `${user.name} (@${user.username})` : `@${user.username}`,
 	subtitle: i18n.ts.followers,
 	userName: user,
diff --git a/packages/frontend/src/pages/user/following.vue b/packages/frontend/src/pages/user/following.vue
index 52f5207119..ba5ddafbdb 100644
--- a/packages/frontend/src/pages/user/following.vue
+++ b/packages/frontend/src/pages/user/following.vue
@@ -53,7 +53,7 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => []);
 
 definePageMetadata(computed(() => user ? {
-	icon: 'ti ti-user',
+	icon: 'ph-user ph-bold ph-lg',
 	title: user.name ? `${user.name} (@${user.username})` : `@${user.username}`,
 	subtitle: i18n.ts.following,
 	userName: user,
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index 1d8c9957d0..a29574959d 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -8,8 +8,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div ref="rootEl" class="ftskorzw" :class="{ wide: !narrow }" style="container-type: inline-size;">
 		<div class="main _gaps">
 			<!-- TODO -->
-			<!-- <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="punished" v-if="user.isSuspended"><i class="ph-warning ph-bold ph-lg" style="margin-right: 8px;"></i> {{ i18n.ts.userSuspended }}</div> -->
+			<!-- <div class="punished" v-if="user.isSilenced"><i class="ph-warning ph-bold ph-lg" style="margin-right: 8px;"></i> {{ i18n.ts.userSilenced }}</div> -->
 
 			<div class="profile _gaps">
 				<MkAccountMoved v-if="user.movedTo" :movedTo="user.movedTo"/>
@@ -23,17 +23,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<MkUserName class="name" :user="user" :nowrap="true"/>
 							<div class="bottom">
 								<span class="username"><MkAcct :user="user" :detail="true"/></span>
-								<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--badge);"><i class="ti ti-shield"></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="ti ti-robot"></i></span>
+								<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--badge);"><i class="ph-shield ph-bold ph-lg"></i></span>
+								<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="ph-lock ph-bold ph-lg"></i></span>
+								<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ph-robot ph-bold ph-lg"></i></span>
 								<button v-if="!isEditingMemo && !memoDraft" class="_button add-note-button" @click="showMemoTextarea">
-									<i class="ti ti-edit"/> {{ i18n.ts.addMemo }}
+									<i class="ph-pencil-line ph-bold pg-lg"/> {{ i18n.ts.addMemo }}
 								</button>
 							</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="ti ti-dots"></i></button>
+							<button class="menu _button" @click="menu"><i class="ph-dots-three ph-bold ph-lg"></i></button>
 							<MkFollowButton v-if="$i.id != user.id" :user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/>
 						</div>
 					</div>
@@ -42,9 +42,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<MkUserName :user="user" :nowrap="false" class="name"/>
 						<div class="bottom">
 							<span class="username"><MkAcct :user="user" :detail="true"/></span>
-							<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--badge);"><i class="ti ti-shield"></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="ti ti-robot"></i></span>
+							<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--badge);"><i class="ph-shield ph-bold ph-lg"></i></span>
+							<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="ph-lock ph-bold ph-lg"></i></span>
+							<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ph-robot ph-bold ph-lg"></i></span>
 						</div>
 					</div>
 					<div v-if="user.roles.length > 0" class="roles">
@@ -82,15 +82,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</div>
 					<div class="fields system">
 						<dl v-if="user.location" class="field">
-							<dt class="name"><i class="ti ti-map-pin ti-fw"></i> {{ i18n.ts.location }}</dt>
+							<dt class="name"><i class="ph-map-pin ph-bold ph-lg 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="ti ti-cake ti-fw"></i> {{ i18n.ts.birthday }}</dt>
+							<dt class="name"><i class="ph-cake ph-bold ph-lg ti-fw"></i> {{ i18n.ts.birthday }}</dt>
 							<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ i18n.t('yearsOld', { age }) }})</dd>
 						</dl>
 						<dl class="field">
-							<dt class="name"><i class="ti ti-calendar ti-fw"></i> {{ i18n.ts.registeredDate }}</dt>
+							<dt class="name"><i class="ph-calendar ph-bold ph-lg ti-fw"></i> {{ i18n.ts.registeredDate }}</dt>
 							<dd class="value">{{ dateString(user.createdAt) }} (<MkTime :time="user.createdAt"/>)</dd>
 						</dl>
 					</div>
@@ -101,7 +101,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 							</dt>
 							<dd class="value">
 								<Mfm :text="field.value" :author="user" :i="$i" :colored="false"/>
-								<i v-if="user.verifiedLinks.includes(field.value)" v-tooltip:dialog="i18n.ts.verifiedLink" class="ti ti-circle-check" :class="$style.verifiedLink"></i>
+								<i v-if="user.verifiedLinks.includes(field.value)" v-tooltip:dialog="i18n.ts.verifiedLink" class="ph-seal-check ph-bold ph-lg" :class="$style.verifiedLink"></i>
 							</dd>
 						</dl>
 					</div>
@@ -385,7 +385,7 @@ onUnmounted(() => {
 						color: #fff;
 						background: rgba(0, 0, 0, 0.7);
 						font-size: 0.7em;
-						border-radius: 6px;
+						border-radius: 5px;
 					}
 
 					> .actions {
@@ -492,7 +492,7 @@ onUnmounted(() => {
 
 					> .role {
 						border: solid 1px var(--color, var(--divider));
-						border-radius: 999px;
+						border-radius: 4px;
 						margin-right: 4px;
 						padding: 3px 8px;
 					}
@@ -507,7 +507,7 @@ onUnmounted(() => {
 					background: transparent;
 					color: var(--fg);
 					border: 1px solid var(--divider);
-					border-radius: 8px;
+					border-radius: 5px;
 					padding: 8px;
 					line-height: 0;
 
@@ -713,9 +713,9 @@ onUnmounted(() => {
 	margin: calc(var(--margin) / 2) 0;
 	padding: calc(var(--margin) / 2) 0;
 	background: var(--bg);
-	border-radius: 8px;
+	border-radius: 5px;
 	> button {
-		border-radius: 8px;
+		border-radius: 5px;
 		margin-left: 0.4rem;
 		margin-right: 0.4rem;
 	}
diff --git a/packages/frontend/src/pages/user/index.activity.vue b/packages/frontend/src/pages/user/index.activity.vue
index c531bda598..52311fca73 100644
--- a/packages/frontend/src/pages/user/index.activity.vue
+++ b/packages/frontend/src/pages/user/index.activity.vue
@@ -5,11 +5,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer>
-	<template #icon><i class="ti ti-chart-line"></i></template>
+	<template #icon><i class="ph-chart-line ph-bold pg-lg"></i></template>
 	<template #header>{{ i18n.ts.activity }}</template>
 	<template #func="{ buttonStyleClass }">
 		<button class="_button" :class="buttonStyleClass" @click="showMenu">
-			<i class="ti ti-dots"></i>
+			<i class="ph-dots-three ph-bold ph-lg"></i>
 		</button>
 	</template>
 
diff --git a/packages/frontend/src/pages/user/index.listenbrainz.vue b/packages/frontend/src/pages/user/index.listenbrainz.vue
index afc5cd2c2a..ff51b09027 100644
--- a/packages/frontend/src/pages/user/index.listenbrainz.vue
+++ b/packages/frontend/src/pages/user/index.listenbrainz.vue
@@ -2,7 +2,7 @@
 	<MkContainer :foldable="true">
 		<template #header
 			><i
-				class="ti ti-headphones"
+				class="ph-headphones ph-bold ph-lg"
 				style="margin-right: 0.5em"
 			></i
 			>Music</template
@@ -19,7 +19,7 @@
 				</a>
 				<a :href="listenbrainz.listenbrainzurl">
 					<div class="playicon">
-						<i class="ti ti-player-play-filled"></i>
+						<i class="ph-play ph-bold pg-lg-filled"></i>
 					</div>
 				</a>
 			</div>
diff --git a/packages/frontend/src/pages/user/index.photos.vue b/packages/frontend/src/pages/user/index.photos.vue
index b6cae9f131..383261d890 100644
--- a/packages/frontend/src/pages/user/index.photos.vue
+++ b/packages/frontend/src/pages/user/index.photos.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :max-height="300" :foldable="true">
-	<template #icon><i class="ti ti-photo"></i></template>
+	<template #icon><i class="ph-image-square ph-bold ph-lg"></i></template>
 	<template #header>{{ i18n.ts.images }}</template>
 	<div :class="$style.root">
 		<MkLoading v-if="fetching"/>
@@ -93,7 +93,7 @@ onMounted(() => {
 
 .img {
 	height: 128px;
-	border-radius: 6px;
+	border-radius: 5px;
 	overflow: clip;
 }
 
diff --git a/packages/frontend/src/pages/user/index.vue b/packages/frontend/src/pages/user/index.vue
index 7550d5bcb2..c352a04ed9 100644
--- a/packages/frontend/src/pages/user/index.vue
+++ b/packages/frontend/src/pages/user/index.vue
@@ -75,47 +75,47 @@ const headerActions = $computed(() => []);
 const headerTabs = $computed(() => user ? [{
 	key: 'home',
 	title: i18n.ts.overview,
-	icon: 'ti ti-home',
+	icon: 'ph-house ph-bold ph-lg',
 }, {
 	key: 'notes',
 	title: i18n.ts.notes,
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 }, {
 	key: 'activity',
 	title: i18n.ts.activity,
-	icon: 'ti ti-chart-line',
+	icon: 'ph-chart-line ph-bold pg-lg',
 }, ...(user.host == null ? [{
 	key: 'achievements',
 	title: i18n.ts.achievements,
-	icon: 'ti ti-medal',
+	icon: 'ph-trophy ph-bold ph-lg',
 }] : []), ...($i && ($i.id === user.id)) || user.publicReactions ? [{
 	key: 'reactions',
 	title: i18n.ts.reaction,
-	icon: 'ti ti-mood-happy',
+	icon: 'ph-smiley ph-bold ph-lg',
 }] : [], {
 	key: 'clips',
 	title: i18n.ts.clips,
-	icon: 'ti ti-paperclip',
+	icon: 'ph-paperclip ph-bold ph-lg',
 }, {
 	key: 'lists',
 	title: i18n.ts.lists,
-	icon: 'ti ti-list',
+	icon: 'ph-list ph-bold pg-lg',
 }, {
 	key: 'pages',
 	title: i18n.ts.pages,
-	icon: 'ti ti-news',
+	icon: 'ph-newspaper ph-bold ph-lg',
 }, {
 	key: 'flashs',
 	title: 'Play',
-	icon: 'ti ti-player-play',
+	icon: 'ph-play ph-bold pg-lg',
 }, {
 	key: 'gallery',
 	title: i18n.ts.gallery,
-	icon: 'ti ti-icons',
+	icon: 'ph-images-square ph-bold pg-lg',
 }] : []);
 
 definePageMetadata(computed(() => user ? {
-	icon: 'ti ti-user',
+	icon: 'ph-user ph-bold ph-lg',
 	title: user.name ? `${user.name} (@${user.username})` : `@${user.username}`,
 	subtitle: `@${getAcct(user)}`,
 	userName: user,
diff --git a/packages/frontend/src/pages/user/lists.vue b/packages/frontend/src/pages/user/lists.vue
index 4b9c5cbf8f..474237f018 100644
--- a/packages/frontend/src/pages/user/lists.vue
+++ b/packages/frontend/src/pages/user/lists.vue
@@ -45,7 +45,7 @@ const pagination = {
 	display: block;
 	padding: 16px;
 	border: solid 1px var(--divider);
-	border-radius: 6px;
+	border-radius: 5px;
 	margin-bottom: 8px;
 
 	&:hover {
diff --git a/packages/frontend/src/pages/welcome.entrance.a.vue b/packages/frontend/src/pages/welcome.entrance.a.vue
index d446b198d1..665dbed7b9 100644
--- a/packages/frontend/src/pages/welcome.entrance.a.vue
+++ b/packages/frontend/src/pages/welcome.entrance.a.vue
@@ -155,7 +155,7 @@ os.apiGet('federation/instances', {
 		background: var(--acrylicPanel);
 		-webkit-backdrop-filter: var(--blur, blur(15px));
 		backdrop-filter: var(--blur, blur(15px));
-		border-radius: 999px;
+		border-radius: 4px;
 		overflow: clip;
 		width: 800px;
 		padding: 8px 0;
@@ -175,14 +175,14 @@ os.apiGet('federation/instances', {
 	padding: 6px 12px 6px 6px;
 	margin: 0 10px 0 0;
 	background: var(--panel);
-	border-radius: 999px;
+	border-radius: 4px;
 
 	> :global(.icon) {
 		display: inline-block;
 		width: 20px;
 		height: 20px;
 		margin-right: 5px;
-		border-radius: 999px;
+		border-radius: 4px;
 	}
 }
 </style>
diff --git a/packages/frontend/src/pages/welcome.setup.vue b/packages/frontend/src/pages/welcome.setup.vue
index ec47fc8ad2..bac6cc1f0c 100644
--- a/packages/frontend/src/pages/welcome.setup.vue
+++ b/packages/frontend/src/pages/welcome.setup.vue
@@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				</MkInput>
 				<MkInput v-model="password" type="password" data-cy-admin-password>
 					<template #label>{{ i18n.ts.password }}</template>
-					<template #prefix><i class="ti ti-lock"></i></template>
+					<template #prefix><i class="ph-lock ph-bold ph-lg"></i></template>
 				</MkInput>
 				<div>
 					<MkButton gradate large rounded type="submit" :disabled="submitting" data-cy-admin-ok style="margin: 0 auto;">
diff --git a/packages/frontend/src/pages/welcome.timeline.vue b/packages/frontend/src/pages/welcome.timeline.vue
index f2e151468a..823f713d39 100644
--- a/packages/frontend/src/pages/welcome.timeline.vue
+++ b/packages/frontend/src/pages/welcome.timeline.vue
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div v-for="note in notes" :key="note.id" :class="$style.note">
 			<div class="_panel" :class="$style.content">
 				<div>
-					<MkA v-if="note.replyId" class="reply" :to="`/notes/${note.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
+					<MkA v-if="note.replyId" class="reply" :to="`/notes/${note.replyId}`"><i class="ph-arrow-u-up-left ph-bold pg-lg"></i></MkA>
 					<Mfm v-if="note.text" :text="note.text" :author="note.user" :i="$i"/>
 					<MkA v-if="note.renoteId" class="rp" :to="`/notes/${note.renoteId}`">RN: ...</MkA>
 				</div>
@@ -88,7 +88,7 @@ onUpdated(() => {
 	padding: 16px;
 	margin: 0 0 0 auto;
 	max-width: max-content;
-	border-radius: 16px;
+	border-radius: 4px;
 }
 
 .richcontent {
diff --git a/packages/frontend/src/scripts/get-drive-file-menu.ts b/packages/frontend/src/scripts/get-drive-file-menu.ts
index 0964108249..a01df8cf51 100644
--- a/packages/frontend/src/scripts/get-drive-file-menu.ts
+++ b/packages/frontend/src/scripts/get-drive-file-menu.ts
@@ -78,50 +78,50 @@ export function getDriveFileMenu(file: Misskey.entities.DriveFile, folder?: Miss
 	let menu;
 	menu = [{
 		text: i18n.ts.rename,
-		icon: 'ti ti-forms',
+		icon: 'ph-textbox ph-bold ph-lg',
 		action: () => rename(file),
 	}, {
 		text: file.isSensitive ? i18n.ts.unmarkAsSensitive : i18n.ts.markAsSensitive,
-		icon: file.isSensitive ? 'ti ti-eye' : 'ti ti-eye-exclamation',
+		icon: file.isSensitive ? 'ph-eye ph-bold ph-lg' : 'ph-eye-closed ph-bold ph-lg',
 		action: () => toggleSensitive(file),
 	}, {
 		text: i18n.ts.describeFile,
-		icon: 'ti ti-text-caption',
+		icon: 'ph-text-indent ph-bold ph-lg',
 		action: () => describe(file),
 	}, ...isImage ? [{
 		text: i18n.ts.cropImage,
-		icon: 'ti ti-crop',
+		icon: 'ph-crop ph-bold ph-lg',
 		action: () => os.cropImage(file, {
 			aspectRatio: NaN,
 			uploadFolder: folder ? folder.id : folder,
 		}),
 	}] : [], null, {
 		text: i18n.ts.createNoteFromTheFile,
-		icon: 'ti ti-pencil',
+		icon: 'ph-pencil ph-bold ph-lg',
 		action: () => os.post({
 			initialFiles: [file],
 		}),
 	}, {
 		text: i18n.ts.copyUrl,
-		icon: 'ti ti-link',
+		icon: 'ph-link ph-bold ph-lg',
 		action: () => copyUrl(file),
 	}, {
 		type: 'a',
 		href: file.url,
 		target: '_blank',
 		text: i18n.ts.download,
-		icon: 'ti ti-download',
+		icon: 'ph-download ph-bold ph-lg',
 		download: file.name,
 	}, null, {
 		text: i18n.ts.delete,
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		danger: true,
 		action: () => deleteFile(file),
 	}];
 
 	if (defaultStore.state.devMode) {
 		menu = menu.concat([null, {
-			icon: 'ti ti-id',
+			icon: 'ph-identification-card ph-bold ph-lg',
 			text: i18n.ts.copyFileId,
 			action: () => {
 				copyToClipboard(file.id);
diff --git a/packages/frontend/src/scripts/get-note-menu.ts b/packages/frontend/src/scripts/get-note-menu.ts
index 99475d6234..4889efe104 100644
--- a/packages/frontend/src/scripts/get-note-menu.ts
+++ b/packages/frontend/src/scripts/get-note-menu.ts
@@ -60,7 +60,7 @@ export async function getNoteClipMenu(props: {
 			);
 		},
 	})), null, {
-		icon: 'ti ti-plus',
+		icon: 'ph-plus ph-bold ph-lg',
 		text: i18n.ts.createNew,
 		action: async () => {
 			const { canceled, result } = await os.form(i18n.ts.createNewClip, {
@@ -94,7 +94,7 @@ export async function getNoteClipMenu(props: {
 
 export function getAbuseNoteMenu(note: misskey.entities.Note, text: string): MenuItem {
 	return {
-		icon: 'ti ti-exclamation-circle',
+		icon: 'ph-warning-circle ph-bold ph-lg',
 		text,
 		action: (): void => {
 			const u = note.url ?? note.uri ?? `${url}/notes/${note.id}`;
@@ -108,7 +108,7 @@ export function getAbuseNoteMenu(note: misskey.entities.Note, text: string): Men
 
 export function getCopyNoteLinkMenu(note: misskey.entities.Note, text: string): MenuItem {
 	return {
-		icon: 'ti ti-link',
+		icon: 'ph-link ph-bold ph-lg',
 		text,
 		action: (): void => {
 			copyToClipboard(`${url}/notes/${note.id}`);
@@ -267,74 +267,74 @@ export function getNoteMenu(props: {
 		menu = [
 			...(
 				props.currentClip?.userId === $i.id ? [{
-					icon: 'ti ti-backspace',
+					icon: 'ph-backspace ph-bold ph-lg',
 					text: i18n.ts.unclip,
 					danger: true,
 					action: unclip,
 				}, null] : []
 			), {
-				icon: 'ti ti-info-circle',
+				icon: 'ph-info ph-bold ph-lg',
 				text: i18n.ts.details,
 				action: openDetail,
 			}, {
-				icon: 'ti ti-copy',
+				icon: 'ph-copy ph-bold ph-lg',
 				text: i18n.ts.copyContent,
 				action: copyContent,
 			}, getCopyNoteLinkMenu(appearNote, i18n.ts.copyLink)
 			, (appearNote.url || appearNote.uri) ? {
-				icon: 'ti ti-external-link',
+				icon: 'ph-arrow-square-out ph-bold ph-lg',
 				text: i18n.ts.showOnRemote,
 				action: () => {
 					window.open(appearNote.url ?? appearNote.uri, '_blank');
 				},
 			} : undefined,
 			{
-				icon: 'ti ti-share',
+				icon: 'ph-share-network ph-bold pg-lg',
 				text: i18n.ts.share,
 				action: share,
 			},
 			instance.translatorAvailable ? {
-				icon: 'ti ti-language-hiragana',
+				icon: 'ph-translate ph-bold ph-lg',
 				text: i18n.ts.translate,
 				action: translate,
 			} : undefined,
 			null,
 			statePromise.then(state => state.isFavorited ? {
-				icon: 'ti ti-star-off',
+				icon: 'ph-star-half ph-bold pg-lg',
 				text: i18n.ts.unfavorite,
 				action: () => toggleFavorite(false),
 			} : {
-				icon: 'ti ti-star',
+				icon: 'ph-star ph-bold pg-lg',
 				text: i18n.ts.favorite,
 				action: () => toggleFavorite(true),
 			}),
 			{
 				type: 'parent' as const,
-				icon: 'ti ti-paperclip',
+				icon: 'ph-paperclip ph-bold ph-lg',
 				text: i18n.ts.clip,
 				children: () => getNoteClipMenu(props),
 			},
 			statePromise.then(state => state.isMutedThread ? {
-				icon: 'ti ti-message-off',
+				icon: 'ph-bell-slash ph-bold ph-lg',
 				text: i18n.ts.unmuteThread,
 				action: () => toggleThreadMute(false),
 			} : {
-				icon: 'ti ti-message-off',
+				icon: 'ph-bell-slash ph-bold ph-lg',
 				text: i18n.ts.muteThread,
 				action: () => toggleThreadMute(true),
 			}),
 			appearNote.userId === $i.id ? ($i.pinnedNoteIds ?? []).includes(appearNote.id) ? {
-				icon: 'ti ti-pinned-off',
+				icon: 'ph-push-pin ph-bold ph-lgned-off',
 				text: i18n.ts.unpin,
 				action: () => togglePin(false),
 			} : {
-				icon: 'ti ti-pin',
+				icon: 'ph-push-pin ph-bold ph-lg',
 				text: i18n.ts.pin,
 				action: () => togglePin(true),
 			} : undefined,
 			{
 				type: 'parent' as const,
-				icon: 'ti ti-user',
+				icon: 'ph-user ph-bold ph-lg',
 				text: i18n.ts.user,
 				children: async () => {
 					const user = appearNote.userId === $i?.id ? $i : await os.api('users/show', { userId: appearNote.userId });
@@ -347,7 +347,7 @@ export function getNoteMenu(props: {
 		...($i.isModerator || $i.isAdmin ? [
 			null,
 			{
-				icon: 'ti ti-speakerphone',
+				icon: 'ph-megaphone ph-bold ph-lg',
 				text: i18n.ts.promote,
 				action: promote
 			}]
@@ -362,18 +362,18 @@ export function getNoteMenu(props: {
 			...(appearNote.userId === $i.id || $i.isModerator || $i.isAdmin ? [
 				null,
 				appearNote.userId === $i.id ? {
-					icon: 'ti ti-pencil',
+					icon: 'ph-pencil ph-bold ph-lg',
 					text: i18n.ts.edit,
 					action: edit,
 				} : undefined,
 				{
-					icon: 'ti ti-edit',
+					icon: 'ph-pencil-line ph-bold pg-lg',
 					text: i18n.ts.deleteAndEdit,
 					danger: true,
 					action: delEdit,
 				}, 
 				{
-					icon: 'ti ti-trash',
+					icon: 'ph-trash ph-bold ph-lg',
 					text: i18n.ts.delete,
 					danger: true,
 					action: del,
@@ -383,16 +383,16 @@ export function getNoteMenu(props: {
 			.filter(x => x !== undefined);
 	} else {
 		menu = [{
-			icon: 'ti ti-info-circle',
+			icon: 'ph-info ph-bold ph-lg',
 			text: i18n.ts.details,
 			action: openDetail,
 		}, {
-			icon: 'ti ti-copy',
+			icon: 'ph-copy ph-bold ph-lg',
 			text: i18n.ts.copyContent,
 			action: copyContent,
 		}, getCopyNoteLinkMenu(appearNote, i18n.ts.copyLink)
 		, (appearNote.url || appearNote.uri) ? {
-			icon: 'ti ti-external-link',
+			icon: 'ph-arrow-square-out ph-bold ph-lg',
 			text: i18n.ts.showOnRemote,
 			action: () => {
 				window.open(appearNote.url ?? appearNote.uri, '_blank');
@@ -403,7 +403,7 @@ export function getNoteMenu(props: {
 
 	if (noteActions.length > 0) {
 		menu = menu.concat([null, ...noteActions.map(action => ({
-			icon: 'ti ti-plug',
+			icon: 'ph-plug ph-bold ph-lg',
 			text: action.title,
 			action: () => {
 				action.handler(appearNote);
@@ -413,7 +413,7 @@ export function getNoteMenu(props: {
 
 	if (defaultStore.state.devMode) {
 		menu = menu.concat([null, {
-			icon: 'ti ti-id',
+			icon: 'ph-identification-card ph-bold ph-lg',
 			text: i18n.ts.copyNoteId,
 			action: () => {
 				copyToClipboard(appearNote.id);
diff --git a/packages/frontend/src/scripts/get-user-menu.ts b/packages/frontend/src/scripts/get-user-menu.ts
index 128cbafb15..24ca93495a 100644
--- a/packages/frontend/src/scripts/get-user-menu.ts
+++ b/packages/frontend/src/scripts/get-user-menu.ts
@@ -137,46 +137,46 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
 	}
 
 	let menu = [{
-		icon: 'ti ti-at',
+		icon: 'ph-at ph-bold ph-lg',
 		text: i18n.ts.copyUsername,
 		action: () => {
 			copyToClipboard(`@${user.username}@${user.host ?? host}`);
 		},
 	}, ...(iAmModerator ? [{
-		icon: 'ti ti-user-exclamation',
+		icon: 'ph-warning-circle ph-bold ph-lg',
 		text: i18n.ts.moderation,
 		action: () => {
 			router.push(`/admin/user/${user.id}`);
 		},
 	}] : []), {
-		icon: 'ti ti-rss',
+		icon: 'ph-rss ph-bold ph-lg',
 		text: i18n.ts.copyRSS,
 		action: () => {
 			copyToClipboard(`${user.host ?? host}/@${user.username}.atom`);
 		},
 	}, {
-		icon: 'ti ti-share',
+		icon: 'ph-share-network ph-bold pg-lg',
 		text: i18n.ts.copyProfileUrl,
 		action: () => {
 			const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${toUnicode(user.host)}`;
 			copyToClipboard(`${url}/${canonical}`);
 		},
 	}, {
-		icon: 'ti ti-mail',
+		icon: 'ph-envelope ph-bold ph-lg',
 		text: i18n.ts.sendMessage,
 		action: () => {
 			const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${user.host}`;
 			os.post({ specified: user, initialText: `${canonical} ` });
 		},
 	}, null, {
-		icon: 'ti ti-pencil',
+		icon: 'ph-pencil ph-bold ph-lg',
 		text: i18n.ts.editMemo,
 		action: () => {
 			editMemo();
 		},
 	}, {
 		type: 'parent',
-		icon: 'ti ti-list',
+		icon: 'ph-list ph-bold pg-lg',
 		text: i18n.ts.addToList,
 		children: async () => {
 			const lists = await userListsCache.fetch();
@@ -209,7 +209,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
 		},
 	}, {
 		type: 'parent',
-		icon: 'ti ti-antenna',
+		icon: 'ph-flying-saucer ph-bold pg-lg',
 		text: i18n.ts.addToAntenna,
 		children: async () => {
 			const antennas = await antennasCache.fetch();
@@ -240,7 +240,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
 		if (iAmModerator) {
 			menu = menu.concat([{
 				type: 'parent',
-				icon: 'ti ti-badges',
+				icon: 'ph-seal-check ph-bold pg-lg',
 				text: i18n.ts.roles,
 				children: async () => {
 					const roles = await rolesCache.fetch();
@@ -282,36 +282,36 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
 		// フォローしたとしても user.isFollowing はリアルタイム更新されないので不便なため
 		//if (user.isFollowing) {
 		menu = menu.concat([{
-			icon: user.notify === 'none' ? 'ti ti-bell' : 'ti ti-bell-off',
+			icon: user.notify === 'none' ? 'ph-bell ph-bold pg-lg' : 'ph-bell ph-bold pg-lg-off',
 			text: user.notify === 'none' ? i18n.ts.notifyNotes : i18n.ts.unnotifyNotes,
 			action: toggleNotify,
 		}]);
 		//}
 
 		menu = menu.concat([null, {
-			icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off',
+			icon: user.isMuted ? 'ph-eye ph-bold ph-lg' : 'ph-eye-slash ph-bold ph-lg',
 			text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute,
 			action: toggleMute,
 		}, {
-			icon: user.isRenoteMuted ? 'ti ti-repeat' : 'ti ti-repeat-off',
+			icon: user.isRenoteMuted ? 'ph-repeat ph-bold ph-lg' : 'ph-repeat ph-bold ph-lg-off',
 			text: user.isRenoteMuted ? i18n.ts.renoteUnmute : i18n.ts.renoteMute,
 			action: toggleRenoteMute,
 		}, {
-			icon: 'ti ti-ban',
+			icon: 'ph-prohibit ph-bold ph-lg',
 			text: user.isBlocking ? i18n.ts.unblock : i18n.ts.block,
 			action: toggleBlock,
 		}]);
 
 		if (user.isFollowed) {
 			menu = menu.concat([{
-				icon: 'ti ti-link-off',
+				icon: 'ph-link ph-bold ph-lg-off',
 				text: i18n.ts.breakFollow,
 				action: invalidateFollow,
 			}]);
 		}
 
 		menu = menu.concat([null, {
-			icon: 'ti ti-exclamation-circle',
+			icon: 'ph-warning-circle ph-bold ph-lg',
 			text: i18n.ts.reportAbuse,
 			action: reportAbuse,
 		}]);
@@ -319,7 +319,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
 
 	if (defaultStore.state.devMode) {
 		menu = menu.concat([null, {
-			icon: 'ti ti-id',
+			icon: 'ph-identification-card ph-bold ph-lg',
 			text: i18n.ts.copyUserId,
 			action: () => {
 				copyToClipboard(user.id);
@@ -329,7 +329,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
 
 	if ($i && meId === user.id) {
 		menu = menu.concat([null, {
-			icon: 'ti ti-pencil',
+			icon: 'ph-pencil ph-bold ph-lg',
 			text: i18n.ts.editProfile,
 			action: () => {
 				router.push('/settings/profile');
@@ -339,7 +339,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router
 
 	if (userActions.length > 0) {
 		menu = menu.concat([null, ...userActions.map(action => ({
-			icon: 'ti ti-plug',
+			icon: 'ph-plug ph-bold ph-lg',
 			text: action.title,
 			action: () => {
 				action.handler(user);
diff --git a/packages/frontend/src/scripts/select-file.ts b/packages/frontend/src/scripts/select-file.ts
index 53e2cd5b16..674c762fac 100644
--- a/packages/frontend/src/scripts/select-file.ts
+++ b/packages/frontend/src/scripts/select-file.ts
@@ -92,15 +92,15 @@ function select(src: any, label: string | null, multiple: boolean): Promise<Miss
 			ref: keepOriginal,
 		}, {
 			text: i18n.ts.upload,
-			icon: 'ti ti-upload',
+			icon: 'ph-upload ph-bold ph-lg',
 			action: () => chooseFileFromPc(multiple, keepOriginal.value).then(files => res(files)),
 		}, {
 			text: i18n.ts.fromDrive,
-			icon: 'ti ti-cloud',
+			icon: 'ph-cloud ph-bold ph-lg',
 			action: () => chooseFileFromDrive(multiple).then(files => res(files)),
 		}, {
 			text: i18n.ts.fromUrl,
-			icon: 'ti ti-link',
+			icon: 'ph-link ph-bold ph-lg',
 			action: () => chooseFileFromUrl().then(file => res([file])),
 		}], src);
 	});
diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts
index 53d9b06ab7..69306d5b90 100644
--- a/packages/frontend/src/store.ts
+++ b/packages/frontend/src/store.ts
@@ -63,11 +63,11 @@ export const defaultStore = markRaw(new Storage('base', {
 	},
 	collapseRenotes: {
 		where: 'account',
-		default: true,
+		default: false,
 	},
 	collapseFiles: {
 		where: 'account',
-		default: true,
+		default: false,
 	},
 	rememberNoteVisibility: {
 		where: 'account',
diff --git a/packages/frontend/src/style.scss b/packages/frontend/src/style.scss
index 6efb6077c9..df2f953c50 100644
--- a/packages/frontend/src/style.scss
+++ b/packages/frontend/src/style.scss
@@ -15,7 +15,7 @@
  */
 
 :root {
-	--radius: 12px;
+	--radius: 5px;
 	--marginFull: 16px;
 	--marginHalf: 10px;
 
@@ -140,7 +140,7 @@ hr {
 	background: var(--divider);
 }
 
-.ti {
+.ph-bold {
 	width: 1.28em;
 	vertical-align: -12%;
 	line-height: 1em;
@@ -391,7 +391,7 @@ hr {
 		vertical-align: bottom;
 		height: 128px;
 		margin-bottom: 16px;
-		border-radius: 16px;
+		border-radius: 4px;
 	}
 }
 
diff --git a/packages/frontend/src/ui/_common_/announcements.vue b/packages/frontend/src/ui/_common_/announcements.vue
index 2b1133d472..913fa35cc2 100644
--- a/packages/frontend/src/ui/_common_/announcements.vue
+++ b/packages/frontend/src/ui/_common_/announcements.vue
@@ -12,10 +12,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 		to="/announcements"
 	>
 		<span :class="$style.icon">
-			<i v-if="announcement.icon === 'info'" class="ti ti-info-circle"></i>
-			<i v-else-if="announcement.icon === 'warning'" class="ti ti-alert-triangle" style="color: var(--warn);"></i>
-			<i v-else-if="announcement.icon === 'error'" class="ti ti-circle-x" style="color: var(--error);"></i>
-			<i v-else-if="announcement.icon === 'success'" class="ti ti-check" style="color: var(--success);"></i>
+			<i v-if="announcement.icon === 'info'" class="ph-info ph-bold ph-lg"></i>
+			<i v-else-if="announcement.icon === 'warning'" class="ph-warning ph-bold ph-lg" style="color: var(--warn);"></i>
+			<i v-else-if="announcement.icon === 'error'" class="ph-x-circle ph-bold ph-lg" style="color: var(--error);"></i>
+			<i v-else-if="announcement.icon === 'success'" class="ph-check ph-bold ph-lg" style="color: var(--success);"></i>
 		</span>
 		<span :class="$style.title">{{ announcement.title }}</span>
 		<span :class="$style.body">{{ announcement.text }}</span>
diff --git a/packages/frontend/src/ui/_common_/common.ts b/packages/frontend/src/ui/_common_/common.ts
index 49fe5a8347..3810be4fe6 100644
--- a/packages/frontend/src/ui/_common_/common.ts
+++ b/packages/frontend/src/ui/_common_/common.ts
@@ -16,61 +16,61 @@ export function openInstanceMenu(ev: MouseEvent) {
 	}, {
 		type: 'link',
 		text: i18n.ts.instanceInfo,
-		icon: 'ti ti-info-circle',
+		icon: 'ph-info ph-bold ph-lg',
 		to: '/about',
 	}, {
 		type: 'link',
 		text: i18n.ts.customEmojis,
-		icon: 'ti ti-icons',
+		icon: 'ph-smiley ph-bold pg-lg',
 		to: '/about#emojis',
 	}, {
 		type: 'link',
 		text: i18n.ts.federation,
-		icon: 'ti ti-whirl',
+		icon: 'ph-globe-hemisphere-west ph-bold ph-lg',
 		to: '/about#federation',
 	}, {
 		type: 'link',
 		text: i18n.ts.charts,
-		icon: 'ti ti-chart-line',
+		icon: 'ph-chart-line ph-bold pg-lg',
 		to: '/about#charts',
 	}, null, {
 		type: 'link',
 		text: i18n.ts.ads,
-		icon: 'ti ti-ad',
+		icon: 'ph-flag ph-bold ph-lg',
 		to: '/ads',
 	}, ($i && ($i.isAdmin || $i.policies.canInvite) && instance.disableRegistration) ? {
 		type: 'link',
 		to: '/invite',
 		text: i18n.ts.invite,
-		icon: 'ti ti-user-plus',
+		icon: 'ph-user-plus ph-bold ph-lg',
 	} : undefined, {
 		type: 'parent',
 		text: i18n.ts.tools,
-		icon: 'ti ti-tool',
+		icon: 'ph-wrench ph-bold ph-lg',
 		children: [{
 			type: 'link',
 			to: '/scratchpad',
 			text: i18n.ts.scratchpad,
-			icon: 'ti ti-terminal-2',
+			icon: 'ph-terminal-window ph-bold ph-lg-2',
 		}, {
 			type: 'link',
 			to: '/api-console',
 			text: 'API Console',
-			icon: 'ti ti-terminal-2',
+			icon: 'ph-terminal-window ph-bold ph-lg-2',
 		}, {
 			type: 'link',
 			to: '/clicker',
 			text: '🍪👈',
-			icon: 'ti ti-cookie',
+			icon: 'ph-cookie ph-bold pg-lg',
 		}, ($i && ($i.isAdmin || $i.policies.canManageCustomEmojis)) ? {
 			type: 'link',
 			to: '/custom-emojis-manager',
 			text: i18n.ts.manageCustomEmojis,
-			icon: 'ti ti-icons',
+			icon: 'ph-smiley ph-bold pg-lg',
 		} : undefined],
 	}, null, {
 		text: i18n.ts.help,
-		icon: 'ti ti-help-circle',
+		icon: 'ph-question ph-bold ph-lg',
 		action: () => {
 			window.open('https://misskey-hub.net/help.html', '_blank');
 		},
diff --git a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue b/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
index eed4cc777a..70dbc7e0b3 100644
--- a/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
+++ b/packages/frontend/src/ui/_common_/navbar-for-mobile.vue
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</div>
 	<div :class="$style.middle">
 		<MkA :class="$style.item" :activeClass="$style.active" to="/" exact>
-			<i :class="$style.itemIcon" class="ti ti-home ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.timeline }}</span>
+			<i :class="$style.itemIcon" class="ph-house ph-bold ph-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.timeline }}</span>
 		</MkA>
 		<template v-for="item in menu">
 			<div v-if="item === '-'" :class="$style.divider"></div>
@@ -24,19 +24,19 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</template>
 		<div :class="$style.divider"></div>
 		<MkA v-if="$i.isAdmin || $i.isModerator" :class="$style.item" :activeClass="$style.active" to="/admin">
-			<i :class="$style.itemIcon" class="ti ti-dashboard ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
+			<i :class="$style.itemIcon" class="ph-gauge ph-bold pg-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
 		</MkA>
 		<button :class="$style.item" class="_button" @click="more">
-			<i :class="$style.itemIcon" class="ti ti-grid-dots ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
+			<i :class="$style.itemIcon" class="ph-dots-nine ph-bold ph-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
 			<span v-if="otherMenuItemIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
 		</button>
 		<MkA :class="$style.item" :activeClass="$style.active" to="/settings">
-			<i :class="$style.itemIcon" class="ti ti-settings ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.settings }}</span>
+			<i :class="$style.itemIcon" class="ph-gear ph-bold pg-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.settings }}</span>
 		</MkA>
 	</div>
 	<div :class="$style.bottom">
 		<button class="_button" :class="$style.post" data-cy-open-post-form @click="os.post">
-			<i :class="$style.postIcon" class="ti ti-pencil ti-fw"></i><span style="position: relative;">{{ i18n.ts.note }}</span>
+			<i :class="$style.postIcon" class="ph-pencil ph-bold ph-lg ti-fw"></i><span style="position: relative;">{{ i18n.ts.note }}</span>
 		</button>
 		<button class="_button" :class="$style.account" @click="openAccountMenu">
 			<MkAvatar :user="$i" :class="$style.avatar"/><MkAcct :class="$style.acct" class="_nowrap" :user="$i"/>
@@ -146,7 +146,7 @@ function more() {
 		left: 0;
 		right: 0;
 		bottom: 0;
-		border-radius: 999px;
+		border-radius: 4px;
 		background: linear-gradient(90deg, var(--buttonGradateA), var(--buttonGradateB));
 	}
 
@@ -233,7 +233,7 @@ function more() {
 			left: 0;
 			right: 0;
 			bottom: 0;
-			border-radius: 999px;
+			border-radius: 4px;
 			background: var(--accentedBg);
 		}
 	}
diff --git a/packages/frontend/src/ui/_common_/navbar.vue b/packages/frontend/src/ui/_common_/navbar.vue
index 46d92867b1..73ef815899 100644
--- a/packages/frontend/src/ui/_common_/navbar.vue
+++ b/packages/frontend/src/ui/_common_/navbar.vue
@@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 		<div :class="$style.middle">
 			<MkA v-tooltip.noDelay.right="i18n.ts.timeline" :class="$style.item" :activeClass="$style.active" to="/" exact>
-				<i :class="$style.itemIcon" class="ti ti-home ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.timeline }}</span>
+				<i :class="$style.itemIcon" class="ph-house ph-bold ph-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.timeline }}</span>
 			</MkA>
 			<template v-for="item in menu">
 				<div v-if="item === '-'" :class="$style.divider"></div>
@@ -34,19 +34,19 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</template>
 			<div :class="$style.divider"></div>
 			<MkA v-if="$i.isAdmin || $i.isModerator" v-tooltip.noDelay.right="i18n.ts.controlPanel" :class="$style.item" :activeClass="$style.active" to="/admin">
-				<i :class="$style.itemIcon" class="ti ti-dashboard ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
+				<i :class="$style.itemIcon" class="ph-gauge ph-bold pg-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.controlPanel }}</span>
 			</MkA>
 			<button class="_button" :class="$style.item" @click="more">
-				<i :class="$style.itemIcon" class="ti ti-grid-dots ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
+				<i :class="$style.itemIcon" class="ph-dots-nine ph-bold ph-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.more }}</span>
 				<span v-if="otherMenuItemIndicated" :class="$style.itemIndicator"><i class="_indicatorCircle"></i></span>
 			</button>
 			<MkA v-tooltip.noDelay.right="i18n.ts.settings" :class="$style.item" :activeClass="$style.active" to="/settings">
-				<i :class="$style.itemIcon" class="ti ti-settings ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.settings }}</span>
+				<i :class="$style.itemIcon" class="ph-gear ph-bold pg-lg ti-fw"></i><span :class="$style.itemText">{{ i18n.ts.settings }}</span>
 			</MkA>
 		</div>
 		<div :class="$style.bottom">
 			<button v-tooltip.noDelay.right="i18n.ts.note" class="_button" :class="[$style.post]" data-cy-open-post-form @click="os.post">
-				<i class="ti ti-pencil ti-fw" :class="$style.postIcon"></i><span :class="$style.postText">{{ i18n.ts.note }}</span>
+				<i class="ph-pencil ph-bold ph-lg ti-fw" :class="$style.postIcon"></i><span :class="$style.postText">{{ i18n.ts.note }}</span>
 			</button>
 			<button v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="_button" :class="[$style.account]" @click="openAccountMenu">
 				<MkAvatar :user="$i" :class="$style.avatar"/><MkAcct class="_nowrap" :class="$style.acct" :user="$i"/>
@@ -199,7 +199,7 @@ function more(ev: MouseEvent) {
 			left: 0;
 			right: 0;
 			bottom: 0;
-			border-radius: 999px;
+			border-radius: 4px;
 			background: linear-gradient(90deg, var(--buttonGradateA), var(--buttonGradateB));
 		}
 
@@ -292,7 +292,7 @@ function more(ev: MouseEvent) {
 				left: 0;
 				right: 0;
 				bottom: 0;
-				border-radius: 999px;
+				border-radius: 4px;
 				background: var(--accentedBg);
 			}
 		}
@@ -445,7 +445,7 @@ function more(ev: MouseEvent) {
 				left: 0;
 				right: 0;
 				bottom: 0;
-				border-radius: 999px;
+				border-radius: 4px;
 				background: var(--accentedBg);
 			}
 
diff --git a/packages/frontend/src/ui/_common_/notification.vue b/packages/frontend/src/ui/_common_/notification.vue
index dfc1f83960..4ca900ff12 100644
--- a/packages/frontend/src/ui/_common_/notification.vue
+++ b/packages/frontend/src/ui/_common_/notification.vue
@@ -22,7 +22,7 @@ defineProps<{
 <style lang="scss" module>
 .root {
 	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
-	border-radius: 8px;
+	border-radius: 5px;
 	overflow: clip;
 	contain: content;
 }
diff --git a/packages/frontend/src/ui/_common_/stream-indicator.vue b/packages/frontend/src/ui/_common_/stream-indicator.vue
index b09221f5d2..0955a71718 100644
--- a/packages/frontend/src/ui/_common_/stream-indicator.vue
+++ b/packages/frontend/src/ui/_common_/stream-indicator.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div v-if="hasDisconnected && defaultStore.state.serverDisconnectedBehavior === 'quiet'" :class="$style.root" class="_panel _shadow" @click="resetDisconnected">
-	<div><i class="ti ti-alert-triangle"></i> {{ i18n.ts.disconnectedFromServer }}</div>
+	<div><i class="ph-warning ph-bold ph-lg"></i> {{ i18n.ts.disconnectedFromServer }}</div>
 	<div :class="$style.command" class="_buttons">
 		<MkButton small primary @click="reload">{{ i18n.ts.reload }}</MkButton>
 		<MkButton small>{{ i18n.ts.doNothing }}</MkButton>
diff --git a/packages/frontend/src/ui/_common_/upload.vue b/packages/frontend/src/ui/_common_/upload.vue
index 3365571a14..676dd1d542 100644
--- a/packages/frontend/src/ui/_common_/upload.vue
+++ b/packages/frontend/src/ui/_common_/upload.vue
@@ -40,7 +40,7 @@ const zIndex = os.claimZIndex('high');
 	padding: 16px 20px;
 	pointer-events: none;
 	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
-	border-radius: 8px;
+	border-radius: 5px;
 }
 .mk-uploader:empty {
   display: none;
diff --git a/packages/frontend/src/ui/classic.header.vue b/packages/frontend/src/ui/classic.header.vue
index 3b78aa93cd..79909d4ae9 100644
--- a/packages/frontend/src/ui/classic.header.vue
+++ b/packages/frontend/src/ui/classic.header.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<img :src="instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" class="_ghost"/>
 			</button>
 			<MkA v-click-anime v-tooltip="i18n.ts.timeline" class="item index" activeClass="active" to="/" exact>
-				<i class="ti ti-home ti-fw"></i>
+				<i class="ph-house ph-bold ph-lg ti-fw"></i>
 			</MkA>
 			<template v-for="item in menu">
 				<div v-if="item === '-'" class="divider"></div>
@@ -22,23 +22,23 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</template>
 			<div class="divider"></div>
 			<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip="i18n.ts.controlPanel" class="item" activeClass="active" to="/admin" :behavior="settingsWindowed ? 'window' : null">
-				<i class="ti ti-dashboard ti-fw"></i>
+				<i class="ph-gauge ph-bold pg-lg ti-fw"></i>
 			</MkA>
 			<button v-click-anime class="item _button" @click="more">
-				<i class="ti ti-dots ti-fw"></i>
+				<i class="ph-dots-three ph-bold ph-lg 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="i18n.ts.settings" class="item" activeClass="active" to="/settings" :behavior="settingsWindowed ? 'window' : null">
-				<i class="ti ti-settings ti-fw"></i>
+				<i class="ph-gear ph-bold pg-lg 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="os.post()">
 				<MkButton class="button" gradate full rounded>
-					<i class="ti ti-pencil ti-fw"></i>
+					<i class="ph-pencil ph-bold ph-lg ti-fw"></i>
 				</MkButton>
 			</div>
 		</div>
diff --git a/packages/frontend/src/ui/classic.sidebar.vue b/packages/frontend/src/ui/classic.sidebar.vue
index 6f22a736f5..3e501db91b 100644
--- a/packages/frontend/src/ui/classic.sidebar.vue
+++ b/packages/frontend/src/ui/classic.sidebar.vue
@@ -10,12 +10,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</button>
 	<div class="post" data-cy-open-post-form @click="os.post">
 		<MkButton class="button" gradate full rounded>
-			<i class="ti ti-pencil ti-fw"></i><span v-if="!iconOnly" class="text">{{ i18n.ts.note }}</span>
+			<i class="ph-pencil ph-bold ph-lg ti-fw"></i><span v-if="!iconOnly" class="text">{{ i18n.ts.note }}</span>
 		</MkButton>
 	</div>
 	<div class="divider"></div>
 	<MkA v-click-anime class="item index" activeClass="active" to="/" exact>
-		<i class="ti ti-home ti-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
+		<i class="ph-house ph-bold ph-lg ti-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
 	</MkA>
 	<template v-for="item in menu">
 		<div v-if="item === '-'" class="divider"></div>
@@ -26,14 +26,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</template>
 	<div class="divider"></div>
 	<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime class="item" activeClass="active" to="/admin" :behavior="settingsWindowed ? 'window' : null">
-		<i class="ti ti-dashboard ti-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
+		<i class="ph-gauge ph-bold pg-lg ti-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
 	</MkA>
 	<button v-click-anime class="item _button" @click="more">
-		<i class="ti ti-dots ti-fw"></i><span class="text">{{ i18n.ts.more }}</span>
+		<i class="ph-dots-three ph-bold ph-lg ti-fw"></i><span class="text">{{ i18n.ts.more }}</span>
 		<span v-if="otherNavItemIndicated" class="indicator"><i class="_indicatorCircle"></i></span>
 	</button>
 	<MkA v-click-anime class="item" activeClass="active" to="/settings" :behavior="settingsWindowed ? 'window' : null">
-		<i class="ti ti-settings ti-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
+		<i class="ph-gear ph-bold pg-lg ti-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
 	</MkA>
 	<div class="divider"></div>
 	<div class="about">
diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue
index 3323e813bb..c4239fc9db 100644
--- a/packages/frontend/src/ui/classic.vue
+++ b/packages/frontend/src/ui/classic.vue
@@ -110,13 +110,13 @@ function onContextmenu(ev: MouseEvent) {
 		type: 'label',
 		text: path,
 	}, {
-		icon: fullView ? 'ti ti-minimize' : 'ti ti-maximize',
+		icon: fullView ? 'ph-arrows-in-simple ph-bold ph-lg' : 'ph-frame-corners ph-bold ph-lg',
 		text: fullView ? i18n.ts.quitFullView : i18n.ts.fullView,
 		action: () => {
 			fullView = !fullView;
 		},
 	}, {
-		icon: 'ti ti-window-maximize',
+		icon: 'ph-frame-corners ph-bold ph-lg',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(path);
diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index 2510977877..0cd0914b97 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -36,24 +36,24 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 			<div :class="$style.sideMenu">
 				<div :class="$style.sideMenuTop">
-					<button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${deckStore.state.profile}`" :class="$style.sideMenuButton" class="_button" @click="changeProfile"><i class="ti ti-caret-down"></i></button>
-					<button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.sideMenuButton" class="_button" @click="deleteProfile"><i class="ti ti-trash"></i></button>
+					<button v-tooltip.noDelay.left="`${i18n.ts._deck.profile}: ${deckStore.state.profile}`" :class="$style.sideMenuButton" class="_button" @click="changeProfile"><i class="ph-caret-down ph-bold ph-lg"></i></button>
+					<button v-tooltip.noDelay.left="i18n.ts._deck.deleteProfile" :class="$style.sideMenuButton" class="_button" @click="deleteProfile"><i class="ph-trash ph-bold ph-lg"></i></button>
 				</div>
 				<div :class="$style.sideMenuMiddle">
-					<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ti ti-plus"></i></button>
+					<button v-tooltip.noDelay.left="i18n.ts._deck.addColumn" :class="$style.sideMenuButton" class="_button" @click="addColumn"><i class="ph-plus ph-bold ph-lg"></i></button>
 				</div>
 				<div :class="$style.sideMenuBottom">
-					<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ti ti-settings"></i></button>
+					<button v-tooltip.noDelay.left="i18n.ts.settings" :class="$style.sideMenuButton" class="_button" @click="showSettings"><i class="ph-gear ph-bold pg-lg"></i></button>
 				</div>
 			</div>
 		</div>
 	</div>
 
 	<div v-if="isMobile" :class="$style.nav">
-		<button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
-		<button :class="$style.navButton" class="_button" @click="mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ti ti-home"></i></button>
-		<button :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
-		<button :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
+		<button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ph-list ph-bold ph-lg-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
+		<button :class="$style.navButton" class="_button" @click="mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ph-house ph-bold ph-lg"></i></button>
+		<button :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ph-bell ph-bold pg-lg"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
+		<button :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ph-pencil ph-bold ph-lg"></i></button>
 	</div>
 
 	<Transition
@@ -233,7 +233,7 @@ function changeProfile(ev: MouseEvent) {
 			},
 		}))), null, {
 			text: i18n.ts._deck.newProfile,
-			icon: 'ti ti-plus',
+			icon: 'ph-plus ph-bold ph-lg',
 			action: async () => {
 				const { canceled, result: name } = await os.inputText({
 					title: i18n.ts._deck.profile,
diff --git a/packages/frontend/src/ui/deck/antenna-column.vue b/packages/frontend/src/ui/deck/antenna-column.vue
index a93a14648c..53ae113ffa 100644
--- a/packages/frontend/src/ui/deck/antenna-column.vue
+++ b/packages/frontend/src/ui/deck/antenna-column.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <XColumn :menu="menu" :column="column" :isStacked="isStacked">
 	<template #header>
-		<i class="ti ti-antenna"></i><span style="margin-left: 8px;">{{ column.name }}</span>
+		<i class="ph-flying-saucer ph-bold pg-lg"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<MkTimeline v-if="column.antennaId" ref="timeline" src="antenna" :antenna="column.antennaId"/>
@@ -55,12 +55,12 @@ function editAntenna() {
 
 const menu = [
 	{
-		icon: 'ti ti-pencil',
+		icon: 'ph-pencil ph-bold ph-lg',
 		text: i18n.ts.selectAntenna,
 		action: setAntenna,
 	},
 	{
-		icon: 'ti ti-settings',
+		icon: 'ph-gear ph-bold pg-lg',
 		text: i18n.ts.editAntenna,
 		action: editAntenna,
 	},
diff --git a/packages/frontend/src/ui/deck/channel-column.vue b/packages/frontend/src/ui/deck/channel-column.vue
index 4b982073ad..e7bc530e2e 100644
--- a/packages/frontend/src/ui/deck/channel-column.vue
+++ b/packages/frontend/src/ui/deck/channel-column.vue
@@ -6,12 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <XColumn :menu="menu" :column="column" :isStacked="isStacked">
 	<template #header>
-		<i class="ti ti-device-tv"></i><span style="margin-left: 8px;">{{ column.name }}</span>
+		<i class="ph-television ph-bold ph-lg"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<template v-if="column.channelId">
 		<div style="padding: 8px; text-align: center;">
-			<MkButton primary gradate rounded inline @click="post"><i class="ti ti-pencil"></i></MkButton>
+			<MkButton primary gradate rounded inline @click="post"><i class="ph-pencil ph-bold ph-lg"></i></MkButton>
 		</div>
 		<MkTimeline ref="timeline" src="channel" :channel="column.channelId"/>
 	</template>
@@ -70,7 +70,7 @@ async function post() {
 }
 
 const menu = [{
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	text: i18n.ts.selectChannel,
 	action: setChannel,
 }];
diff --git a/packages/frontend/src/ui/deck/column.vue b/packages/frontend/src/ui/deck/column.vue
index 269b9d57d5..82505ee145 100644
--- a/packages/frontend/src/ui/deck/column.vue
+++ b/packages/frontend/src/ui/deck/column.vue
@@ -26,14 +26,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</svg>
 		<div :class="$style.color"></div>
 		<button v-if="isStacked && !isMainColumn" :class="$style.toggleActive" class="_button" @click="toggleActive">
-			<template v-if="active"><i class="ti ti-chevron-up"></i></template>
-			<template v-else><i class="ti ti-chevron-down"></i></template>
+			<template v-if="active"><i class="ph-caret-up ph-bold ph-lg"></i></template>
+			<template v-else><i class="ph-caret-down ph-bold ph-lg"></i></template>
 		</button>
 		<span :class="$style.title"><slot name="header"></slot></span>
 		<svg viewBox="0 0 16 16" version="1.1" :class="$style.grabber">
 			<path fill="currentColor" d="M10 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm0-4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm-4 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm5-9a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM7 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM6 5a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path>
 		</svg>
-		<button v-tooltip="i18n.ts.settings" :class="$style.menu" class="_button" @click.stop="showSettingsMenu"><i class="ti ti-dots"></i></button>
+		<button v-tooltip="i18n.ts.settings" :class="$style.menu" class="_button" @click.stop="showSettingsMenu"><i class="ph-dots-three ph-bold ph-lg"></i></button>
 	</header>
 	<div v-if="active" ref="body" :class="$style.body">
 		<slot></slot>
@@ -104,7 +104,7 @@ function toggleActive() {
 
 function getMenu() {
 	let items = [{
-		icon: 'ti ti-settings',
+		icon: 'ph-gear ph-bold pg-lg',
 		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: 'ti ti-arrows-move',
+		icon: 'ph-arrows-out-cardinal ph-bold ph-lg',
 		children: [{
-			icon: 'ti ti-arrow-left',
+			icon: 'ph-arrow-left ph-bold pg-lg',
 			text: i18n.ts._deck.swapLeft,
 			action: () => {
 				swapLeftColumn(props.column.id);
 			},
 		}, {
-			icon: 'ti ti-arrow-right',
+			icon: 'ph-arrow-right ph-bold pg-lg',
 			text: i18n.ts._deck.swapRight,
 			action: () => {
 				swapRightColumn(props.column.id);
 			},
 		}, props.isStacked ? {
-			icon: 'ti ti-arrow-up',
+			icon: 'ph-arrow-up ph-bold ph-lg',
 			text: i18n.ts._deck.swapUp,
 			action: () => {
 				swapUpColumn(props.column.id);
 			},
 		} : undefined, props.isStacked ? {
-			icon: 'ti ti-arrow-down',
+			icon: 'ph-arrow-down ph-bold ph-lg',
 			text: i18n.ts._deck.swapDown,
 			action: () => {
 				swapDownColumn(props.column.id);
 			},
 		} : undefined],
 	}, {
-		icon: 'ti ti-stack-2',
+		icon: 'ph-stack ph-bold ph-lg',
 		text: i18n.ts._deck.stackLeft,
 		action: () => {
 			stackLeftColumn(props.column.id);
 		},
 	}, props.isStacked ? {
-		icon: 'ti ti-window-maximize',
+		icon: 'ph-frame-corners ph-bold ph-lg',
 		text: i18n.ts._deck.popRight,
 		action: () => {
 			popRightColumn(props.column.id);
 		},
 	} : undefined, null, {
-		icon: 'ti ti-trash',
+		icon: 'ph-trash ph-bold ph-lg',
 		text: i18n.ts.remove,
 		danger: true,
 		action: () => {
@@ -255,7 +255,7 @@ function onDrop(ev) {
 	height: 100%;
 	overflow: clip;
 	contain: strict;
-	border-radius: 10px;
+	border-radius: 5px;
 
 	&.draghover {
 		&:after {
@@ -356,7 +356,7 @@ function onDrop(ev) {
 	width: 3px;
 	height: calc(100% - 24px);
 	background: var(--accent);
-	border-radius: 999px;
+	border-radius: 4px;
 }
 
 .tabShape {
diff --git a/packages/frontend/src/ui/deck/direct-column.vue b/packages/frontend/src/ui/deck/direct-column.vue
index 940d2d7609..e7c48c94ce 100644
--- a/packages/frontend/src/ui/deck/direct-column.vue
+++ b/packages/frontend/src/ui/deck/direct-column.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <XColumn :column="column" :isStacked="isStacked">
-	<template #header><i class="ti ti-mail" style="margin-right: 8px;"></i>{{ column.name }}</template>
+	<template #header><i class="ph-envelope ph-bold ph-lg" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
 	<MkNotes :pagination="pagination"/>
 </XColumn>
diff --git a/packages/frontend/src/ui/deck/list-column.vue b/packages/frontend/src/ui/deck/list-column.vue
index c43ccdfabb..b3bd76d2dc 100644
--- a/packages/frontend/src/ui/deck/list-column.vue
+++ b/packages/frontend/src/ui/deck/list-column.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <XColumn :menu="menu" :column="column" :isStacked="isStacked">
 	<template #header>
-		<i class="ti ti-list"></i><span style="margin-left: 8px;">{{ column.name }}</span>
+		<i class="ph-list ph-bold pg-lg"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<MkTimeline v-if="column.listId" ref="timeline" src="list" :list="column.listId"/>
@@ -53,12 +53,12 @@ function editList() {
 
 const menu = [
 	{
-		icon: 'ti ti-pencil',
+		icon: 'ph-pencil ph-bold ph-lg',
 		text: i18n.ts.selectList,
 		action: setList,
 	},
 	{
-		icon: 'ti ti-settings',
+		icon: 'ph-gear ph-bold pg-lg',
 		text: i18n.ts.editList,
 		action: editList,
 	},
diff --git a/packages/frontend/src/ui/deck/main-column.vue b/packages/frontend/src/ui/deck/main-column.vue
index d54368c932..40639d46aa 100644
--- a/packages/frontend/src/ui/deck/main-column.vue
+++ b/packages/frontend/src/ui/deck/main-column.vue
@@ -64,7 +64,7 @@ function onContextmenu(ev: MouseEvent) {
 		type: 'label',
 		text: path,
 	}, {
-		icon: 'ti ti-window-maximize',
+		icon: 'ph-frame-corners ph-bold ph-lg',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(path);
diff --git a/packages/frontend/src/ui/deck/mentions-column.vue b/packages/frontend/src/ui/deck/mentions-column.vue
index 381a9d02f2..7ef8c6854f 100644
--- a/packages/frontend/src/ui/deck/mentions-column.vue
+++ b/packages/frontend/src/ui/deck/mentions-column.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <XColumn :column="column" :isStacked="isStacked">
-	<template #header><i class="ti ti-at" style="margin-right: 8px;"></i>{{ column.name }}</template>
+	<template #header><i class="ph-at ph-bold ph-lg" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
 	<MkNotes :pagination="pagination"/>
 </XColumn>
diff --git a/packages/frontend/src/ui/deck/notifications-column.vue b/packages/frontend/src/ui/deck/notifications-column.vue
index 0455d43deb..624c828341 100644
--- a/packages/frontend/src/ui/deck/notifications-column.vue
+++ b/packages/frontend/src/ui/deck/notifications-column.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <XColumn :column="column" :isStacked="isStacked" :menu="menu">
-	<template #header><i class="ti ti-bell" style="margin-right: 8px;"></i>{{ column.name }}</template>
+	<template #header><i class="ph-bell ph-bold pg-lg" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
 	<XNotifications :includeTypes="column.includingTypes"/>
 </XColumn>
@@ -38,7 +38,7 @@ function func() {
 }
 
 const menu = [{
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	text: i18n.ts.notificationSetting,
 	action: func,
 }];
diff --git a/packages/frontend/src/ui/deck/role-timeline-column.vue b/packages/frontend/src/ui/deck/role-timeline-column.vue
index e986b1f7d3..9e3d65e2e5 100644
--- a/packages/frontend/src/ui/deck/role-timeline-column.vue
+++ b/packages/frontend/src/ui/deck/role-timeline-column.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <XColumn :menu="menu" :column="column" :isStacked="isStacked">
 	<template #header>
-		<i class="ti ti-badge"></i><span style="margin-left: 8px;">{{ column.name }}</span>
+		<i class="ph-seal-check ph-bold pg-lg"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<MkTimeline v-if="column.roleId" ref="timeline" src="role" :role="column.roleId"/>
@@ -50,7 +50,7 @@ async function setRole() {
 }
 
 const menu = [{
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	text: i18n.ts.role,
 	action: setRole,
 }];
diff --git a/packages/frontend/src/ui/deck/tl-column.vue b/packages/frontend/src/ui/deck/tl-column.vue
index 073898409c..6481db6ea0 100644
--- a/packages/frontend/src/ui/deck/tl-column.vue
+++ b/packages/frontend/src/ui/deck/tl-column.vue
@@ -6,16 +6,16 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <XColumn :menu="menu" :column="column" :isStacked="isStacked">
 	<template #header>
-		<i v-if="column.tl === 'home'" class="ti ti-home"></i>
-		<i v-else-if="column.tl === 'local'" class="ti ti-planet"></i>
-		<i v-else-if="column.tl === 'social'" class="ti ti-rocket"></i>
-		<i v-else-if="column.tl === 'global'" class="ti ti-whirl"></i>
+		<i v-if="column.tl === 'home'" class="ph-house ph-bold ph-lg"></i>
+		<i v-else-if="column.tl === 'local'" class="ph-planet ph-bold pg-lg"></i>
+		<i v-else-if="column.tl === 'social'" class="ph-rocket-launch ph-bold pg-lg"></i>
+		<i v-else-if="column.tl === 'global'" class="ph-globe-hemisphere-west ph-bold ph-lg"></i>
 		<span style="margin-left: 8px;">{{ column.name }}</span>
 	</template>
 
 	<div v-if="(((column.tl === 'local' || column.tl === 'social') && !isLocalTimelineAvailable) || (column.tl === 'global' && !isGlobalTimelineAvailable))" :class="$style.disabled">
 		<p :class="$style.disabledTitle">
-			<i class="ti ti-circle-minus"></i>
+			<i class="ph-minus-circle ph-bold ph-lg"></i>
 			{{ i18n.ts._disabledTimeline.title }}
 		</p>
 		<p :class="$style.disabledDescription">{{ i18n.ts._disabledTimeline.description }}</p>
@@ -100,7 +100,7 @@ async function setType() {
 }
 
 const menu = [{
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	text: i18n.ts.timeline,
 	action: setType,
 }, {
diff --git a/packages/frontend/src/ui/deck/widgets-column.vue b/packages/frontend/src/ui/deck/widgets-column.vue
index 5bd6d73976..736fb7d235 100644
--- a/packages/frontend/src/ui/deck/widgets-column.vue
+++ b/packages/frontend/src/ui/deck/widgets-column.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <XColumn :menu="menu" :naked="true" :column="column" :isStacked="isStacked">
-	<template #header><i class="ti ti-apps" style="margin-right: 8px;"></i>{{ column.name }}</template>
+	<template #header><i class="ph-squares-four ph-bold pg-lg" style="margin-right: 8px;"></i>{{ column.name }}</template>
 
 	<div :class="$style.root">
 		<div v-if="!(column.widgets && column.widgets.length > 0) && !edit" :class="$style.intro">{{ i18n.ts._deck.widgetsIntroduction }}</div>
@@ -49,7 +49,7 @@ function func() {
 }
 
 const menu = [{
-	icon: 'ti ti-pencil',
+	icon: 'ph-pencil ph-bold ph-lg',
 	text: i18n.ts.editWidgets,
 	action: func,
 }];
diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue
index 38168cc195..354110c406 100644
--- a/packages/frontend/src/ui/universal.vue
+++ b/packages/frontend/src/ui/universal.vue
@@ -22,14 +22,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<XWidgets/>
 	</div>
 
-	<button v-if="!isDesktop && !isMobile" :class="$style.widgetButton" class="_button" @click="widgetsShowing = true"><i class="ti ti-apps"></i></button>
+	<button v-if="!isDesktop && !isMobile" :class="$style.widgetButton" class="_button" @click="widgetsShowing = true"><i class="ph-squares-four ph-bold pg-lg"></i></button>
 
 	<div v-if="isMobile" ref="navFooter" :class="$style.nav">
-		<button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ti ti-menu-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
-		<button :class="$style.navButton" class="_button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ti ti-home"></i></button>
-		<button :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ti ti-bell"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
-		<button :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ti ti-apps"></i></button>
-		<button :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ti ti-pencil"></i></button>
+		<button :class="$style.navButton" class="_button" @click="drawerMenuShowing = true"><i :class="$style.navButtonIcon" class="ph-list ph-bold ph-lg-2"></i><span v-if="menuIndicated" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
+		<button :class="$style.navButton" class="_button" @click="mainRouter.currentRoute.value.name === 'index' ? top() : mainRouter.push('/')"><i :class="$style.navButtonIcon" class="ph-house ph-bold ph-lg"></i></button>
+		<button :class="$style.navButton" class="_button" @click="mainRouter.push('/my/notifications')"><i :class="$style.navButtonIcon" class="ph-bell ph-bold pg-lg"></i><span v-if="$i?.hasUnreadNotification" :class="$style.navButtonIndicator"><i class="_indicatorCircle"></i></span></button>
+		<button :class="$style.navButton" class="_button" @click="widgetsShowing = true"><i :class="$style.navButtonIcon" class="ph-squares-four ph-bold pg-lg"></i></button>
+		<button :class="$style.postButton" class="_button" @click="os.post()"><i :class="$style.navButtonIcon" class="ph-pencil ph-bold ph-lg"></i></button>
 	</div>
 
 	<Transition
@@ -80,7 +80,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		:leaveToClass="defaultStore.state.animation ? $style.transition_widgetsDrawer_leaveTo : ''"
 	>
 		<div v-if="widgetsShowing" :class="$style.widgetsDrawer">
-			<button class="_button" :class="$style.widgetsCloseButton" @click="widgetsShowing = false"><i class="ti ti-x"></i></button>
+			<button class="_button" :class="$style.widgetsCloseButton" @click="widgetsShowing = false"><i class="ph-x ph-bold ph-lg"></i></button>
 			<XWidgets/>
 		</div>
 	</Transition>
@@ -196,7 +196,7 @@ const onContextmenu = (ev) => {
 		type: 'label',
 		text: path,
 	}, {
-		icon: 'ti ti-window-maximize',
+		icon: 'ph-frame-corners ph-bold ph-lg',
 		text: i18n.ts.openInWindow,
 		action: () => {
 			os.pageWindow(path);
diff --git a/packages/frontend/src/ui/universal.widgets.vue b/packages/frontend/src/ui/universal.widgets.vue
index 44988e6df3..08ed6d324c 100644
--- a/packages/frontend/src/ui/universal.widgets.vue
+++ b/packages/frontend/src/ui/universal.widgets.vue
@@ -7,8 +7,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div>
 	<XWidgets :edit="editMode" :widgets="widgets" @addWidget="addWidget" @removeWidget="removeWidget" @updateWidget="updateWidget" @updateWidgets="updateWidgets" @exit="editMode = false"/>
 
-	<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" data-cy-widget-edit :class="$style.edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ti ti-pencil"></i> {{ i18n.ts.editWidgets }}</button>
+	<button v-if="editMode" class="_textButton" style="font-size: 0.9em;" @click="editMode = false"><i class="ph-check ph-bold ph-lg"></i> {{ i18n.ts.editWidgetsExit }}</button>
+	<button v-else class="_textButton" data-cy-widget-edit :class="$style.edit" style="font-size: 0.9em;" @click="editMode = true"><i class="ph-pencil ph-bold ph-lg"></i> {{ i18n.ts.editWidgets }}</button>
 </div>
 </template>
 
diff --git a/packages/frontend/src/ui/visitor.vue b/packages/frontend/src/ui/visitor.vue
index 2ed6e698dc..4d2678a4c5 100644
--- a/packages/frontend/src/ui/visitor.vue
+++ b/packages/frontend/src/ui/visitor.vue
@@ -15,14 +15,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<div class="main">
 		<div v-if="!root" class="header">
 			<div v-if="narrow === false" class="wide">
-				<MkA to="/" class="link" activeClass="active"><i class="ti ti-home icon"></i> {{ i18n.ts.home }}</MkA>
-				<MkA v-if="isTimelineAvailable" to="/timeline" class="link" activeClass="active"><i class="ti ti-message icon"></i> {{ i18n.ts.timeline }}</MkA>
-				<MkA to="/explore" class="link" activeClass="active"><i class="ti ti-hash icon"></i> {{ i18n.ts.explore }}</MkA>
-				<MkA to="/channels" class="link" activeClass="active"><i class="ti ti-device-tv icon"></i> {{ i18n.ts.channel }}</MkA>
+				<MkA to="/" class="link" activeClass="active"><i class="ph-house ph-bold ph-lg icon"></i> {{ i18n.ts.home }}</MkA>
+				<MkA v-if="isTimelineAvailable" to="/timeline" class="link" activeClass="active"><i class="ph-chat-text ph-bold ph-lg icon"></i> {{ i18n.ts.timeline }}</MkA>
+				<MkA to="/explore" class="link" activeClass="active"><i class="ph-hash ph-bold ph-lg icon"></i> {{ i18n.ts.explore }}</MkA>
+				<MkA to="/channels" class="link" activeClass="active"><i class="ph-television ph-bold ph-lg icon"></i> {{ i18n.ts.channel }}</MkA>
 			</div>
 			<div v-else-if="narrow === true" class="narrow">
 				<button class="menu _button" @click="showMenu = true">
-					<i class="ti ti-menu-2 icon"></i>
+					<i class="ph-list ph-bold ph-lg-2 icon"></i>
 				</button>
 			</div>
 		</div>
@@ -47,15 +47,15 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 	<Transition :name="'tray'">
 		<div v-if="showMenu" class="menu">
-			<MkA to="/" class="link" activeClass="active"><i class="ti ti-home icon"></i>{{ i18n.ts.home }}</MkA>
-			<MkA v-if="isTimelineAvailable" to="/timeline" class="link" activeClass="active"><i class="ti ti-message icon"></i>{{ i18n.ts.timeline }}</MkA>
-			<MkA to="/explore" class="link" activeClass="active"><i class="ti ti-hash icon"></i>{{ i18n.ts.explore }}</MkA>
-			<MkA to="/announcements" class="link" activeClass="active"><i class="ti ti-speakerphone icon"></i>{{ i18n.ts.announcements }}</MkA>
-			<MkA to="/channels" class="link" activeClass="active"><i class="ti ti-device-tv icon"></i>{{ i18n.ts.channel }}</MkA>
+			<MkA to="/" class="link" activeClass="active"><i class="ph-house ph-bold ph-lg icon"></i>{{ i18n.ts.home }}</MkA>
+			<MkA v-if="isTimelineAvailable" to="/timeline" class="link" activeClass="active"><i class="ph-chat-text ph-bold ph-lg icon"></i>{{ i18n.ts.timeline }}</MkA>
+			<MkA to="/explore" class="link" activeClass="active"><i class="ph-hash ph-bold ph-lg icon"></i>{{ i18n.ts.explore }}</MkA>
+			<MkA to="/announcements" class="link" activeClass="active"><i class="ph-megaphone ph-bold ph-lg icon"></i>{{ i18n.ts.announcements }}</MkA>
+			<MkA to="/channels" class="link" activeClass="active"><i class="ph-television ph-bold ph-lg icon"></i>{{ i18n.ts.channel }}</MkA>
 			<div class="divider"></div>
-			<MkA to="/pages" class="link" activeClass="active"><i class="ti ti-news icon"></i>{{ i18n.ts.pages }}</MkA>
-			<MkA to="/play" class="link" activeClass="active"><i class="ti ti-player-play icon"></i>Play</MkA>
-			<MkA to="/gallery" class="link" activeClass="active"><i class="ti ti-icons icon"></i>{{ i18n.ts.gallery }}</MkA>
+			<MkA to="/pages" class="link" activeClass="active"><i class="ph-newspaper ph-bold ph-lg icon"></i>{{ i18n.ts.pages }}</MkA>
+			<MkA to="/play" class="link" activeClass="active"><i class="ph-play ph-bold pg-lg icon"></i>Play</MkA>
+			<MkA to="/gallery" class="link" activeClass="active"><i class="ph-images-square ph-bold pg-lgs icon"></i>{{ i18n.ts.gallery }}</MkA>
 			<div class="action">
 				<button class="_buttonPrimary" @click="signup()">{{ i18n.ts.signup }}</button>
 				<button class="_button" @click="signin()">{{ i18n.ts.login }}</button>
@@ -273,7 +273,7 @@ defineExpose({
 				padding: 10px;
 				box-sizing: border-box;
 				text-align: center;
-				border-radius: 999px;
+				border-radius: 4px;
 
 				&._button {
 					background: var(--panel);
diff --git a/packages/frontend/src/ui/zen.vue b/packages/frontend/src/ui/zen.vue
index 4f0945eb48..4448763e7a 100644
--- a/packages/frontend/src/ui/zen.vue
+++ b/packages/frontend/src/ui/zen.vue
@@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	See https://github.com/misskey-dev/misskey/issues/10905
 -->
 <div v-if="showBottom" :class="$style.bottom">
-	<button v-tooltip="i18n.ts.goToMisskey" :class="['_button', '_shadow', $style.button]" @click="goToMisskey"><i class="ti ti-home"></i></button>
+	<button v-tooltip="i18n.ts.goToMisskey" :class="['_button', '_shadow', $style.button]" @click="goToMisskey"><i class="ph-house ph-bold ph-lg"></i></button>
 </div>
 </template>
 
diff --git a/packages/frontend/src/widgets/WidgetActivity.vue b/packages/frontend/src/widgets/WidgetActivity.vue
index ed969abcfc..e4fb5f291e 100644
--- a/packages/frontend/src/widgets/WidgetActivity.vue
+++ b/packages/frontend/src/widgets/WidgetActivity.vue
@@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" :naked="widgetProps.transparent" data-cy-mkw-activity class="mkw-activity">
-	<template #icon><i class="ti ti-chart-line"></i></template>
+	<template #icon><i class="ph-chart-line ph-bold pg-lg"></i></template>
 	<template #header>{{ i18n.ts._widgets.activity }}</template>
-	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="toggleView()"><i class="ti ti-selector"></i></button></template>
+	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="toggleView()"><i class="ph-caret-up-down ph-bold ph-lg"></i></button></template>
 
 	<div>
 		<MkLoading v-if="fetching"/>
diff --git a/packages/frontend/src/widgets/WidgetAiscript.vue b/packages/frontend/src/widgets/WidgetAiscript.vue
index 4b927563f8..36bddcb229 100644
--- a/packages/frontend/src/widgets/WidgetAiscript.vue
+++ b/packages/frontend/src/widgets/WidgetAiscript.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" data-cy-mkw-aiscript class="mkw-aiscript">
-	<template #icon><i class="ti ti-terminal-2"></i></template>
+	<template #icon><i class="ph-terminal-window ph-bold ph-lg-2"></i></template>
 	<template #header>{{ i18n.ts._widgets.aiscript }}</template>
 
 	<div class="uylguesu _monospace">
diff --git a/packages/frontend/src/widgets/WidgetCalendar.vue b/packages/frontend/src/widgets/WidgetCalendar.vue
index 4b592203ec..08537b42c8 100644
--- a/packages/frontend/src/widgets/WidgetCalendar.vue
+++ b/packages/frontend/src/widgets/WidgetCalendar.vue
@@ -208,7 +208,7 @@ defineExpose<WidgetComponentExpose>({
 	width: 100%;
 	overflow: hidden;
 	background: var(--X11);
-	border-radius: 8px;
+	border-radius: 5px;
 }
 
 .meterVal {
diff --git a/packages/frontend/src/widgets/WidgetClicker.vue b/packages/frontend/src/widgets/WidgetClicker.vue
index 9b19c007de..1f7d9d35c8 100644
--- a/packages/frontend/src/widgets/WidgetClicker.vue
+++ b/packages/frontend/src/widgets/WidgetClicker.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" class="mkw-clicker">
-	<template #icon><i class="ti ti-cookie"></i></template>
+	<template #icon><i class="ph-cookie ph-bold pg-lg"></i></template>
 	<template #header>Clicker</template>
 	<MkClickerGame/>
 </MkContainer>
diff --git a/packages/frontend/src/widgets/WidgetFederation.vue b/packages/frontend/src/widgets/WidgetFederation.vue
index 1d067aac69..dabeae7b98 100644
--- a/packages/frontend/src/widgets/WidgetFederation.vue
+++ b/packages/frontend/src/widgets/WidgetFederation.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" :foldable="foldable" :scrollable="scrollable" data-cy-mkw-federation class="mkw-federation">
-	<template #icon><i class="ti ti-whirl"></i></template>
+	<template #icon><i class="ph-globe-hemisphere-west ph-bold ph-lg"></i></template>
 	<template #header>{{ i18n.ts._widgets.federation }}</template>
 
 	<div class="wbrkwalb">
diff --git a/packages/frontend/src/widgets/WidgetInstanceInfo.vue b/packages/frontend/src/widgets/WidgetInstanceInfo.vue
index 48a1849090..ce4de307db 100644
--- a/packages/frontend/src/widgets/WidgetInstanceInfo.vue
+++ b/packages/frontend/src/widgets/WidgetInstanceInfo.vue
@@ -66,7 +66,7 @@ defineExpose<WidgetComponentExpose>({
 	display: inline-block;
 	width: 60px;
 	height: 60px;
-	border-radius: 8px;
+	border-radius: 5px;
 	box-sizing: border-box;
 	border: solid 3px #fff;
 }
diff --git a/packages/frontend/src/widgets/WidgetJobQueue.vue b/packages/frontend/src/widgets/WidgetJobQueue.vue
index e0025a8074..b6a5af7425 100644
--- a/packages/frontend/src/widgets/WidgetJobQueue.vue
+++ b/packages/frontend/src/widgets/WidgetJobQueue.vue
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <div data-cy-mkw-jobQueue class="mkw-jobQueue _monospace" :class="{ _panel: !widgetProps.transparent }">
 	<div class="inbox">
-		<div class="label">Inbox queue<i v-if="current.inbox.waiting > 0" class="ti ti-alert-triangle icon"></i></div>
+		<div class="label">Inbox queue<i v-if="current.inbox.waiting > 0" class="ph-warning ph-bold ph-lg icon"></i></div>
 		<div class="values">
 			<div>
 				<div>Process</div>
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</div>
 	</div>
 	<div class="deliver">
-		<div class="label">Deliver queue<i v-if="current.deliver.waiting > 0" class="ti ti-alert-triangle icon"></i></div>
+		<div class="label">Deliver queue<i v-if="current.deliver.waiting > 0" class="ph-warning ph-bold ph-lg icon"></i></div>
 		<div class="values">
 			<div>
 				<div>Process</div>
diff --git a/packages/frontend/src/widgets/WidgetMemo.vue b/packages/frontend/src/widgets/WidgetMemo.vue
index c12afd50b0..3b44b2aa2e 100644
--- a/packages/frontend/src/widgets/WidgetMemo.vue
+++ b/packages/frontend/src/widgets/WidgetMemo.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" data-cy-mkw-memo class="mkw-memo">
-	<template #icon><i class="ti ti-note"></i></template>
+	<template #icon><i class="ph-note ph-bold ph-lg"></i></template>
 	<template #header>{{ i18n.ts._widgets.memo }}</template>
 
 	<div :class="$style.root">
diff --git a/packages/frontend/src/widgets/WidgetNotifications.vue b/packages/frontend/src/widgets/WidgetNotifications.vue
index b9999d8011..acf53fbcee 100644
--- a/packages/frontend/src/widgets/WidgetNotifications.vue
+++ b/packages/frontend/src/widgets/WidgetNotifications.vue
@@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :style="`height: ${widgetProps.height}px;`" :showHeader="widgetProps.showHeader" :scrollable="true" data-cy-mkw-notifications class="mkw-notifications">
-	<template #icon><i class="ti ti-bell"></i></template>
+	<template #icon><i class="ph-bell ph-bold pg-lg"></i></template>
 	<template #header>{{ i18n.ts.notifications }}</template>
-	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configureNotification()"><i class="ti ti-settings"></i></button></template>
+	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configureNotification()"><i class="ph-gear ph-bold pg-lg"></i></button></template>
 
 	<div>
 		<XNotifications :includeTypes="widgetProps.includingTypes"/>
diff --git a/packages/frontend/src/widgets/WidgetPhotos.vue b/packages/frontend/src/widgets/WidgetPhotos.vue
index 8c01d3cce9..46cf3893af 100644
--- a/packages/frontend/src/widgets/WidgetPhotos.vue
+++ b/packages/frontend/src/widgets/WidgetPhotos.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" :naked="widgetProps.transparent" :class="$style.root" :data-transparent="widgetProps.transparent ? true : null" data-cy-mkw-photos class="mkw-photos">
-	<template #icon><i class="ti ti-camera"></i></template>
+	<template #icon><i class="ph-camera ph-bold ph-lg"></i></template>
 	<template #header>{{ i18n.ts._widgets.photos }}</template>
 
 	<div class="">
@@ -101,7 +101,7 @@ defineExpose<WidgetComponentExpose>({
 
 	.img {
 		border: solid 4px transparent;
-		border-radius: 8px;
+		border-radius: 5px;
 	}
 }
 
diff --git a/packages/frontend/src/widgets/WidgetRss.vue b/packages/frontend/src/widgets/WidgetRss.vue
index 22833415dd..2f4a31097e 100644
--- a/packages/frontend/src/widgets/WidgetRss.vue
+++ b/packages/frontend/src/widgets/WidgetRss.vue
@@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" data-cy-mkw-rss class="mkw-rss">
-	<template #icon><i class="ti ti-rss"></i></template>
+	<template #icon><i class="ph-rss ph-bold ph-lg"></i></template>
 	<template #header>RSS</template>
-	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configure"><i class="ti ti-settings"></i></button></template>
+	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configure"><i class="ph-gear ph-bold pg-lg"></i></button></template>
 
 	<div class="ekmkgxbj">
 		<MkLoading v-if="fetching"/>
diff --git a/packages/frontend/src/widgets/WidgetRssTicker.vue b/packages/frontend/src/widgets/WidgetRssTicker.vue
index ce8142f1ad..d57479349c 100644
--- a/packages/frontend/src/widgets/WidgetRssTicker.vue
+++ b/packages/frontend/src/widgets/WidgetRssTicker.vue
@@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :naked="widgetProps.transparent" :showHeader="widgetProps.showHeader" class="mkw-rss-ticker">
-	<template #icon><i class="ti ti-rss"></i></template>
+	<template #icon><i class="ph-rss ph-bold ph-lg"></i></template>
 	<template #header>RSS</template>
-	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configure"><i class="ti ti-settings"></i></button></template>
+	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configure"><i class="ph-gear ph-bold pg-lg"></i></button></template>
 
 	<div :class="$style.feed">
 		<div v-if="fetching" :class="$style.loading">
diff --git a/packages/frontend/src/widgets/WidgetTimeline.vue b/packages/frontend/src/widgets/WidgetTimeline.vue
index 51623023c7..ae20ade151 100644
--- a/packages/frontend/src/widgets/WidgetTimeline.vue
+++ b/packages/frontend/src/widgets/WidgetTimeline.vue
@@ -6,23 +6,23 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" :style="`height: ${widgetProps.height}px;`" :scrollable="true" data-cy-mkw-timeline class="mkw-timeline">
 	<template #icon>
-		<i v-if="widgetProps.src === 'home'" class="ti ti-home"></i>
-		<i v-else-if="widgetProps.src === 'local'" class="ti ti-planet"></i>
-		<i v-else-if="widgetProps.src === 'social'" class="ti ti-rocket"></i>
-		<i v-else-if="widgetProps.src === 'global'" class="ti ti-whirl"></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>
+		<i v-if="widgetProps.src === 'home'" class="ph-house ph-bold ph-lg"></i>
+		<i v-else-if="widgetProps.src === 'local'" class="ph-planet ph-bold pg-lg"></i>
+		<i v-else-if="widgetProps.src === 'social'" class="ph-rocket-launch ph-bold pg-lg"></i>
+		<i v-else-if="widgetProps.src === 'global'" class="ph-globe-hemisphere-west ph-bold ph-lg"></i>
+		<i v-else-if="widgetProps.src === 'list'" class="ph-list ph-bold pg-lg"></i>
+		<i v-else-if="widgetProps.src === 'antenna'" class="ph-flying-saucer ph-bold pg-lg"></i>
 	</template>
 	<template #header>
 		<button class="_button" @click="choose">
 			<span>{{ widgetProps.src === 'list' ? widgetProps.list.name : widgetProps.src === 'antenna' ? widgetProps.antenna.name : i18n.t('_timelines.' + widgetProps.src) }}</span>
-			<i :class="menuOpened ? 'ti ti-chevron-up' : 'ti ti-chevron-down'" style="margin-left: 8px;"></i>
+			<i :class="menuOpened ? 'ph-caret-up ph-bold ph-lg' : 'ph-caret-down ph-bold ph-lg'" style="margin-left: 8px;"></i>
 		</button>
 	</template>
 
 	<div v-if="(((widgetProps.src === 'local' || widgetProps.src === 'social') && !isLocalTimelineAvailable) || (widgetProps.src === 'global' && !isGlobalTimelineAvailable))" :class="$style.disabled">
 		<p :class="$style.disabledTitle">
-			<i class="ti ti-minus"></i>
+			<i class="ph-minus ph-bold ph-lg"></i>
 			{{ i18n.ts._disabledTimeline.title }}
 		</p>
 		<p :class="$style.disabledDescription">{{ i18n.ts._disabledTimeline.description }}</p>
@@ -100,7 +100,7 @@ const choose = async (ev) => {
 	]);
 	const antennaItems = antennas.map(antenna => ({
 		text: antenna.name,
-		icon: 'ti ti-antenna',
+		icon: 'ph-flying-saucer ph-bold pg-lg',
 		action: () => {
 			widgetProps.antenna = antenna;
 			setSrc('antenna');
@@ -108,7 +108,7 @@ const choose = async (ev) => {
 	}));
 	const listItems = lists.map(list => ({
 		text: list.name,
-		icon: 'ti ti-list',
+		icon: 'ph-list ph-bold pg-lg',
 		action: () => {
 			widgetProps.list = list;
 			setSrc('list');
@@ -116,19 +116,19 @@ const choose = async (ev) => {
 	}));
 	os.popupMenu([{
 		text: i18n.ts._timelines.home,
-		icon: 'ti ti-home',
+		icon: 'ph-house ph-bold ph-lg',
 		action: () => { setSrc('home'); },
 	}, {
 		text: i18n.ts._timelines.local,
-		icon: 'ti ti-planet',
+		icon: 'ph-planet ph-bold pg-lg',
 		action: () => { setSrc('local'); },
 	}, {
 		text: i18n.ts._timelines.social,
-		icon: 'ti ti-rocket',
+		icon: 'ph-rocket-launch ph-bold pg-lg',
 		action: () => { setSrc('social'); },
 	}, {
 		text: i18n.ts._timelines.global,
-		icon: 'ti ti-whirl',
+		icon: 'ph-globe-hemisphere-west ph-bold ph-lg',
 		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/frontend/src/widgets/WidgetTrends.vue b/packages/frontend/src/widgets/WidgetTrends.vue
index 0a57305526..3c72d1f751 100644
--- a/packages/frontend/src/widgets/WidgetTrends.vue
+++ b/packages/frontend/src/widgets/WidgetTrends.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" data-cy-mkw-trends class="mkw-trends">
-	<template #icon><i class="ti ti-hash"></i></template>
+	<template #icon><i class="ph-hash ph-bold ph-lg"></i></template>
 	<template #header>{{ i18n.ts._widgets.trends }}</template>
 
 	<div class="wbrkwala">
diff --git a/packages/frontend/src/widgets/WidgetUserList.vue b/packages/frontend/src/widgets/WidgetUserList.vue
index 343e9a4292..87bef1909a 100644
--- a/packages/frontend/src/widgets/WidgetUserList.vue
+++ b/packages/frontend/src/widgets/WidgetUserList.vue
@@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" class="mkw-userList">
-	<template #icon><i class="ti ti-users"></i></template>
+	<template #icon><i class="ph-users ph-bold pg-lg"></i></template>
 	<template #header>{{ list ? list.name : i18n.ts._widgets.userList }}</template>
-	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configure()"><i class="ti ti-settings"></i></button></template>
+	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="configure()"><i class="ph-gear ph-bold pg-lg"></i></button></template>
 
 	<div :class="$style.root">
 		<div v-if="widgetProps.listId == null" class="init">
diff --git a/packages/frontend/src/widgets/server-metric/cpu.vue b/packages/frontend/src/widgets/server-metric/cpu.vue
index 1c9cce8598..65da16a632 100644
--- a/packages/frontend/src/widgets/server-metric/cpu.vue
+++ b/packages/frontend/src/widgets/server-metric/cpu.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="vrvdvrys">
 	<XPie class="pie" :value="usage"/>
 	<div>
-		<p><i class="ti ti-cpu"></i>CPU</p>
+		<p><i class="ph-cpu ph-bold ph-lg"></i>CPU</p>
 		<p>{{ meta.cpu.cores }} Logical cores</p>
 		<p>{{ meta.cpu.model }}</p>
 	</div>
diff --git a/packages/frontend/src/widgets/server-metric/disk.vue b/packages/frontend/src/widgets/server-metric/disk.vue
index 079b326fd6..2ef9272179 100644
--- a/packages/frontend/src/widgets/server-metric/disk.vue
+++ b/packages/frontend/src/widgets/server-metric/disk.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="zbwaqsat">
 	<XPie class="pie" :value="usage"/>
 	<div>
-		<p><i class="ti ti-database"></i>Disk</p>
+		<p><i class="ph-database ph-bold pg-lg"></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/frontend/src/widgets/server-metric/index.vue b/packages/frontend/src/widgets/server-metric/index.vue
index f070dbbbe1..57fbb6811b 100644
--- a/packages/frontend/src/widgets/server-metric/index.vue
+++ b/packages/frontend/src/widgets/server-metric/index.vue
@@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkContainer :showHeader="widgetProps.showHeader" :naked="widgetProps.transparent">
-	<template #icon><i class="ti ti-server"></i></template>
+	<template #icon><i class="ph-hard-drives ph-bold ph-lg"></i></template>
 	<template #header>{{ i18n.ts._widgets.serverMetric }}</template>
-	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="toggleView()"><i class="ti ti-selector"></i></button></template>
+	<template #func="{ buttonStyleClass }"><button class="_button" :class="buttonStyleClass" @click="toggleView()"><i class="ph-caret-up-down ph-bold ph-lg"></i></button></template>
 
 	<div v-if="meta" data-cy-mkw-serverMetric class="mkw-serverMetric">
 		<XCpuMemory v-if="widgetProps.view === 0" :connection="connection" :meta="meta"/>
diff --git a/packages/frontend/src/widgets/server-metric/mem.vue b/packages/frontend/src/widgets/server-metric/mem.vue
index 47f5a70a7e..5a57ef6e1e 100644
--- a/packages/frontend/src/widgets/server-metric/mem.vue
+++ b/packages/frontend/src/widgets/server-metric/mem.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="zlxnikvl">
 	<XPie class="pie" :value="usage"/>
 	<div>
-		<p><i class="ti ti-section"></i>RAM</p>
+		<p><i class="ph-selection-all ph-bold ph-lg"></i>RAM</p>
 		<p>Total: {{ bytes(total, 1) }}</p>
 		<p>Used: {{ bytes(used, 1) }}</p>
 		<p>Free: {{ bytes(free, 1) }}</p>