From 1ac1a968b9edd801aa13e8dae56ca378744d9e2e Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Thu, 30 Sep 2021 00:50:45 +0900
Subject: [PATCH] refactor components

---
 CONTRIBUTING.md                               |   4 +
 locales/ja-JP.yml                             |   2 +
 package.json                                  |   6 +-
 src/client/components/abuse-report-window.vue |   2 +-
 src/client/components/cw-button.vue           |   8 +-
 .../components/{form => debobigego}/base.vue  |  24 +-
 .../{form => debobigego}/button.vue           |  10 +-
 .../form.scss => debobigego/debobigego.scss}  |  24 +-
 .../components/{form => debobigego}/group.vue |  26 +-
 .../components/{form => debobigego}/info.vue  |   4 +-
 .../components/{ui => debobigego}/input.vue   | 173 +++++-------
 .../{form => debobigego}/key-value-view.vue   |   8 +-
 .../components/{form => debobigego}/link.vue  |   8 +-
 .../{form => debobigego}/object-view.vue      |  10 +-
 .../{form => debobigego}/pagination.vue       |   2 +-
 src/client/components/debobigego/radios.vue   | 112 ++++++++
 src/client/components/debobigego/range.vue    | 122 ++++++++
 src/client/components/debobigego/select.vue   | 145 ++++++++++
 .../{form => debobigego}/suspense.vue         |  12 +-
 src/client/components/debobigego/switch.vue   | 132 +++++++++
 src/client/components/debobigego/textarea.vue | 161 +++++++++++
 .../components/{form => debobigego}/tuple.vue |   2 +-
 src/client/components/dialog.vue              |   4 +-
 src/client/components/forgot-password.vue     |   2 +-
 src/client/components/form-dialog.vue         |  28 +-
 src/client/components/form/input.vue          | 183 ++++++------
 src/client/components/{ui => form}/radio.vue  |   0
 src/client/components/form/radios.vue         |  88 ++----
 src/client/components/form/range.vue          | 141 +++++-----
 src/client/components/form/section.vue        |  31 +++
 src/client/components/form/select.vue         | 247 ++++++++++++-----
 src/client/components/form/slot.vue           |  50 ++++
 src/client/components/form/switch.vue         | 192 +++++++------
 src/client/components/form/textarea.vue       | 195 +++++++++----
 src/client/components/instance-stats.vue      |   2 +-
 src/client/components/note-detailed.vue       |   2 +-
 src/client/components/note-preview.vue        |   2 +-
 src/client/components/note.sub.vue            |   2 +-
 src/client/components/note.vue                |   2 +-
 .../notification-setting-window.vue           |   2 +-
 .../components/page/page.number-input.vue     |   2 +-
 src/client/components/page/page.post.vue      |   2 +-
 .../components/page/page.radio-button.vue     |   2 +-
 src/client/components/page/page.switch.vue    |   2 +-
 .../components/page/page.text-input.vue       |   2 +-
 .../components/page/page.textarea-input.vue   |   2 +-
 src/client/components/page/page.textarea.vue  |   2 +-
 src/client/components/poll-editor.vue         |   6 +-
 src/client/components/sample.vue              |   8 +-
 src/client/components/signin.vue              |  10 +-
 src/client/components/signup.vue              |  22 +-
 src/client/components/tab.vue                 |   8 +-
 .../components/taskmanager.api-window.vue     |   2 +-
 src/client/components/taskmanager.vue         |   2 +-
 .../components/token-generate-window.vue      |   6 +-
 src/client/components/ui/button.vue           |   8 -
 src/client/components/ui/radios.vue           |  58 ----
 src/client/components/ui/range.vue            | 139 ----------
 src/client/components/ui/select.vue           | 262 ------------------
 src/client/components/ui/switch.vue           | 144 ----------
 src/client/components/ui/textarea.vue         | 254 -----------------
 src/client/components/user-select-dialog.vue  |   4 +-
 src/client/components/widgets.vue             |   2 +-
 src/client/pages/about-misskey.vue            |  14 +-
 src/client/pages/about.vue                    |  16 +-
 src/client/pages/advanced-theme-editor.vue    |  30 +-
 src/client/pages/api-console.vue              |   8 +-
 src/client/pages/channel-editor.vue           |   4 +-
 src/client/pages/channels.vue                 |   2 +-
 src/client/pages/docs.vue                     |   4 +-
 src/client/pages/emojis.category.vue          |   6 +-
 src/client/pages/explore.vue                  |   2 +-
 src/client/pages/federation.vue               |   8 +-
 src/client/pages/gallery/edit.vue             |  24 +-
 src/client/pages/gallery/index.vue            |   4 +-
 src/client/pages/instance-info.vue            |  28 +-
 src/client/pages/instance/abuses.vue          |   8 +-
 src/client/pages/instance/ads.vue             |   6 +-
 src/client/pages/instance/announcements.vue   |   4 +-
 src/client/pages/instance/bot-protection.vue  |  42 +--
 src/client/pages/instance/database.vue        |  10 +-
 src/client/pages/instance/email-settings.vue  |  32 +--
 .../pages/instance/emoji-edit-dialog.vue      |   2 +-
 src/client/pages/instance/emojis.vue          |   4 +-
 src/client/pages/instance/file-dialog.vue     |   2 +-
 src/client/pages/instance/files-settings.vue  |  20 +-
 src/client/pages/instance/files.vue           |   4 +-
 src/client/pages/instance/index.vue           |  12 +-
 src/client/pages/instance/instance-block.vue  |  18 +-
 src/client/pages/instance/instance.vue        |   4 +-
 .../pages/instance/integrations-discord.vue   |  18 +-
 .../pages/instance/integrations-github.vue    |  18 +-
 .../pages/instance/integrations-twitter.vue   |  18 +-
 src/client/pages/instance/integrations.vue    |  16 +-
 src/client/pages/instance/logs.vue            |   6 +-
 src/client/pages/instance/metrics.vue         |  22 +-
 src/client/pages/instance/object-storage.vue  |  36 +--
 src/client/pages/instance/other-settings.vue  |  18 +-
 src/client/pages/instance/overview.vue        |  24 +-
 src/client/pages/instance/proxy-account.vue   |  16 +-
 src/client/pages/instance/queue.chart.vue     |   6 +-
 src/client/pages/instance/queue.vue           |   4 +-
 src/client/pages/instance/relays.vue          |  10 +-
 src/client/pages/instance/security.vue        |  16 +-
 src/client/pages/instance/service-worker.vue  |  18 +-
 src/client/pages/instance/settings.vue        |  38 +--
 src/client/pages/instance/users.vue           |   4 +-
 src/client/pages/mfm-cheat-sheet.vue          |   2 +-
 src/client/pages/my-antennas/editor.vue       |  10 +-
 src/client/pages/my-groups/index.vue          |   2 +-
 .../page-editor/els/page-editor.el.button.vue |   6 +-
 .../page-editor/els/page-editor.el.canvas.vue |   2 +-
 .../els/page-editor.el.counter.vue            |   2 +-
 .../page-editor/els/page-editor.el.if.vue     |   4 +-
 .../page-editor/els/page-editor.el.note.vue   |   4 +-
 .../els/page-editor.el.number-input.vue       |   2 +-
 .../page-editor/els/page-editor.el.post.vue   |   6 +-
 .../els/page-editor.el.radio-button.vue       |   4 +-
 .../els/page-editor.el.section.vue            |   2 +-
 .../page-editor/els/page-editor.el.switch.vue |   4 +-
 .../els/page-editor.el.text-input.vue         |   2 +-
 .../els/page-editor.el.textarea-input.vue     |   4 +-
 .../pages/page-editor/page-editor.blocks.vue  |  13 +-
 .../page-editor/page-editor.script-block.vue  |  94 +++----
 src/client/pages/page-editor/page-editor.vue  |  10 +-
 src/client/pages/pages.vue                    |   2 +-
 src/client/pages/reset-password.vue           |  12 +-
 src/client/pages/reversi/game.setting.vue     |   4 +-
 src/client/pages/room/room.vue                |   2 +-
 src/client/pages/settings/2fa.vue             |  10 +-
 src/client/pages/settings/account-info.vue    |  10 +-
 src/client/pages/settings/accounts.vue        |  15 +-
 src/client/pages/settings/api.vue             |  11 +-
 src/client/pages/settings/apps.vue            |  13 +-
 src/client/pages/settings/custom-css.vue      |  15 +-
 src/client/pages/settings/deck.vue            |  15 +-
 src/client/pages/settings/delete-account.vue  |  11 +-
 src/client/pages/settings/drive.vue           |  21 +-
 src/client/pages/settings/email-address.vue   |  11 +-
 .../pages/settings/email-notification.vue     |  21 +-
 src/client/pages/settings/email.vue           |  15 +-
 .../pages/settings/experimental-features.vue  |  10 +-
 src/client/pages/settings/general.vue         |  61 ++--
 src/client/pages/settings/import-export.vue   |   9 +-
 src/client/pages/settings/index.link.vue      |  97 +++++++
 src/client/pages/settings/index.vue           |  99 ++++---
 src/client/pages/settings/integration.vue     |  23 +-
 src/client/pages/settings/menu.vue            |  15 +-
 src/client/pages/settings/mute-block.vue      |  13 +-
 src/client/pages/settings/notifications.vue   |  11 +-
 src/client/pages/settings/other.vue           |  17 +-
 src/client/pages/settings/plugin.install.vue  |  15 +-
 src/client/pages/settings/plugin.manage.vue   |  21 +-
 src/client/pages/settings/plugin.vue          |   9 +-
 src/client/pages/settings/privacy.vue         |  29 +-
 src/client/pages/settings/profile.vue         |  35 +--
 src/client/pages/settings/reaction.vue        |  19 +-
 src/client/pages/settings/registry.keys.vue   |  13 +-
 src/client/pages/settings/registry.value.vue  |  15 +-
 src/client/pages/settings/registry.vue        |  13 +-
 src/client/pages/settings/security.vue        |  15 +-
 src/client/pages/settings/sounds.vue          |  15 +-
 src/client/pages/settings/theme.install.vue   |  13 +-
 src/client/pages/settings/theme.manage.vue    |  11 +-
 src/client/pages/settings/theme.vue           |  27 +-
 src/client/pages/settings/update.vue          |  15 +-
 src/client/pages/settings/word-mute.vue       |  19 +-
 src/client/pages/test.vue                     |   8 +-
 src/client/pages/theme-editor.vue             |  30 +-
 src/client/pages/user-ap-info.vue             |  16 +-
 src/client/pages/user-info.vue                |  26 +-
 src/client/pages/user/index.timeline.vue      |   2 +-
 src/client/pages/welcome.setup.vue            |   2 +-
 src/client/style.scss                         |  14 +-
 src/client/ui/_common_/sidebar.vue            |   2 +-
 src/client/ui/chat/note-preview.vue           |   2 +-
 src/client/ui/chat/note.sub.vue               |   2 +-
 src/client/ui/chat/note.vue                   |   2 +-
 yarn.lock                                     | 166 +++++------
 179 files changed, 2611 insertions(+), 2386 deletions(-)
 rename src/client/components/{form => debobigego}/base.vue (63%)
 rename src/client/components/{form => debobigego}/button.vue (77%)
 rename src/client/components/{form/form.scss => debobigego/debobigego.scss} (52%)
 rename src/client/components/{form => debobigego}/group.vue (57%)
 rename src/client/components/{form => debobigego}/info.vue (87%)
 rename src/client/components/{ui => debobigego}/input.vue (62%)
 rename src/client/components/{form => debobigego}/key-value-view.vue (78%)
 rename src/client/components/{form => debobigego}/link.vue (84%)
 rename src/client/components/{form => debobigego}/object-view.vue (88%)
 rename src/client/components/{form => debobigego}/pagination.vue (95%)
 create mode 100644 src/client/components/debobigego/radios.vue
 create mode 100644 src/client/components/debobigego/range.vue
 create mode 100644 src/client/components/debobigego/select.vue
 rename src/client/components/{form => debobigego}/suspense.vue (87%)
 create mode 100644 src/client/components/debobigego/switch.vue
 create mode 100644 src/client/components/debobigego/textarea.vue
 rename src/client/components/{form => debobigego}/tuple.vue (87%)
 rename src/client/components/{ui => form}/radio.vue (100%)
 create mode 100644 src/client/components/form/section.vue
 create mode 100644 src/client/components/form/slot.vue
 delete mode 100644 src/client/components/ui/radios.vue
 delete mode 100644 src/client/components/ui/range.vue
 delete mode 100644 src/client/components/ui/select.vue
 delete mode 100644 src/client/components/ui/switch.vue
 delete mode 100644 src/client/components/ui/textarea.vue
 create mode 100644 src/client/pages/settings/index.link.vue

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 72a7dc4b16..06154f1f44 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -177,6 +177,10 @@ npx ts-node ./node_modules/typeorm/cli.js migration:generate -n 変更の名前
 ### JSONのimportに気を付けよう
 TypeScriptでjsonをimportすると、tscでコンパイルするときにそのjsonファイルも一緒にdistディレクトリに吐き出されてしまう。この挙動により、意図せずファイルの書き換えが発生することがあるので、jsonをimportするときは書き換えられても良いものかどうか確認すること。書き換えされて欲しくない場合は、importで読み込むのではなく、`fs.readFileSync`などの関数を使って読み込むようにすればよい。
 
+### コンポーネントのスタイル定義でmarginを持たせない
+コンポーネント自身がmarginを設定するのは問題の元となることはよく知られている
+marginはそのコンポーネントを使う側が設定する
+
 ## その他
 ### HTMLのクラス名で follow という単語は使わない
 広告ブロッカーで誤ってブロックされる
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index f050ad4df8..f5f859b9ff 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -787,6 +787,8 @@ pubSub: "Pub/Subのアカウント"
 lastCommunication: "直近の通信"
 resolved: "解決済み"
 unresolved: "未解決"
+itsOn: "オンになっています"
+itsOff: "オフになっています"
 
 _accountDelete:
   accountDelete: "アカウントの削除"
diff --git a/package.json b/package.json
index 2d0c1cc5fc..9f37bea172 100644
--- a/package.json
+++ b/package.json
@@ -104,7 +104,7 @@
 		"@types/websocket": "1.0.4",
 		"@types/ws": "7.4.7",
 		"@typescript-eslint/parser": "4.31.2",
-		"@vue/compiler-sfc": "3.2.13",
+		"@vue/compiler-sfc": "3.2.19",
 		"abort-controller": "3.0.0",
 		"apexcharts": "3.28.3",
 		"autobind-decorator": "2.4.0",
@@ -233,7 +233,7 @@
 		"uuid": "8.3.2",
 		"v-debounce": "0.1.2",
 		"vanilla-tilt": "1.7.2",
-		"vue": "3.2.13",
+		"vue": "3.2.19",
 		"vue-loader": "16.7.0",
 		"vue-prism-editor": "2.0.0-alpha.2",
 		"vue-router": "4.0.5",
@@ -241,7 +241,7 @@
 		"vue-svg-loader": "0.17.0-beta.2",
 		"vuedraggable": "4.0.1",
 		"web-push": "3.4.5",
-		"webpack": "5.53.0",
+		"webpack": "5.54.0",
 		"webpack-cli": "4.8.0",
 		"websocket": "1.0.34",
 		"ws": "8.2.2",
diff --git a/src/client/components/abuse-report-window.vue b/src/client/components/abuse-report-window.vue
index 266c0d566f..21a19385ae 100644
--- a/src/client/components/abuse-report-window.vue
+++ b/src/client/components/abuse-report-window.vue
@@ -25,7 +25,7 @@
 <script lang="ts">
 import { defineComponent, markRaw } from 'vue';
 import XWindow from '@client/components/ui/window.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
 import MkButton from '@client/components/ui/button.vue';
 import * as os from '@client/os';
 
diff --git a/src/client/components/cw-button.vue b/src/client/components/cw-button.vue
index d2336085ad..3a172f5d5e 100644
--- a/src/client/components/cw-button.vue
+++ b/src/client/components/cw-button.vue
@@ -1,7 +1,7 @@
 <template>
 <button class="nrvgflfu _button" @click="toggle">
-	<b>{{ value ? $ts._cw.hide : $ts._cw.show }}</b>
-	<span v-if="!value">{{ label }}</span>
+	<b>{{ modelValue ? $ts._cw.hide : $ts._cw.show }}</b>
+	<span v-if="!modelValue">{{ label }}</span>
 </button>
 </template>
 
@@ -12,7 +12,7 @@ import { concat } from '../../prelude/array';
 
 export default defineComponent({
 	props: {
-		value: {
+		modelValue: {
 			type: Boolean,
 			required: true
 		},
@@ -36,7 +36,7 @@ export default defineComponent({
 		length,
 
 		toggle() {
-			this.$emit('update:value', !this.value);
+			this.$emit('update:modelValue', !this.modelValue);
 		}
 	}
 });
diff --git a/src/client/components/form/base.vue b/src/client/components/debobigego/base.vue
similarity index 63%
rename from src/client/components/form/base.vue
rename to src/client/components/debobigego/base.vue
index 132942d527..f551a3478b 100644
--- a/src/client/components/form/base.vue
+++ b/src/client/components/debobigego/base.vue
@@ -21,39 +21,39 @@ export default defineComponent({
 <style lang="scss" scoped>
 .rbusrurv {
 	// 他のCSSからも参照されるので消さないように
-	--formXPadding: 32px;
-	--formYPadding: 32px;
+	--debobigegoXPadding: 32px;
+	--debobigegoYPadding: 32px;
 
-	--formContentHMargin: 16px;
+	--debobigegoContentHMargin: 16px;
 
 	font-size: 95%;
 	line-height: 1.3em;
 	background: var(--bg);
-	padding: var(--formYPadding) var(--formXPadding);
+	padding: var(--debobigegoYPadding) var(--debobigegoXPadding);
 	max-width: 750px;
 	margin: 0 auto;
 
 	&:not(.wide).max-width_400px {
-		--formXPadding: 0px;
+		--debobigegoXPadding: 0px;
 
 		> ::v-deep(*) {
-			._formPanel {
+			._debobigegoPanel {
 				border: solid 0.5px var(--divider);
 				border-radius: 0;
 				border-left: none;
 				border-right: none;
 			}
 
-			._form_group {
-				> *:not(._formNoConcat) {
-					&:not(:last-child):not(._formNoConcatPrev) {
-						&._formPanel, ._formPanel {
+			._debobigego_group {
+				> *:not(._debobigegoNoConcat) {
+					&:not(:last-child):not(._debobigegoNoConcatPrev) {
+						&._debobigegoPanel, ._debobigegoPanel {
 							border-bottom: solid 0.5px var(--divider);
 						}
 					}
 
-					&:not(:first-child):not(._formNoConcatNext) {
-						&._formPanel, ._formPanel {
+					&:not(:first-child):not(._debobigegoNoConcatNext) {
+						&._debobigegoPanel, ._debobigegoPanel {
 							border-top: none;
 						}
 					}
diff --git a/src/client/components/form/button.vue b/src/client/components/debobigego/button.vue
similarity index 77%
rename from src/client/components/form/button.vue
rename to src/client/components/debobigego/button.vue
index b4f0890945..b883e817a4 100644
--- a/src/client/components/form/button.vue
+++ b/src/client/components/debobigego/button.vue
@@ -1,7 +1,7 @@
 <template>
-<div class="yzpgjkxe _formItem">
-	<div class="_formLabel"><slot name="label"></slot></div>
-	<button class="main _button _formPanel _formClickable" :class="{ center, primary, danger }">
+<div class="yzpgjkxe _debobigegoItem">
+	<div class="_debobigegoLabel"><slot name="label"></slot></div>
+	<button class="main _button _debobigegoPanel _debobigegoClickable" :class="{ center, primary, danger }">
 		<slot></slot>
 		<div class="suffix">
 			<slot name="suffix"></slot>
@@ -10,13 +10,13 @@
 			</div>
 		</div>
 	</button>
-	<div class="_formCaption"><slot name="desc"></slot></div>
+	<div class="_debobigegoCaption"><slot name="desc"></slot></div>
 </div>
 </template>
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import './form.scss';
+import './debobigego.scss';
 
 export default defineComponent({
 	props: {
diff --git a/src/client/components/form/form.scss b/src/client/components/debobigego/debobigego.scss
similarity index 52%
rename from src/client/components/form/form.scss
rename to src/client/components/debobigego/debobigego.scss
index 00f40df9b1..833b656b66 100644
--- a/src/client/components/form/form.scss
+++ b/src/client/components/debobigego/debobigego.scss
@@ -1,9 +1,9 @@
-._formPanel {
+._debobigegoPanel {
 	background: var(--panel);
 	border-radius: var(--radius);
 	transition: background 0.2s ease;
 
-	&._formClickable {
+	&._debobigegoClickable {
 		&:hover {
 			//background: var(--panelHighlight);
 		}
@@ -15,8 +15,8 @@
 	}
 }
 
-._formLabel,
-._formCaption {
+._debobigegoLabel,
+._debobigegoCaption {
 	font-size: 80%;
 	color: var(--fgTransparentWeak);
 
@@ -25,28 +25,28 @@
 	}
 }
 
-._formLabel {
+._debobigegoLabel {
 	position: sticky;
 	top: var(--stickyTop, 0px);
 	z-index: 2;
-	margin: -8px calc(var(--formXPadding) * -1) 0 calc(var(--formXPadding) * -1);
-	padding: 8px calc(var(--formContentHMargin) + var(--formXPadding)) 8px calc(var(--formContentHMargin) + var(--formXPadding));
+	margin: -8px calc(var(--debobigegoXPadding) * -1) 0 calc(var(--debobigegoXPadding) * -1);
+	padding: 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding)) 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding));
 	background: var(--X17);
 	-webkit-backdrop-filter: var(--blur, blur(10px));
 	backdrop-filter: var(--blur, blur(10px));
 }
 
-._themeChanging_ ._formLabel {
+._themeChanging_ ._debobigegoLabel {
 	transition: none !important;
 	background: transparent;
 }
 
-._formCaption {
-	padding: 8px var(--formContentHMargin) 0 var(--formContentHMargin);
+._debobigegoCaption {
+	padding: 8px var(--debobigegoContentHMargin) 0 var(--debobigegoContentHMargin);
 }
 
-._formItem {
-	& + ._formItem {
+._debobigegoItem {
+	& + ._debobigegoItem {
 		margin-top: 24px;
 	}
 }
diff --git a/src/client/components/form/group.vue b/src/client/components/debobigego/group.vue
similarity index 57%
rename from src/client/components/form/group.vue
rename to src/client/components/debobigego/group.vue
index 34ccaeff07..cba2c6ec94 100644
--- a/src/client/components/form/group.vue
+++ b/src/client/components/debobigego/group.vue
@@ -1,10 +1,10 @@
 <template>
-<div class="vrtktovg _formItem _formNoConcat" v-size="{ max: [500] }" v-sticky-container>
-	<div class="_formLabel"><slot name="label"></slot></div>
-	<div class="main _form_group" ref="child">
+<div class="vrtktovg _debobigegoItem _debobigegoNoConcat" v-size="{ max: [500] }" v-sticky-container>
+	<div class="_debobigegoLabel"><slot name="label"></slot></div>
+	<div class="main _debobigego_group" ref="child">
 		<slot></slot>
 	</div>
-	<div class="_formCaption"><slot name="caption"></slot></div>
+	<div class="_debobigegoCaption"><slot name="caption"></slot></div>
 </div>
 </template>
 
@@ -20,9 +20,9 @@ export default defineComponent({
 			const els = Array.from(child.value.children);
 			for (let i = 0; i < els.length; i++) {
 				const el = els[i];
-				if (el.classList.contains('_formNoConcat')) {
-					if (els[i - 1]) els[i - 1].classList.add('_formNoConcatPrev');
-					if (els[i + 1]) els[i + 1].classList.add('_formNoConcatNext');
+				if (el.classList.contains('_debobigegoNoConcat')) {
+					if (els[i - 1]) els[i - 1].classList.add('_debobigegoNoConcatPrev');
+					if (els[i + 1]) els[i + 1].classList.add('_debobigegoNoConcatNext');
 				}
 			}
 		};
@@ -52,21 +52,21 @@ export default defineComponent({
 <style lang="scss" scoped>
 .vrtktovg {
 	> .main {
-		> ::v-deep(*):not(._formNoConcat) {
-			&:not(._formNoConcatNext) {
+		> ::v-deep(*):not(._debobigegoNoConcat) {
+			&:not(._debobigegoNoConcatNext) {
 				margin: 0;
 			}
 
-			&:not(:last-child):not(._formNoConcatPrev) {
-				&._formPanel, ._formPanel {
+			&:not(:last-child):not(._debobigegoNoConcatPrev) {
+				&._debobigegoPanel, ._debobigegoPanel {
 					border-bottom: solid 0.5px var(--divider);
 					border-bottom-left-radius: 0;
 					border-bottom-right-radius: 0;
 				}
 			}
 
-			&:not(:first-child):not(._formNoConcatNext) {
-				&._formPanel, ._formPanel {
+			&:not(:first-child):not(._debobigegoNoConcatNext) {
+				&._debobigegoPanel, ._debobigegoPanel {
 					border-top: none;
 					border-top-left-radius: 0;
 					border-top-right-radius: 0;
diff --git a/src/client/components/form/info.vue b/src/client/components/debobigego/info.vue
similarity index 87%
rename from src/client/components/form/info.vue
rename to src/client/components/debobigego/info.vue
index 9fdcbdca62..41afb03304 100644
--- a/src/client/components/form/info.vue
+++ b/src/client/components/debobigego/info.vue
@@ -1,6 +1,6 @@
 <template>
-<div class="fzenkabp _formItem">
-	<div class="_formPanel" :class="{ warn }">
+<div class="fzenkabp _debobigegoItem">
+	<div class="_debobigegoPanel" :class="{ warn }">
 		<i v-if="warn" class="fas fa-exclamation-triangle"></i>
 		<i v-else class="fas fa-info-circle"></i>
 		<slot></slot>
diff --git a/src/client/components/ui/input.vue b/src/client/components/debobigego/input.vue
similarity index 62%
rename from src/client/components/ui/input.vue
rename to src/client/components/debobigego/input.vue
index a916a0b035..d113f04d27 100644
--- a/src/client/components/ui/input.vue
+++ b/src/client/components/debobigego/input.vue
@@ -1,49 +1,53 @@
 <template>
-<div class="matxzzsk">
-	<div class="label" @click="focus"><slot name="label"></slot></div>
-	<div class="input" :class="{ inline, disabled, focused }">
-		<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
-		<input ref="inputEl"
-			:type="type"
-			v-model="v"
-			:disabled="disabled"
-			:required="required"
-			:readonly="readonly"
-			:placeholder="placeholder"
-			:pattern="pattern"
-			:autocomplete="autocomplete"
-			:spellcheck="spellcheck"
-			:step="step"
-			@focus="focused = true"
-			@blur="focused = false"
-			@keydown="onKeydown($event)"
-			@input="onInput"
-			:list="id"
-		>
-		<datalist :id="id" v-if="datalist">
-			<option v-for="data in datalist" :value="data"/>
-		</datalist>
-		<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
+<FormGroup class="_debobigegoItem">
+	<template #label><slot></slot></template>
+	<div class="ztzhwixg _debobigegoItem" :class="{ inline, disabled }">
+		<div class="icon" ref="icon"><slot name="icon"></slot></div>
+		<div class="input _debobigegoPanel">
+			<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
+			<input ref="inputEl"
+				:type="type"
+				v-model="v"
+				:disabled="disabled"
+				:required="required"
+				:readonly="readonly"
+				:placeholder="placeholder"
+				:pattern="pattern"
+				:autocomplete="autocomplete"
+				:spellcheck="spellcheck"
+				:step="step"
+				@focus="focused = true"
+				@blur="focused = false"
+				@keydown="onKeydown($event)"
+				@input="onInput"
+				:list="id"
+			>
+			<datalist :id="id" v-if="datalist">
+				<option v-for="data in datalist" :value="data"/>
+			</datalist>
+			<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
+		</div>
 	</div>
-	<div class="caption"><slot name="caption"></slot></div>
+	<template #caption><slot name="desc"></slot></template>
 
-	<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
-</div>
+	<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+</FormGroup>
 </template>
 
 <script lang="ts">
 import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
-import MkButton from './button.vue';
-import { debounce } from 'throttle-debounce';
+import './debobigego.scss';
+import FormButton from './button.vue';
+import FormGroup from './group.vue';
 
 export default defineComponent({
 	components: {
-		MkButton,
+		FormGroup,
+		FormButton,
 	},
-
 	props: {
 		modelValue: {
-			required: true
+			required: false
 		},
 		type: {
 			type: String,
@@ -92,20 +96,13 @@ export default defineComponent({
 			required: false,
 			default: false
 		},
-		debounce: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
 		manualSave: {
 			type: Boolean,
 			required: false,
 			default: false
 		},
 	},
-
 	emits: ['change', 'keydown', 'enter', 'update:modelValue'],
-
 	setup(props, context) {
 		const { modelValue, type, autofocus } = toRefs(props);
 		const v = ref(modelValue.value);
@@ -140,19 +137,13 @@ export default defineComponent({
 			}
 		};
 
-		const debouncedUpdated = debounce(1000, updated);
-
-		watch(modelValue, newValue => {
+		watch(modelValue.value, newValue => {
 			v.value = newValue;
 		});
 
 		watch(v, newValue => {
 			if (!props.manualSave) {
-				if (props.debounce) {
-					debouncedUpdated();
-				} else {
-					updated();
-				}
+				updated();
 			}
 
 			invalid.value = inputEl.value.validity.badInput;
@@ -205,68 +196,59 @@ export default defineComponent({
 </script>
 
 <style lang="scss" scoped>
-.matxzzsk {
-	margin: 1.5em 0;
+.ztzhwixg {
+	position: relative;
 
-	> .label {
-		font-size: 0.85em;
-		padding: 0 0 8px 12px;
-		user-select: none;
+	> .icon {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 24px;
+		text-align: center;
+		line-height: 32px;
 
-		&:empty {
-			display: none;
-		}
-	}
-
-	> .caption {
-		font-size: 0.8em;
-		padding: 8px 0 0 12px;
-		color: var(--fgTransparentWeak);
-
-		&:empty {
-			display: none;
+		&:not(:empty) + .input {
+			margin-left: 28px;
 		}
 	}
 
 	> .input {
-		$height: 42px;
+		$height: 48px;
 		position: relative;
 
 		> input {
-			appearance: none;
-			-webkit-appearance: none;
 			display: block;
 			height: $height;
 			width: 100%;
 			margin: 0;
-			padding: 0 12px;
+			padding: 0 16px;
 			font: inherit;
 			font-weight: normal;
 			font-size: 1em;
-			color: var(--fg);
-			background: var(--panel);
-			border: solid 0.5px var(--inputBorder);
-			border-radius: 6px;
+			line-height: $height;
+			color: var(--inputText);
+			background: transparent;
+			border: none;
+			border-radius: 0;
 			outline: none;
 			box-shadow: none;
 			box-sizing: border-box;
-			transition: border-color 0.1s ease-out;
 
-			&:hover {
-				border-color: var(--inputBorderHover);
+			&[type='file'] {
+				display: none;
 			}
 		}
 
 		> .prefix,
 		> .suffix {
-			display: flex;
-			align-items: center;
+			display: block;
 			position: absolute;
 			z-index: 1;
 			top: 0;
-			padding: 0 12px;
+			padding: 0 16px;
 			font-size: 1em;
-			height: $height;
+			line-height: $height;
+			color: var(--inputLabel);
 			pointer-events: none;
 
 			&:empty {
@@ -285,32 +267,25 @@ export default defineComponent({
 
 		> .prefix {
 			left: 0;
-			padding-right: 6px;
+			padding-right: 8px;
 		}
 
 		> .suffix {
 			right: 0;
-			padding-left: 6px;
+			padding-left: 8px;
 		}
+	}
 
-		&.inline {
-			display: inline-block;
-			margin: 0;
-		}
+	&.inline {
+		display: inline-block;
+		margin: 0;
+	}
 
-		&.focused {
-			> input {
-				border-color: var(--accent);
-				//box-shadow: 0 0 0 4px var(--focus);
-			}
-		}
+	&.disabled {
+		opacity: 0.7;
 
-		&.disabled {
-			opacity: 0.7;
-
-			&, * {
-				cursor: not-allowed !important;
-			}
+		&, * {
+			cursor: not-allowed !important;
 		}
 	}
 }
diff --git a/src/client/components/form/key-value-view.vue b/src/client/components/debobigego/key-value-view.vue
similarity index 78%
rename from src/client/components/form/key-value-view.vue
rename to src/client/components/debobigego/key-value-view.vue
index ca4c09867f..0e034a2d54 100644
--- a/src/client/components/form/key-value-view.vue
+++ b/src/client/components/debobigego/key-value-view.vue
@@ -1,6 +1,6 @@
 <template>
-<div class="_formItem">
-	<div class="_formPanel anocepby">
+<div class="_debobigegoItem">
+	<div class="_debobigegoPanel anocepby">
 		<span class="key"><slot name="key"></slot></span>
 		<span class="value"><slot name="value"></slot></span>
 	</div>
@@ -9,7 +9,7 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import './form.scss';
+import './debobigego.scss';
 
 export default defineComponent({
 
@@ -20,7 +20,7 @@ export default defineComponent({
 .anocepby {
 	display: flex;
 	align-items: center;
-	padding: 14px var(--formContentHMargin);
+	padding: 14px var(--debobigegoContentHMargin);
 
 	> .key {
 		margin-right: 12px;
diff --git a/src/client/components/form/link.vue b/src/client/components/debobigego/link.vue
similarity index 84%
rename from src/client/components/form/link.vue
rename to src/client/components/debobigego/link.vue
index e1d13c6431..885579eadf 100644
--- a/src/client/components/form/link.vue
+++ b/src/client/components/debobigego/link.vue
@@ -1,6 +1,6 @@
 <template>
-<div class="qmfkfnzi _formItem">
-	<a class="main _button _formPanel _formClickable" :href="to" target="_blank" v-if="external">
+<div class="qmfkfnzi _debobigegoItem">
+	<a class="main _button _debobigegoPanel _debobigegoClickable" :href="to" target="_blank" v-if="external">
 		<span class="icon"><slot name="icon"></slot></span>
 		<span class="text"><slot></slot></span>
 		<span class="right">
@@ -8,7 +8,7 @@
 			<i class="fas fa-external-link-alt icon"></i>
 		</span>
 	</a>
-	<MkA class="main _button _formPanel _formClickable" :class="{ active }" :to="to" :behavior="behavior" v-else>
+	<MkA class="main _button _debobigegoPanel _debobigegoClickable" :class="{ active }" :to="to" :behavior="behavior" v-else>
 		<span class="icon"><slot name="icon"></slot></span>
 		<span class="text"><slot></slot></span>
 		<span class="right">
@@ -21,7 +21,7 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import './form.scss';
+import './debobigego.scss';
 
 export default defineComponent({
 	props: {
diff --git a/src/client/components/form/object-view.vue b/src/client/components/debobigego/object-view.vue
similarity index 88%
rename from src/client/components/form/object-view.vue
rename to src/client/components/debobigego/object-view.vue
index 59fb62b5e6..ea79daa915 100644
--- a/src/client/components/form/object-view.vue
+++ b/src/client/components/debobigego/object-view.vue
@@ -1,8 +1,8 @@
 <template>
-<FormGroup class="_formItem">
+<FormGroup class="_debobigegoItem">
 	<template #label><slot></slot></template>
-	<div class="drooglns _formItem" :class="{ tall }">
-		<div class="input _formPanel">
+	<div class="drooglns _debobigegoItem" :class="{ tall }">
+		<div class="input _debobigegoPanel">
 			<textarea class="_monospace"
 				v-model="v"
 				readonly
@@ -17,7 +17,7 @@
 <script lang="ts">
 import { defineComponent, ref, toRefs, watch } from 'vue';
 import * as JSON5 from 'json5';
-import './form.scss';
+import './debobigego.scss';
 import FormGroup from './group.vue';
 
 export default defineComponent({
@@ -75,7 +75,7 @@ export default defineComponent({
 			max-width: 100%;
 			min-height: 130px;
 			margin: 0;
-			padding: 16px var(--formContentHMargin);
+			padding: 16px var(--debobigegoContentHMargin);
 			box-sizing: border-box;
 			font: inherit;
 			font-weight: normal;
diff --git a/src/client/components/form/pagination.vue b/src/client/components/debobigego/pagination.vue
similarity index 95%
rename from src/client/components/form/pagination.vue
rename to src/client/components/debobigego/pagination.vue
index 0a2f1ff0e1..2166f5065f 100644
--- a/src/client/components/form/pagination.vue
+++ b/src/client/components/debobigego/pagination.vue
@@ -1,5 +1,5 @@
 <template>
-<FormGroup class="uljviswt _formItem">
+<FormGroup class="uljviswt _debobigegoItem">
 	<template #label><slot name="label"></slot></template>
 	<slot :items="items"></slot>
 	<div class="empty" v-if="empty" key="_empty_">
diff --git a/src/client/components/debobigego/radios.vue b/src/client/components/debobigego/radios.vue
new file mode 100644
index 0000000000..071c013afb
--- /dev/null
+++ b/src/client/components/debobigego/radios.vue
@@ -0,0 +1,112 @@
+<script lang="ts">
+import { defineComponent, h } from 'vue';
+import MkRadio from '@client/components/form/radio.vue';
+import './debobigego.scss';
+
+export default defineComponent({
+	components: {
+		MkRadio
+	},
+	props: {
+		modelValue: {
+			required: false
+		},
+	},
+	data() {
+		return {
+			value: this.modelValue,
+		}
+	},
+	watch: {
+		modelValue() {
+			this.value = this.modelValue;
+		},
+		value() {
+			this.$emit('update:modelValue', this.value);
+		}
+	},
+	render() {
+		const label = this.$slots.desc();
+		let options = this.$slots.default();
+
+		// なぜかFragmentになることがあるため
+		if (options.length === 1 && options[0].props == null) options = options[0].children;
+
+		return h('div', {
+			class: 'cnklmpwm _debobigegoItem'
+		}, [
+			h('div', {
+				class: '_debobigegoLabel',
+			}, label),
+			...options.map(option => h('button', {
+				class: '_button _debobigegoPanel _debobigegoClickable',
+				key: option.key,
+				onClick: () => this.value = option.props.value,
+			}, [h('span', {
+				class: ['check', { checked: this.value === option.props.value }],
+			}), option.children]))
+		]);
+	}
+});
+</script>
+
+<style lang="scss">
+.cnklmpwm {
+	> button {
+		display: block;
+		width: 100%;
+		box-sizing: border-box;
+		padding: 14px 18px;
+		text-align: left;
+
+		&:not(:first-of-type) {
+			border-top: none !important;
+			border-top-left-radius: 0;
+			border-top-right-radius: 0;
+		}
+
+		&:not(:last-of-type) {
+			border-bottom: solid 0.5px var(--divider);
+			border-bottom-left-radius: 0;
+			border-bottom-right-radius: 0;
+		}
+
+		> .check {
+			display: inline-block;
+			vertical-align: bottom;
+			position: relative;
+			width: 16px;
+			height: 16px;
+			margin-right: 8px;
+			background: none;
+			border: 2px solid var(--inputBorder);
+			border-radius: 100%;
+			transition: inherit;
+
+			&:after {
+				content: "";
+				display: block;
+				position: absolute;
+				top: 3px;
+				right: 3px;
+				bottom: 3px;
+				left: 3px;
+				border-radius: 100%;
+				opacity: 0;
+				transform: scale(0);
+				transition: .4s cubic-bezier(.25,.8,.25,1);
+			}
+
+			&.checked {
+				border-color: var(--accent);
+
+				&:after {
+					background-color: var(--accent);
+					transform: scale(1);
+					opacity: 1;
+				}
+			}
+		}
+	}
+}
+</style>
diff --git a/src/client/components/debobigego/range.vue b/src/client/components/debobigego/range.vue
new file mode 100644
index 0000000000..26fb0f37c6
--- /dev/null
+++ b/src/client/components/debobigego/range.vue
@@ -0,0 +1,122 @@
+<template>
+<div class="ifitouly _debobigegoItem" :class="{ focused, disabled }">
+	<div class="_debobigegoLabel"><slot name="label"></slot></div>
+	<div class="_debobigegoPanel main">
+		<input
+			type="range"
+			ref="input"
+			v-model="v"
+			:disabled="disabled"
+			:min="min"
+			:max="max"
+			:step="step"
+			@focus="focused = true"
+			@blur="focused = false"
+			@input="$emit('update:value', $event.target.value)"
+		/>
+	</div>
+	<div class="_debobigegoCaption"><slot name="caption"></slot></div>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+	props: {
+		value: {
+			type: Number,
+			required: false,
+			default: 0
+		},
+		disabled: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
+		min: {
+			type: Number,
+			required: false,
+			default: 0
+		},
+		max: {
+			type: Number,
+			required: false,
+			default: 100
+		},
+		step: {
+			type: Number,
+			required: false,
+			default: 1
+		},
+	},
+	data() {
+		return {
+			v: this.value,
+			focused: false
+		};
+	},
+	watch: {
+		value(v) {
+			this.v = parseFloat(v);
+		}
+	},
+});
+</script>
+
+<style lang="scss" scoped>
+.ifitouly {
+	position: relative;
+
+	> .main {
+		padding: 22px 16px;
+
+		> input {
+			display: block;
+			-webkit-appearance: none;
+			-moz-appearance: none;
+			appearance: none;
+			background: var(--X10);
+			height: 4px;
+			width: 100%;
+			box-sizing: border-box;
+			margin: 0;
+			outline: 0;
+			border: 0;
+			border-radius: 7px;
+
+			&.disabled {
+				opacity: 0.6;
+				cursor: not-allowed;
+			}
+
+			&::-webkit-slider-thumb {
+				-webkit-appearance: none;
+				appearance: none;
+				cursor: pointer;
+				width: 20px;
+				height: 20px;
+				display: block;
+				border-radius: 50%;
+				border: none;
+				background: var(--accent);
+				box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
+				box-sizing: content-box;
+			}
+
+			&::-moz-range-thumb {
+				-moz-appearance: none;
+				appearance: none;
+				cursor: pointer;
+				width: 20px;
+				height: 20px;
+				display: block;
+				border-radius: 50%;
+				border: none;
+				background: var(--accent);
+				box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
+			}
+		}
+	}
+}
+</style>
diff --git a/src/client/components/debobigego/select.vue b/src/client/components/debobigego/select.vue
new file mode 100644
index 0000000000..7a31371afc
--- /dev/null
+++ b/src/client/components/debobigego/select.vue
@@ -0,0 +1,145 @@
+<template>
+<div class="yrtfrpux _debobigegoItem" :class="{ disabled, inline }">
+	<div class="_debobigegoLabel"><slot name="label"></slot></div>
+	<div class="icon" ref="icon"><slot name="icon"></slot></div>
+	<div class="input _debobigegoPanel _debobigegoClickable" @click="focus">
+		<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
+		<select ref="input"
+			v-model="v"
+			:required="required"
+			:disabled="disabled"
+			@focus="focused = true"
+			@blur="focused = false"
+		>
+			<slot></slot>
+		</select>
+		<div class="suffix">
+			<i class="fas fa-chevron-down"></i>
+		</div>
+	</div>
+	<div class="_debobigegoCaption"><slot name="caption"></slot></div>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import './debobigego.scss';
+
+export default defineComponent({
+	props: {
+		modelValue: {
+			required: false
+		},
+		required: {
+			type: Boolean,
+			required: false
+		},
+		disabled: {
+			type: Boolean,
+			required: false
+		},
+		inline: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
+	},
+	data() {
+		return {
+		};
+	},
+	computed: {
+		v: {
+			get() {
+				return this.modelValue;
+			},
+			set(v) {
+				this.$emit('update:modelValue', v);
+			}
+		},
+	},
+	methods: {
+		focus() {
+			this.$refs.input.focus();
+		}
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.yrtfrpux {
+	position: relative;
+
+	> .icon {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 24px;
+		text-align: center;
+		line-height: 32px;
+
+		&:not(:empty) + .input {
+			margin-left: 28px;
+		}
+	}
+
+	> .input {
+		display: flex;
+		position: relative;
+
+		> select {
+			display: block;
+			flex: 1;
+			width: 100%;
+			padding: 0 16px;
+			font: inherit;
+			font-weight: normal;
+			font-size: 1em;
+			height: 48px;
+			background: none;
+			border: none;
+			border-radius: 0;
+			outline: none;
+			box-shadow: none;
+			appearance: none;
+			-webkit-appearance: none;
+			color: var(--fg);
+
+			option,
+			optgroup {
+				color: var(--fg);
+				background: var(--bg);
+			}
+		}
+
+		> .prefix,
+		> .suffix {
+			display: block;
+			align-self: center;
+			justify-self: center;
+			font-size: 1em;
+			line-height: 32px;
+			color: var(--inputLabel);
+			pointer-events: none;
+
+			&:empty {
+				display: none;
+			}
+
+			> * {
+				display: block;
+				min-width: 16px;
+			}
+		}
+
+		> .prefix {
+			padding-right: 4px;
+		}
+
+		> .suffix {
+			padding: 0 16px 0 0;
+			opacity: 0.7;
+		}
+	}
+}
+</style>
diff --git a/src/client/components/form/suspense.vue b/src/client/components/debobigego/suspense.vue
similarity index 87%
rename from src/client/components/form/suspense.vue
rename to src/client/components/debobigego/suspense.vue
index d04dc07624..e59e0ba12d 100644
--- a/src/client/components/form/suspense.vue
+++ b/src/client/components/debobigego/suspense.vue
@@ -1,15 +1,15 @@
 <template>
 <transition name="fade" mode="out-in">
-	<div class="_formItem" v-if="pending">
-		<div class="_formPanel">
+	<div class="_debobigegoItem" v-if="pending">
+		<div class="_debobigegoPanel">
 			<MkLoading/>
 		</div>
 	</div>
-	<div v-else-if="resolved" class="_formItem">
+	<div v-else-if="resolved" class="_debobigegoItem">
 		<slot :result="result"></slot>
 	</div>
-	<div class="_formItem" v-else>
-		<div class="_formPanel eiurkvay">
+	<div class="_debobigegoItem" v-else>
+		<div class="_debobigegoPanel eiurkvay">
 			<div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div>
 			<MkButton inline @click="retry" class="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton>
 		</div>
@@ -19,7 +19,7 @@
 
 <script lang="ts">
 import { defineComponent, PropType, ref, watch } from 'vue';
-import './form.scss';
+import './debobigego.scss';
 import MkButton from '@client/components/ui/button.vue';
 
 export default defineComponent({
diff --git a/src/client/components/debobigego/switch.vue b/src/client/components/debobigego/switch.vue
new file mode 100644
index 0000000000..0ee0881236
--- /dev/null
+++ b/src/client/components/debobigego/switch.vue
@@ -0,0 +1,132 @@
+<template>
+<div class="ijnpvmgr _debobigegoItem">
+	<div class="main _debobigegoPanel _debobigegoClickable"
+		:class="{ disabled, checked }"
+		:aria-checked="checked"
+		:aria-disabled="disabled"
+		@click.prevent="toggle"
+	>
+		<input
+			type="checkbox"
+			ref="input"
+			:disabled="disabled"
+			@keydown.enter="toggle"
+		>
+		<span class="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff">
+			<span></span>
+		</span>
+		<span class="label">
+			<span><slot></slot></span>
+		</span>
+	</div>
+	<div class="_debobigegoCaption"><slot name="desc"></slot></div>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import './debobigego.scss';
+
+export default defineComponent({
+	props: {
+		modelValue: {
+			type: Boolean,
+			default: false
+		},
+		disabled: {
+			type: Boolean,
+			default: false
+		}
+	},
+	computed: {
+		checked(): boolean {
+			return this.modelValue;
+		}
+	},
+	methods: {
+		toggle() {
+			if (this.disabled) return;
+			this.$emit('update:modelValue', !this.checked);
+		}
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.ijnpvmgr {
+	> .main {
+		position: relative;
+		display: flex;
+		padding: 14px 16px;
+		cursor: pointer;
+
+		> * {
+			user-select: none;
+		}
+
+		&.disabled {
+			opacity: 0.6;
+			cursor: not-allowed;
+		}
+
+		&.checked {
+			> .button {
+				background-color: var(--X10);
+				border-color: var(--X10);
+
+				> * {
+					background-color: var(--accent);
+					transform: translateX(14px);
+				}
+			}
+		}
+
+		> input {
+			position: absolute;
+			width: 0;
+			height: 0;
+			opacity: 0;
+			margin: 0;
+		}
+
+		> .button {
+			position: relative;
+			display: inline-block;
+			flex-shrink: 0;
+			margin: 3px 0 0 0;
+			width: 34px;
+			height: 14px;
+			background: var(--X6);
+			outline: none;
+			border-radius: 14px;
+			transition: all 0.3s;
+			cursor: pointer;
+
+			> * {
+				position: absolute;
+				top: -3px;
+				left: 0;
+				border-radius: 100%;
+				transition: background-color 0.3s, transform 0.3s;
+				width: 20px;
+				height: 20px;
+				background-color: #fff;
+				box-shadow: 0 2px 1px -1px rgba(#000, 0.2), 0 1px 1px 0 rgba(#000, 0.14), 0 1px 3px 0 rgba(#000, 0.12);
+			}
+		}
+
+		> .label {
+			margin-left: 12px;
+			display: block;
+			transition: inherit;
+			color: var(--fg);
+
+			> span {
+				display: block;
+				line-height: 20px;
+				transition: inherit;
+			}
+		}
+	}
+}
+</style>
diff --git a/src/client/components/debobigego/textarea.vue b/src/client/components/debobigego/textarea.vue
new file mode 100644
index 0000000000..64e8d47126
--- /dev/null
+++ b/src/client/components/debobigego/textarea.vue
@@ -0,0 +1,161 @@
+<template>
+<FormGroup class="_debobigegoItem">
+	<template #label><slot></slot></template>
+	<div class="rivhosbp _debobigegoItem" :class="{ tall, pre }">
+		<div class="input _debobigegoPanel">
+			<textarea ref="input" :class="{ code, _monospace: code }"
+				v-model="v"
+				:required="required"
+				:readonly="readonly"
+				:pattern="pattern"
+				:autocomplete="autocomplete"
+				:spellcheck="!code"
+				@input="onInput"
+				@focus="focused = true"
+				@blur="focused = false"
+			></textarea>
+		</div>
+	</div>
+	<template #caption><slot name="desc"></slot></template>
+
+	<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
+</FormGroup>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref, toRefs, watch } from 'vue';
+import './debobigego.scss';
+import FormButton from './button.vue';
+import FormGroup from './group.vue';
+
+export default defineComponent({
+	components: {
+		FormGroup,
+		FormButton,
+	},
+	props: {
+		modelValue: {
+			required: false
+		},
+		required: {
+			type: Boolean,
+			required: false
+		},
+		readonly: {
+			type: Boolean,
+			required: false
+		},
+		pattern: {
+			type: String,
+			required: false
+		},
+		autocomplete: {
+			type: String,
+			required: false
+		},
+		code: {
+			type: Boolean,
+			required: false
+		},
+		tall: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
+		pre: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
+		manualSave: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
+	},
+	setup(props, context) {
+		const { modelValue } = toRefs(props);
+		const v = ref(modelValue.value);
+		const changed = ref(false);
+		const inputEl = ref(null);
+		const focus = () => inputEl.value.focus();
+		const onInput = (ev) => {
+			changed.value = true;
+			context.emit('change', ev);
+		};
+
+		const updated = () => {
+			changed.value = false;
+			context.emit('update:modelValue', v.value);
+		};
+
+		watch(modelValue.value, newValue => {
+			v.value = newValue;
+		});
+
+		watch(v, newValue => {
+			if (!props.manualSave) {
+				updated();
+			}
+		});
+		
+		return {
+			v,
+			updated,
+			changed,
+			focus,
+			onInput,
+		};
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.rivhosbp {
+	position: relative;
+
+	> .input {
+		position: relative;
+	
+		> textarea {
+			display: block;
+			width: 100%;
+			min-width: 100%;
+			max-width: 100%;
+			min-height: 130px;
+			margin: 0;
+			padding: 16px;
+			box-sizing: border-box;
+			font: inherit;
+			font-weight: normal;
+			font-size: 1em;
+			background: transparent;
+			border: none;
+			border-radius: 0;
+			outline: none;
+			box-shadow: none;
+			color: var(--fg);
+
+			&.code {
+				tab-size: 2;
+			}
+		}
+	}
+
+	&.tall {
+		> .input {
+			> textarea {
+				min-height: 200px;
+			}
+		}
+	}
+
+	&.pre {
+		> .input {
+			> textarea {
+				white-space: pre;
+			}
+		}
+	}
+}
+</style>
diff --git a/src/client/components/form/tuple.vue b/src/client/components/debobigego/tuple.vue
similarity index 87%
rename from src/client/components/form/tuple.vue
rename to src/client/components/debobigego/tuple.vue
index 6c8a22d189..8a4599fd64 100644
--- a/src/client/components/form/tuple.vue
+++ b/src/client/components/debobigego/tuple.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="wthhikgt _formItem" v-size="{ max: [500] }">
+<div class="wthhikgt _debobigegoItem" v-size="{ max: [500] }">
 	<slot></slot>
 </div>
 </template>
diff --git a/src/client/components/dialog.vue b/src/client/components/dialog.vue
index f3611f050e..dd4932f61f 100644
--- a/src/client/components/dialog.vue
+++ b/src/client/components/dialog.vue
@@ -40,8 +40,8 @@
 import { defineComponent } from 'vue';
 import MkModal from '@client/components/ui/modal.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSelect from '@client/components/form/select.vue';
 
 export default defineComponent({
 	components: {
diff --git a/src/client/components/forgot-password.vue b/src/client/components/forgot-password.vue
index 3b5ad6d6ba..cb2380f483 100644
--- a/src/client/components/forgot-password.vue
+++ b/src/client/components/forgot-password.vue
@@ -35,7 +35,7 @@
 import { defineComponent } from 'vue';
 import XModalWindow from '@client/components/ui/modal-window.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/components/form-dialog.vue b/src/client/components/form-dialog.vue
index e13592b488..6353b7287e 100644
--- a/src/client/components/form-dialog.vue
+++ b/src/client/components/form-dialog.vue
@@ -14,23 +14,23 @@
 	</template>
 	<FormBase class="xkpnjxcv">
 		<template v-for="item in Object.keys(form).filter(item => !form[item].hidden)">
-			<FormInput v-if="form[item].type === 'number'" v-model:value="values[item]" type="number" :step="form[item].step || 1">
+			<FormInput v-if="form[item].type === 'number'" v-model="values[item]" type="number" :step="form[item].step || 1">
 				<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
 				<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
 			</FormInput>
-			<FormInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model:value="values[item]" type="text">
+			<FormInput v-else-if="form[item].type === 'string' && !form[item].multiline" v-model="values[item]" type="text">
 				<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
 				<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
 			</FormInput>
-			<FormTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model:value="values[item]">
+			<FormTextarea v-else-if="form[item].type === 'string' && form[item].multiline" v-model="values[item]">
 				<span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span>
 				<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
 			</FormTextarea>
-			<FormSwitch v-else-if="form[item].type === 'boolean'" v-model:value="values[item]">
+			<FormSwitch v-else-if="form[item].type === 'boolean'" v-model="values[item]">
 				<span v-text="form[item].label || item"></span>
 				<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
 			</FormSwitch>
-			<FormSelect v-else-if="form[item].type === 'enum'" v-model:value="values[item]">
+			<FormSelect v-else-if="form[item].type === 'enum'" v-model="values[item]">
 				<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
 				<option v-for="item in form[item].enum" :value="item.value" :key="item.value">{{ item.label }}</option>
 			</FormSelect>
@@ -38,7 +38,7 @@
 				<template #desc><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
 				<option v-for="item in form[item].options" :value="item.value" :key="item.value">{{ item.label }}</option>
 			</FormRadios>
-			<FormRange v-else-if="form[item].type === 'range'" v-model:value="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step">
+			<FormRange v-else-if="form[item].type === 'range'" v-model="values[item]" :min="form[item].mim" :max="form[item].max" :step="form[item].step">
 				<template #label><span v-text="form[item].label || item"></span><span v-if="form[item].required === false"> ({{ $ts.optional }})</span></template>
 				<template v-if="form[item].description" #desc>{{ form[item].description }}</template>
 			</FormRange>
@@ -53,14 +53,14 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XModalWindow from '@client/components/ui/modal-window.vue';
-import FormBase from './form/base.vue';
-import FormInput from './form/input.vue';
-import FormTextarea from './form/textarea.vue';
-import FormSwitch from './form/switch.vue';
-import FormSelect from './form/select.vue';
-import FormRange from './form/range.vue';
-import FormButton from './form/button.vue';
-import FormRadios from './form/radios.vue';
+import FormBase from './debobigego/base.vue';
+import FormInput from './debobigego/input.vue';
+import FormTextarea from './debobigego/textarea.vue';
+import FormSwitch from './debobigego/switch.vue';
+import FormSelect from './debobigego/select.vue';
+import FormRange from './debobigego/range.vue';
+import FormButton from './debobigego/button.vue';
+import FormRadios from './debobigego/radios.vue';
 
 export default defineComponent({
 	components: {
diff --git a/src/client/components/form/input.vue b/src/client/components/form/input.vue
index 942ac4dfd2..d7b6f77519 100644
--- a/src/client/components/form/input.vue
+++ b/src/client/components/form/input.vue
@@ -1,53 +1,49 @@
 <template>
-<FormGroup class="_formItem">
-	<template #label><slot></slot></template>
-	<div class="ztzhwixg _formItem" :class="{ inline, disabled }">
-		<div class="icon" ref="icon"><slot name="icon"></slot></div>
-		<div class="input _formPanel">
-			<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
-			<input ref="inputEl"
-				:type="type"
-				v-model="v"
-				:disabled="disabled"
-				:required="required"
-				:readonly="readonly"
-				:placeholder="placeholder"
-				:pattern="pattern"
-				:autocomplete="autocomplete"
-				:spellcheck="spellcheck"
-				:step="step"
-				@focus="focused = true"
-				@blur="focused = false"
-				@keydown="onKeydown($event)"
-				@input="onInput"
-				:list="id"
-			>
-			<datalist :id="id" v-if="datalist">
-				<option v-for="data in datalist" :value="data"/>
-			</datalist>
-			<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
-		</div>
+<div class="matxzzsk">
+	<div class="label" @click="focus"><slot name="label"></slot></div>
+	<div class="input" :class="{ inline, disabled, focused }">
+		<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
+		<input ref="inputEl"
+			:type="type"
+			v-model="v"
+			:disabled="disabled"
+			:required="required"
+			:readonly="readonly"
+			:placeholder="placeholder"
+			:pattern="pattern"
+			:autocomplete="autocomplete"
+			:spellcheck="spellcheck"
+			:step="step"
+			@focus="focused = true"
+			@blur="focused = false"
+			@keydown="onKeydown($event)"
+			@input="onInput"
+			:list="id"
+		>
+		<datalist :id="id" v-if="datalist">
+			<option v-for="data in datalist" :value="data"/>
+		</datalist>
+		<div class="suffix" ref="suffixEl"><slot name="suffix"></slot></div>
 	</div>
-	<template #caption><slot name="desc"></slot></template>
+	<div class="caption"><slot name="caption"></slot></div>
 
-	<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
-</FormGroup>
+	<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
+</div>
 </template>
 
 <script lang="ts">
 import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
-import './form.scss';
-import FormButton from './button.vue';
-import FormGroup from './group.vue';
+import MkButton from '../ui/button.vue';
+import { debounce } from 'throttle-debounce';
 
 export default defineComponent({
 	components: {
-		FormGroup,
-		FormButton,
+		MkButton,
 	},
+
 	props: {
-		value: {
-			required: false
+		modelValue: {
+			required: true
 		},
 		type: {
 			type: String,
@@ -96,16 +92,23 @@ export default defineComponent({
 			required: false,
 			default: false
 		},
+		debounce: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
 		manualSave: {
 			type: Boolean,
 			required: false,
 			default: false
 		},
 	},
-	emits: ['change', 'keydown', 'enter'],
+
+	emits: ['change', 'keydown', 'enter', 'update:modelValue'],
+
 	setup(props, context) {
-		const { value, type, autofocus } = toRefs(props);
-		const v = ref(value.value);
+		const { modelValue, type, autofocus } = toRefs(props);
+		const v = ref(modelValue.value);
 		const id = Math.random().toString(); // TODO: uuid?
 		const focused = ref(false);
 		const changed = ref(false);
@@ -131,19 +134,25 @@ export default defineComponent({
 		const updated = () => {
 			changed.value = false;
 			if (type?.value === 'number') {
-				context.emit('update:value', parseFloat(v.value));
+				context.emit('update:modelValue', parseFloat(v.value));
 			} else {
-				context.emit('update:value', v.value);
+				context.emit('update:modelValue', v.value);
 			}
 		};
 
-		watch(value, newValue => {
+		const debouncedUpdated = debounce(1000, updated);
+
+		watch(modelValue, newValue => {
 			v.value = newValue;
 		});
 
 		watch(v, newValue => {
 			if (!props.manualSave) {
-				updated();
+				if (props.debounce) {
+					debouncedUpdated();
+				} else {
+					updated();
+				}
 			}
 
 			invalid.value = inputEl.value.validity.badInput;
@@ -196,59 +205,66 @@ export default defineComponent({
 </script>
 
 <style lang="scss" scoped>
-.ztzhwixg {
-	position: relative;
+.matxzzsk {
+	> .label {
+		font-size: 0.85em;
+		padding: 0 0 8px 12px;
+		user-select: none;
 
-	> .icon {
-		position: absolute;
-		top: 0;
-		left: 0;
-		width: 24px;
-		text-align: center;
-		line-height: 32px;
+		&:empty {
+			display: none;
+		}
+	}
 
-		&:not(:empty) + .input {
-			margin-left: 28px;
+	> .caption {
+		font-size: 0.8em;
+		padding: 8px 0 0 12px;
+		color: var(--fgTransparentWeak);
+
+		&:empty {
+			display: none;
 		}
 	}
 
 	> .input {
-		$height: 48px;
+		$height: 42px;
 		position: relative;
 
 		> input {
+			appearance: none;
+			-webkit-appearance: none;
 			display: block;
 			height: $height;
 			width: 100%;
 			margin: 0;
-			padding: 0 16px;
+			padding: 0 12px;
 			font: inherit;
 			font-weight: normal;
 			font-size: 1em;
-			line-height: $height;
-			color: var(--inputText);
-			background: transparent;
-			border: none;
-			border-radius: 0;
+			color: var(--fg);
+			background: var(--panel);
+			border: solid 0.5px var(--inputBorder);
+			border-radius: 6px;
 			outline: none;
 			box-shadow: none;
 			box-sizing: border-box;
+			transition: border-color 0.1s ease-out;
 
-			&[type='file'] {
-				display: none;
+			&:hover {
+				border-color: var(--inputBorderHover);
 			}
 		}
 
 		> .prefix,
 		> .suffix {
-			display: block;
+			display: flex;
+			align-items: center;
 			position: absolute;
 			z-index: 1;
 			top: 0;
-			padding: 0 16px;
+			padding: 0 12px;
 			font-size: 1em;
-			line-height: $height;
-			color: var(--inputLabel);
+			height: $height;
 			pointer-events: none;
 
 			&:empty {
@@ -267,25 +283,32 @@ export default defineComponent({
 
 		> .prefix {
 			left: 0;
-			padding-right: 8px;
+			padding-right: 6px;
 		}
 
 		> .suffix {
 			right: 0;
-			padding-left: 8px;
+			padding-left: 6px;
 		}
-	}
 
-	&.inline {
-		display: inline-block;
-		margin: 0;
-	}
+		&.inline {
+			display: inline-block;
+			margin: 0;
+		}
 
-	&.disabled {
-		opacity: 0.7;
+		&.focused {
+			> input {
+				border-color: var(--accent);
+				//box-shadow: 0 0 0 4px var(--focus);
+			}
+		}
 
-		&, * {
-			cursor: not-allowed !important;
+		&.disabled {
+			opacity: 0.7;
+
+			&, * {
+				cursor: not-allowed !important;
+			}
 		}
 	}
 }
diff --git a/src/client/components/ui/radio.vue b/src/client/components/form/radio.vue
similarity index 100%
rename from src/client/components/ui/radio.vue
rename to src/client/components/form/radio.vue
diff --git a/src/client/components/form/radios.vue b/src/client/components/form/radios.vue
index b660c37ace..1d3d80172a 100644
--- a/src/client/components/form/radios.vue
+++ b/src/client/components/form/radios.vue
@@ -1,7 +1,6 @@
 <script lang="ts">
 import { defineComponent, h } from 'vue';
-import MkRadio from '@client/components/ui/radio.vue';
-import './form.scss';
+import MkRadio from './radio.vue';
 
 export default defineComponent({
 	components: {
@@ -18,9 +17,6 @@ export default defineComponent({
 		}
 	},
 	watch: {
-		modelValue() {
-			this.value = this.modelValue;
-		},
 		value() {
 			this.$emit('update:modelValue', this.value);
 		}
@@ -33,80 +29,38 @@ export default defineComponent({
 		if (options.length === 1 && options[0].props == null) options = options[0].children;
 
 		return h('div', {
-			class: 'cnklmpwm _formItem'
+			class: 'novjtcto'
 		}, [
-			h('div', {
-				class: '_formLabel',
-			}, label),
-			...options.map(option => h('button', {
-				class: '_button _formPanel _formClickable',
+			h('div', { class: 'label' }, label),
+			...options.map(option => h(MkRadio, {
 				key: option.key,
-				onClick: () => this.value = option.props.value,
-			}, [h('span', {
-				class: ['check', { checked: this.value === option.props.value }],
-			}), option.children]))
+				value: option.props.value,
+				modelValue: this.value,
+				'onUpdate:modelValue': value => this.value = value,
+			}, option.children))
 		]);
 	}
 });
 </script>
 
 <style lang="scss">
-.cnklmpwm {
-	> button {
-		display: block;
-		width: 100%;
-		box-sizing: border-box;
-		padding: 14px 18px;
-		text-align: left;
+.novjtcto {
+	> .label {
+		font-size: 0.85em;
+		padding: 0 0 8px 12px;
+		user-select: none;
 
-		&:not(:first-of-type) {
-			border-top: none !important;
-			border-top-left-radius: 0;
-			border-top-right-radius: 0;
+		&:empty {
+			display: none;
 		}
+	}
 
-		&:not(:last-of-type) {
-			border-bottom: solid 0.5px var(--divider);
-			border-bottom-left-radius: 0;
-			border-bottom-right-radius: 0;
-		}
+	&:first-child {
+		margin-top: 0;
+	}
 
-		> .check {
-			display: inline-block;
-			vertical-align: bottom;
-			position: relative;
-			width: 16px;
-			height: 16px;
-			margin-right: 8px;
-			background: none;
-			border: 2px solid var(--inputBorder);
-			border-radius: 100%;
-			transition: inherit;
-
-			&:after {
-				content: "";
-				display: block;
-				position: absolute;
-				top: 3px;
-				right: 3px;
-				bottom: 3px;
-				left: 3px;
-				border-radius: 100%;
-				opacity: 0;
-				transform: scale(0);
-				transition: .4s cubic-bezier(.25,.8,.25,1);
-			}
-
-			&.checked {
-				border-color: var(--accent);
-
-				&:after {
-					background-color: var(--accent);
-					transform: scale(1);
-					opacity: 1;
-				}
-			}
-		}
+	&:last-child {
+		margin-bottom: 0;
 	}
 }
 </style>
diff --git a/src/client/components/form/range.vue b/src/client/components/form/range.vue
index 65d665c70a..4cfe66a8fc 100644
--- a/src/client/components/form/range.vue
+++ b/src/client/components/form/range.vue
@@ -1,21 +1,20 @@
 <template>
-<div class="ifitouly _formItem" :class="{ focused, disabled }">
-	<div class="_formLabel"><slot name="label"></slot></div>
-	<div class="_formPanel main">
-		<input
-			type="range"
-			ref="input"
-			v-model="v"
-			:disabled="disabled"
-			:min="min"
-			:max="max"
-			:step="step"
-			@focus="focused = true"
-			@blur="focused = false"
-			@input="$emit('update:value', $event.target.value)"
-		/>
-	</div>
-	<div class="_formCaption"><slot name="caption"></slot></div>
+<div class="timctyfi" :class="{ focused, disabled }">
+	<div class="icon"><slot name="icon"></slot></div>
+	<span class="label"><slot name="label"></slot></span>
+	<input
+		type="range"
+		ref="input"
+		v-model="v"
+		:disabled="disabled"
+		:min="min"
+		:max="max"
+		:step="step"
+		:autofocus="autofocus"
+		@focus="focused = true"
+		@blur="focused = false"
+		@input="$emit('update:value', $event.target.value)"
+	/>
 </div>
 </template>
 
@@ -49,6 +48,10 @@ export default defineComponent({
 			required: false,
 			default: 1
 		},
+		autofocus: {
+			type: Boolean,
+			required: false
+		}
 	},
 	data() {
 		return {
@@ -61,61 +64,75 @@ export default defineComponent({
 			this.v = parseFloat(v);
 		}
 	},
+	mounted() {
+		if (this.autofocus) {
+			this.$nextTick(() => {
+				this.$refs.input.focus();
+			});
+		}
+	}
 });
 </script>
 
 <style lang="scss" scoped>
-.ifitouly {
+.timctyfi {
 	position: relative;
+	margin: 8px;
 
-	> .main {
-		padding: 22px 16px;
+	> .icon {
+		display: inline-block;
+		width: 24px;
+		text-align: center;
+	}
 
-		> input {
-			display: block;
+	> .title {
+		pointer-events: none;
+		font-size: 16px;
+		color: var(--inputLabel);
+		overflow: hidden;
+	}
+
+	> input {
+		-webkit-appearance: none;
+		-moz-appearance: none;
+		appearance: none;
+		background: var(--X10);
+		height: 7px;
+		margin: 0 8px;
+		outline: 0;
+		border: 0;
+		border-radius: 7px;
+
+		&.disabled {
+			opacity: 0.6;
+			cursor: not-allowed;
+		}
+
+		&::-webkit-slider-thumb {
 			-webkit-appearance: none;
+			appearance: none;
+			cursor: pointer;
+			width: 20px;
+			height: 20px;
+			display: block;
+			border-radius: 50%;
+			border: none;
+			background: var(--accent);
+			box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
+			box-sizing: content-box;
+		}
+
+		&::-moz-range-thumb {
 			-moz-appearance: none;
 			appearance: none;
-			background: var(--X10);
-			height: 4px;
-			width: 100%;
-			box-sizing: border-box;
-			margin: 0;
-			outline: 0;
-			border: 0;
-			border-radius: 7px;
-
-			&.disabled {
-				opacity: 0.6;
-				cursor: not-allowed;
-			}
-
-			&::-webkit-slider-thumb {
-				-webkit-appearance: none;
-				appearance: none;
-				cursor: pointer;
-				width: 20px;
-				height: 20px;
-				display: block;
-				border-radius: 50%;
-				border: none;
-				background: var(--accent);
-				box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
-				box-sizing: content-box;
-			}
-
-			&::-moz-range-thumb {
-				-moz-appearance: none;
-				appearance: none;
-				cursor: pointer;
-				width: 20px;
-				height: 20px;
-				display: block;
-				border-radius: 50%;
-				border: none;
-				background: var(--accent);
-				box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
-			}
+			cursor: pointer;
+			width: 20px;
+			height: 20px;
+			display: block;
+			border-radius: 50%;
+			border: none;
+			background: var(--accent);
+			box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
 		}
 	}
 }
diff --git a/src/client/components/form/section.vue b/src/client/components/form/section.vue
new file mode 100644
index 0000000000..8eac40a0db
--- /dev/null
+++ b/src/client/components/form/section.vue
@@ -0,0 +1,31 @@
+<template>
+<div class="vrtktovh" v-size="{ max: [500] }" v-sticky-container>
+	<div class="label"><slot name="label"></slot></div>
+	<div class="main">
+		<slot></slot>
+	</div>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+
+});
+</script>
+
+<style lang="scss" scoped>
+.vrtktovh {
+	border-top: solid 0.5px var(--divider);
+
+	> .label {
+		font-weight: bold;
+		padding: 24px 0 16px 0;
+	}
+
+	> .main {
+		margin-bottom: 32px;
+	}
+}
+</style>
diff --git a/src/client/components/form/select.vue b/src/client/components/form/select.vue
index 1c5a473451..257e2cc990 100644
--- a/src/client/components/form/select.vue
+++ b/src/client/components/form/select.vue
@@ -1,125 +1,216 @@
 <template>
-<div class="yrtfrpux _formItem" :class="{ disabled, inline }">
-	<div class="_formLabel"><slot name="label"></slot></div>
-	<div class="icon" ref="icon"><slot name="icon"></slot></div>
-	<div class="input _formPanel _formClickable" @click="focus">
-		<div class="prefix" ref="prefix"><slot name="prefix"></slot></div>
-		<select ref="input"
+<div class="vblkjoeq">
+	<div class="label" @click="focus"><slot name="label"></slot></div>
+	<div class="input" :class="{ inline, disabled, focused }">
+		<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
+		<select ref="inputEl"
 			v-model="v"
-			:required="required"
 			:disabled="disabled"
+			:required="required"
+			:readonly="readonly"
+			:placeholder="placeholder"
 			@focus="focused = true"
 			@blur="focused = false"
+			@input="onInput"
 		>
 			<slot></slot>
 		</select>
-		<div class="suffix">
-			<i class="fas fa-chevron-down"></i>
-		</div>
+		<div class="suffix" ref="suffixEl"><i class="fas fa-chevron-down"></i></div>
 	</div>
-	<div class="_formCaption"><slot name="caption"></slot></div>
+	<div class="caption"><slot name="caption"></slot></div>
+
+	<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
 </div>
 </template>
 
 <script lang="ts">
-import { defineComponent } from 'vue';
-import './form.scss';
+import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
+import MkButton from '../ui/button.vue';
 
 export default defineComponent({
+	components: {
+		MkButton,
+	},
+
 	props: {
-		value: {
-			required: false
+		modelValue: {
+			required: true
 		},
 		required: {
 			type: Boolean,
 			required: false
 		},
+		readonly: {
+			type: Boolean,
+			required: false
+		},
 		disabled: {
 			type: Boolean,
 			required: false
 		},
+		placeholder: {
+			type: String,
+			required: false
+		},
+		autofocus: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
 		inline: {
 			type: Boolean,
 			required: false,
 			default: false
 		},
-	},
-	data() {
-		return {
-		};
-	},
-	computed: {
-		v: {
-			get() {
-				return this.value;
-			},
-			set(v) {
-				this.$emit('update:value', v);
-			}
+		manualSave: {
+			type: Boolean,
+			required: false,
+			default: false
 		},
 	},
-	methods: {
-		focus() {
-			this.$refs.input.focus();
-		}
-	}
+
+	emits: ['change', 'update:modelValue'],
+
+	setup(props, context) {
+		const { modelValue, autofocus } = toRefs(props);
+		const v = ref(modelValue.value);
+		const focused = ref(false);
+		const changed = ref(false);
+		const invalid = ref(false);
+		const filled = computed(() => v.value !== '' && v.value != null);
+		const inputEl = ref(null);
+		const prefixEl = ref(null);
+		const suffixEl = ref(null);
+
+		const focus = () => inputEl.value.focus();
+		const onInput = (ev) => {
+			changed.value = true;
+			context.emit('change', ev);
+		};
+
+		const updated = () => {
+			changed.value = false;
+			context.emit('update:modelValue', v.value);
+		};
+
+		watch(modelValue, newValue => {
+			v.value = newValue;
+		});
+
+		watch(v, newValue => {
+			if (!props.manualSave) {
+				updated();
+			}
+
+			invalid.value = inputEl.value.validity.badInput;
+		});
+
+		onMounted(() => {
+			nextTick(() => {
+				if (autofocus.value) {
+					focus();
+				}
+
+				// このコンポーネントが作成された時、非表示状態である場合がある
+				// 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する
+				const clock = setInterval(() => {
+					if (prefixEl.value) {
+						if (prefixEl.value.offsetWidth) {
+							inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + 'px';
+						}
+					}
+					if (suffixEl.value) {
+						if (suffixEl.value.offsetWidth) {
+							inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + 'px';
+						}
+					}
+				}, 100);
+
+				onUnmounted(() => {
+					clearInterval(clock);
+				});
+			});
+		});
+
+		return {
+			v,
+			focused,
+			invalid,
+			changed,
+			filled,
+			inputEl,
+			prefixEl,
+			suffixEl,
+			focus,
+			onInput,
+			updated,
+		};
+	},
 });
 </script>
 
 <style lang="scss" scoped>
-.yrtfrpux {
-	position: relative;
+.vblkjoeq {
+	> .label {
+		font-size: 0.85em;
+		padding: 0 0 8px 12px;
+		user-select: none;
 
-	> .icon {
-		position: absolute;
-		top: 0;
-		left: 0;
-		width: 24px;
-		text-align: center;
-		line-height: 32px;
+		&:empty {
+			display: none;
+		}
+	}
 
-		&:not(:empty) + .input {
-			margin-left: 28px;
+	> .caption {
+		font-size: 0.8em;
+		padding: 8px 0 0 12px;
+		color: var(--fgTransparentWeak);
+
+		&:empty {
+			display: none;
 		}
 	}
 
 	> .input {
-		display: flex;
+		$height: 42px;
 		position: relative;
 
 		> select {
+			appearance: none;
+			-webkit-appearance: none;
 			display: block;
-			flex: 1;
+			height: $height;
 			width: 100%;
-			padding: 0 16px;
+			margin: 0;
+			padding: 0 12px;
 			font: inherit;
 			font-weight: normal;
 			font-size: 1em;
-			height: 48px;
-			background: none;
-			border: none;
-			border-radius: 0;
+			color: var(--fg);
+			background: var(--panel);
+			border: solid 1px var(--inputBorder);
+			border-radius: 6px;
 			outline: none;
 			box-shadow: none;
-			appearance: none;
-			-webkit-appearance: none;
-			color: var(--fg);
+			box-sizing: border-box;
+			cursor: pointer;
+			transition: border-color 0.1s ease-out;
 
-			option,
-			optgroup {
-				color: var(--fg);
-				background: var(--bg);
+			&:hover {
+				border-color: var(--inputBorderHover);
 			}
 		}
 
 		> .prefix,
 		> .suffix {
-			display: block;
-			align-self: center;
-			justify-self: center;
+			display: flex;
+			align-items: center;
+			position: absolute;
+			z-index: 1;
+			top: 0;
+			padding: 0 12px;
 			font-size: 1em;
-			line-height: 32px;
-			color: var(--inputLabel);
+			height: $height;
 			pointer-events: none;
 
 			&:empty {
@@ -127,18 +218,42 @@ export default defineComponent({
 			}
 
 			> * {
-				display: block;
+				display: inline-block;
 				min-width: 16px;
+				max-width: 150px;
+				overflow: hidden;
+				white-space: nowrap;
+				text-overflow: ellipsis;
 			}
 		}
 
 		> .prefix {
-			padding-right: 4px;
+			left: 0;
+			padding-right: 6px;
 		}
 
 		> .suffix {
-			padding: 0 16px 0 0;
+			right: 0;
+			padding-left: 6px;
+		}
+
+		&.inline {
+			display: inline-block;
+			margin: 0;
+		}
+
+		&.focused {
+			> select {
+				border-color: var(--accent);
+			}
+		}
+
+		&.disabled {
 			opacity: 0.7;
+
+			&, * {
+				cursor: not-allowed !important;
+			}
 		}
 	}
 }
diff --git a/src/client/components/form/slot.vue b/src/client/components/form/slot.vue
new file mode 100644
index 0000000000..8580c1307d
--- /dev/null
+++ b/src/client/components/form/slot.vue
@@ -0,0 +1,50 @@
+<template>
+<div class="adhpbeou">
+	<div class="label" @click="focus"><slot name="label"></slot></div>
+	<div class="content">
+		<slot></slot>
+	</div>
+	<div class="caption"><slot name="caption"></slot></div>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+
+});
+</script>
+
+<style lang="scss" scoped>
+.adhpbeou {
+	margin: 1.5em 0;
+
+	> .label {
+		font-size: 0.85em;
+		padding: 0 0 8px 12px;
+		user-select: none;
+
+		&:empty {
+			display: none;
+		}
+	}
+
+	> .caption {
+		font-size: 0.8em;
+		padding: 8px 0 0 12px;
+		color: var(--fgTransparentWeak);
+
+		&:empty {
+			display: none;
+		}
+	}
+
+	> .content {
+		position: relative;
+		background: var(--panel);
+		border: solid 0.5px var(--inputBorder);
+		border-radius: 6px;
+	}
+}
+</style>
diff --git a/src/client/components/form/switch.vue b/src/client/components/form/switch.vue
index e7ef714c49..85f8b7c870 100644
--- a/src/client/components/form/switch.vue
+++ b/src/client/components/form/switch.vue
@@ -1,35 +1,34 @@
 <template>
-<div class="ijnpvmgr _formItem">
-	<div class="main _formPanel _formClickable"
-		:class="{ disabled, checked }"
-		:aria-checked="checked"
-		:aria-disabled="disabled"
-		@click.prevent="toggle"
+<div
+	class="ziffeoms"
+	:class="{ disabled, checked }"
+	role="switch"
+	:aria-checked="checked"
+	:aria-disabled="disabled"
+	@click.prevent="toggle"
+>
+	<input
+		type="checkbox"
+		ref="input"
+		:disabled="disabled"
+		@keydown.enter="toggle"
 	>
-		<input
-			type="checkbox"
-			ref="input"
-			:disabled="disabled"
-			@keydown.enter="toggle"
-		>
-		<span class="button">
-			<span></span>
-		</span>
-		<span class="label">
-			<span><slot></slot></span>
-		</span>
-	</div>
-	<div class="_formCaption"><slot name="desc"></slot></div>
+	<span class="button" v-tooltip="checked ? $ts.itsOn : $ts.itsOff">
+		<span class="handle"></span>
+	</span>
+	<span class="label">
+		<span><slot></slot></span>
+		<p><slot name="caption"></slot></p>
+	</span>
 </div>
 </template>
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import './form.scss';
 
 export default defineComponent({
 	props: {
-		value: {
+		modelValue: {
 			type: Boolean,
 			default: false
 		},
@@ -40,91 +39,110 @@ export default defineComponent({
 	},
 	computed: {
 		checked(): boolean {
-			return this.value;
+			return this.modelValue;
 		}
 	},
 	methods: {
 		toggle() {
 			if (this.disabled) return;
-			this.$emit('update:value', !this.checked);
+			this.$emit('update:modelValue', !this.checked);
 		}
 	}
 });
 </script>
 
 <style lang="scss" scoped>
-.ijnpvmgr {
-	> .main {
+.ziffeoms {
+	position: relative;
+	display: flex;
+	cursor: pointer;
+	transition: all 0.3s;
+
+	&:first-child {
+		margin-top: 0;
+	}
+
+	&:last-child {
+		margin-bottom: 0;
+	}
+
+	> * {
+		user-select: none;
+	}
+
+	> input {
+		position: absolute;
+		width: 0;
+		height: 0;
+		opacity: 0;
+		margin: 0;
+	}
+
+	> .button {
 		position: relative;
-		display: flex;
-		padding: 14px 16px;
-		cursor: pointer;
+		display: inline-block;
+		flex-shrink: 0;
+		margin: 0;
+		width: 36px;
+		height: 26px;
+		background: var(--switchBg);
+		outline: none;
+		border-radius: 999px;
+		transition: inherit;
 
-		> * {
-			user-select: none;
-		}
-
-		&.disabled {
-			opacity: 0.6;
-			cursor: not-allowed;
-		}
-
-		&.checked {
-			> .button {
-				background-color: var(--X10);
-				border-color: var(--X10);
-
-				> * {
-					background-color: var(--accent);
-					transform: translateX(14px);
-				}
-			}
-		}
-
-		> input {
+		> .handle {
 			position: absolute;
-			width: 0;
-			height: 0;
-			opacity: 0;
-			margin: 0;
+			top: 0;
+			bottom: 0;
+			left: 5px;
+			margin: auto 0;
+			border-radius: 100%;
+			transition: background-color 0.3s, transform 0.3s;
+			width: 16px;
+			height: 16px;
+			background-color: #fff;
 		}
+	}
 
-		> .button {
-			position: relative;
-			display: inline-block;
-			flex-shrink: 0;
-			margin: 3px 0 0 0;
-			width: 34px;
-			height: 14px;
-			background: var(--X6);
-			outline: none;
-			border-radius: 14px;
-			transition: all 0.3s;
-			cursor: pointer;
+	> .label {
+		margin-left: 16px;
+		margin-top: 2px;
+		display: block;
+		cursor: pointer;
+		transition: inherit;
+		color: var(--fg);
 
-			> * {
-				position: absolute;
-				top: -3px;
-				left: 0;
-				border-radius: 100%;
-				transition: background-color 0.3s, transform 0.3s;
-				width: 20px;
-				height: 20px;
-				background-color: #fff;
-				box-shadow: 0 2px 1px -1px rgba(#000, 0.2), 0 1px 1px 0 rgba(#000, 0.14), 0 1px 3px 0 rgba(#000, 0.12);
-			}
-		}
-
-		> .label {
-			margin-left: 12px;
+		> span {
 			display: block;
+			line-height: 20px;
 			transition: inherit;
-			color: var(--fg);
+		}
 
-			> span {
-				display: block;
-				line-height: 20px;
-				transition: inherit;
+		> p {
+			margin: 0;
+			color: var(--fgTransparentWeak);
+			font-size: 90%;
+		}
+	}
+
+	&:hover {
+		> .button {
+			background-color: var(--accentedBg);
+		}
+	}
+
+	&.disabled {
+		opacity: 0.6;
+		cursor: not-allowed;
+	}
+
+	&.checked {
+		> .button {
+			background-color: var(--accent);
+			border-color: var(--accent);
+
+			> .handle {
+				transform: translateX(10px);
 			}
 		}
 	}
diff --git a/src/client/components/form/textarea.vue b/src/client/components/form/textarea.vue
index 8f42581a9b..50be69f930 100644
--- a/src/client/components/form/textarea.vue
+++ b/src/client/components/form/textarea.vue
@@ -1,40 +1,45 @@
 <template>
-<FormGroup class="_formItem">
-	<template #label><slot></slot></template>
-	<div class="rivhosbp _formItem" :class="{ tall, pre }">
-		<div class="input _formPanel">
-			<textarea ref="input" :class="{ code, _monospace: code }"
-				v-model="v"
-				:required="required"
-				:readonly="readonly"
-				:pattern="pattern"
-				:autocomplete="autocomplete"
-				:spellcheck="!code"
-				@input="onInput"
-				@focus="focused = true"
-				@blur="focused = false"
-			></textarea>
-		</div>
+<div class="adhpbeos">
+	<div class="label" @click="focus"><slot name="label"></slot></div>
+	<div class="input" :class="{ disabled, focused, tall, pre }">
+		<textarea ref="inputEl"
+			:class="{ code, _monospace: code }"
+			v-model="v"
+			:disabled="disabled"
+			:required="required"
+			:readonly="readonly"
+			:placeholder="placeholder"
+			:pattern="pattern"
+			:autocomplete="autocomplete"
+			:spellcheck="spellcheck"
+			@focus="focused = true"
+			@blur="focused = false"
+			@keydown="onKeydown($event)"
+			@input="onInput"
+		></textarea>
 	</div>
-	<template #caption><slot name="desc"></slot></template>
+	<div class="caption"><slot name="caption"></slot></div>
 
-	<FormButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
-</FormGroup>
+	<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
+</div>
 </template>
 
 <script lang="ts">
-import { defineComponent, ref, toRefs, watch } from 'vue';
-import './form.scss';
-import FormButton from './button.vue';
-import FormGroup from './group.vue';
+import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
+import MkButton from '../ui/button.vue';
+import { debounce } from 'throttle-debounce';
 
 export default defineComponent({
 	components: {
-		FormGroup,
-		FormButton,
+		MkButton,
 	},
+
 	props: {
-		value: {
+		modelValue: {
+			required: true
+		},
+		type: {
+			type: String,
 			required: false
 		},
 		required: {
@@ -45,14 +50,29 @@ export default defineComponent({
 			type: Boolean,
 			required: false
 		},
+		disabled: {
+			type: Boolean,
+			required: false
+		},
 		pattern: {
 			type: String,
 			required: false
 		},
-		autocomplete: {
+		placeholder: {
 			type: String,
 			required: false
 		},
+		autofocus: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
+		autocomplete: {
+			required: false
+		},
+		spellcheck: {
+			required: false
+		},
 		code: {
 			type: Boolean,
 			required: false
@@ -67,91 +87,162 @@ export default defineComponent({
 			required: false,
 			default: false
 		},
+		debounce: {
+			type: Boolean,
+			required: false,
+			default: false
+		},
 		manualSave: {
 			type: Boolean,
 			required: false,
 			default: false
 		},
 	},
+
+	emits: ['change', 'keydown', 'enter', 'update:modelValue'],
+
 	setup(props, context) {
-		const { value } = toRefs(props);
-		const v = ref(value.value);
+		const { modelValue, autofocus } = toRefs(props);
+		const v = ref(modelValue.value);
+		const focused = ref(false);
 		const changed = ref(false);
+		const invalid = ref(false);
+		const filled = computed(() => v.value !== '' && v.value != null);
 		const inputEl = ref(null);
+
 		const focus = () => inputEl.value.focus();
 		const onInput = (ev) => {
 			changed.value = true;
 			context.emit('change', ev);
 		};
+		const onKeydown = (ev: KeyboardEvent) => {
+			context.emit('keydown', ev);
+
+			if (ev.code === 'Enter') {
+				context.emit('enter');
+			}
+		};
 
 		const updated = () => {
 			changed.value = false;
-			context.emit('update:value', v.value);
+			context.emit('update:modelValue', v.value);
 		};
 
-		watch(value, newValue => {
+		const debouncedUpdated = debounce(1000, updated);
+
+		watch(modelValue, newValue => {
 			v.value = newValue;
 		});
 
 		watch(v, newValue => {
 			if (!props.manualSave) {
-				updated();
+				if (props.debounce) {
+					debouncedUpdated();
+				} else {
+					updated();
+				}
 			}
+
+			invalid.value = inputEl.value.validity.badInput;
 		});
-		
+
+		onMounted(() => {
+			nextTick(() => {
+				if (autofocus.value) {
+					focus();
+				}
+			});
+		});
+
 		return {
 			v,
-			updated,
+			focused,
+			invalid,
 			changed,
+			filled,
+			inputEl,
 			focus,
 			onInput,
+			onKeydown,
+			updated,
 		};
-	}
+	},
 });
 </script>
 
 <style lang="scss" scoped>
-.rivhosbp {
-	position: relative;
+.adhpbeos {
+	> .label {
+		font-size: 0.85em;
+		padding: 0 0 8px 12px;
+		user-select: none;
+
+		&:empty {
+			display: none;
+		}
+	}
+
+	> .caption {
+		font-size: 0.8em;
+		padding: 8px 0 0 12px;
+		color: var(--fgTransparentWeak);
+
+		&:empty {
+			display: none;
+		}
+	}
 
 	> .input {
 		position: relative;
-	
+
 		> textarea {
+			appearance: none;
+			-webkit-appearance: none;
 			display: block;
 			width: 100%;
 			min-width: 100%;
 			max-width: 100%;
 			min-height: 130px;
 			margin: 0;
-			padding: 16px;
-			box-sizing: border-box;
+			padding: 12px;
 			font: inherit;
 			font-weight: normal;
 			font-size: 1em;
-			background: transparent;
-			border: none;
-			border-radius: 0;
+			color: var(--fg);
+			background: var(--panel);
+			border: solid 0.5px var(--inputBorder);
+			border-radius: 6px;
 			outline: none;
 			box-shadow: none;
-			color: var(--fg);
+			box-sizing: border-box;
+			transition: border-color 0.1s ease-out;
 
-			&.code {
-				tab-size: 2;
+			&:hover {
+				border-color: var(--inputBorderHover);
 			}
 		}
-	}
 
-	&.tall {
-		> .input {
+		&.focused {
+			> textarea {
+				border-color: var(--accent);
+			}
+		}
+
+		&.disabled {
+			opacity: 0.7;
+
+			&, * {
+				cursor: not-allowed !important;
+			}
+		}
+
+		&.tall {
 			> textarea {
 				min-height: 200px;
 			}
 		}
-	}
 
-	&.pre {
-		> .input {
+		&.pre {
 			> textarea {
 				white-space: pre;
 			}
diff --git a/src/client/components/instance-stats.vue b/src/client/components/instance-stats.vue
index 78044f0b16..5e7c71ea65 100644
--- a/src/client/components/instance-stats.vue
+++ b/src/client/components/instance-stats.vue
@@ -36,7 +36,7 @@
 <script lang="ts">
 import { defineComponent, markRaw } from 'vue';
 import Chart from 'chart.js';
-import MkSelect from './ui/select.vue';
+import MkSelect from './form/select.vue';
 import number from '@client/filters/number';
 
 const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
diff --git a/src/client/components/note-detailed.vue b/src/client/components/note-detailed.vue
index e7f116d1fd..68e7c87f2e 100644
--- a/src/client/components/note-detailed.vue
+++ b/src/client/components/note-detailed.vue
@@ -59,7 +59,7 @@
 			<div class="body">
 				<p v-if="appearNote.cw != null" class="cw">
 					<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
-					<XCwButton v-model:value="showContent" :note="appearNote"/>
+					<XCwButton v-model="showContent" :note="appearNote"/>
 				</p>
 				<div class="content" v-show="appearNote.cw == null || showContent">
 					<div class="text">
diff --git a/src/client/components/note-preview.vue b/src/client/components/note-preview.vue
index 4248c2bb1d..406a475cd9 100644
--- a/src/client/components/note-preview.vue
+++ b/src/client/components/note-preview.vue
@@ -6,7 +6,7 @@
 		<div class="body">
 			<p v-if="note.cw != null" class="cw">
 				<span class="text" v-if="note.cw != ''">{{ note.cw }}</span>
-				<XCwButton v-model:value="showContent" :note="note"/>
+				<XCwButton v-model="showContent" :note="note"/>
 			</p>
 			<div class="content" v-show="note.cw == null || showContent">
 				<XSubNote-content class="text" :note="note"/>
diff --git a/src/client/components/note.sub.vue b/src/client/components/note.sub.vue
index 899c4b2f16..157b65ec5c 100644
--- a/src/client/components/note.sub.vue
+++ b/src/client/components/note.sub.vue
@@ -7,7 +7,7 @@
 			<div class="body">
 				<p v-if="note.cw != null" class="cw">
 					<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis" />
-					<XCwButton v-model:value="showContent" :note="note"/>
+					<XCwButton v-model="showContent" :note="note"/>
 				</p>
 				<div class="content" v-show="note.cw == null || showContent">
 					<XSubNote-content class="text" :note="note"/>
diff --git a/src/client/components/note.vue b/src/client/components/note.vue
index 38b529dd91..9fa986836d 100644
--- a/src/client/components/note.vue
+++ b/src/client/components/note.vue
@@ -43,7 +43,7 @@
 			<div class="body">
 				<p v-if="appearNote.cw != null" class="cw">
 					<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
-					<XCwButton v-model:value="showContent" :note="appearNote"/>
+					<XCwButton v-model="showContent" :note="appearNote"/>
 				</p>
 				<div class="content" :class="{ collapsed }" v-show="appearNote.cw == null || showContent">
 					<div class="text">
diff --git a/src/client/components/notification-setting-window.vue b/src/client/components/notification-setting-window.vue
index c33106ae15..0b41672170 100644
--- a/src/client/components/notification-setting-window.vue
+++ b/src/client/components/notification-setting-window.vue
@@ -29,7 +29,7 @@
 <script lang="ts">
 import { defineComponent, PropType } from 'vue';
 import XModalWindow from '@client/components/ui/modal-window.vue';
-import MkSwitch from './ui/switch.vue';
+import MkSwitch from './form/switch.vue';
 import MkInfo from './ui/info.vue';
 import MkButton from './ui/button.vue';
 import { notificationTypes } from '../../types';
diff --git a/src/client/components/page/page.number-input.vue b/src/client/components/page/page.number-input.vue
index 9c4a537e15..5d9168f130 100644
--- a/src/client/components/page/page.number-input.vue
+++ b/src/client/components/page/page.number-input.vue
@@ -8,7 +8,7 @@
 
 <script lang="ts">
 import { computed, defineComponent, PropType } from 'vue';
-import MkInput from '../ui/input.vue';
+import MkInput from '../form/input.vue';
 import * as os from '@client/os';
 import { Hpml } from '@client/scripts/hpml/evaluator';
 import { NumberInputVarBlock } from '@client/scripts/hpml/block';
diff --git a/src/client/components/page/page.post.vue b/src/client/components/page/page.post.vue
index 7b061d8cda..c20d7cade1 100644
--- a/src/client/components/page/page.post.vue
+++ b/src/client/components/page/page.post.vue
@@ -10,7 +10,7 @@
 
 <script lang="ts">
 import { defineComponent, PropType } from 'vue';
-import MkTextarea from '../ui/textarea.vue';
+import MkTextarea from '../form/textarea.vue';
 import MkButton from '../ui/button.vue';
 import { apiUrl } from '@client/config';
 import * as os from '@client/os';
diff --git a/src/client/components/page/page.radio-button.vue b/src/client/components/page/page.radio-button.vue
index f6f146b52f..590e59d706 100644
--- a/src/client/components/page/page.radio-button.vue
+++ b/src/client/components/page/page.radio-button.vue
@@ -7,7 +7,7 @@
 
 <script lang="ts">
 import { computed, defineComponent, PropType } from 'vue';
-import MkRadio from '../ui/radio.vue';
+import MkRadio from '../form/radio.vue';
 import * as os from '@client/os';
 import { Hpml } from '@client/scripts/hpml/evaluator';
 import { RadioButtonVarBlock } from '@client/scripts/hpml/block';
diff --git a/src/client/components/page/page.switch.vue b/src/client/components/page/page.switch.vue
index 8818e6cbcf..4d74e5df39 100644
--- a/src/client/components/page/page.switch.vue
+++ b/src/client/components/page/page.switch.vue
@@ -6,7 +6,7 @@
 
 <script lang="ts">
 import { computed, defineComponent, PropType } from 'vue';
-import MkSwitch from '../ui/switch.vue';
+import MkSwitch from '../form/switch.vue';
 import * as os from '@client/os';
 import { Hpml } from '@client/scripts/hpml/evaluator';
 import { SwitchVarBlock } from '@client/scripts/hpml/block';
diff --git a/src/client/components/page/page.text-input.vue b/src/client/components/page/page.text-input.vue
index 752d3d7257..6e9ac0b543 100644
--- a/src/client/components/page/page.text-input.vue
+++ b/src/client/components/page/page.text-input.vue
@@ -8,7 +8,7 @@
 
 <script lang="ts">
 import { computed, defineComponent, PropType } from 'vue';
-import MkInput from '../ui/input.vue';
+import MkInput from '../form/input.vue';
 import * as os from '@client/os';
 import { Hpml } from '@client/scripts/hpml/evaluator';
 import { TextInputVarBlock } from '@client/scripts/hpml/block';
diff --git a/src/client/components/page/page.textarea-input.vue b/src/client/components/page/page.textarea-input.vue
index e6cf5117f9..dfcb398937 100644
--- a/src/client/components/page/page.textarea-input.vue
+++ b/src/client/components/page/page.textarea-input.vue
@@ -8,7 +8,7 @@
 
 <script lang="ts">
 import { computed, defineComponent, PropType } from 'vue';
-import MkTextarea from '../ui/textarea.vue';
+import MkTextarea from '../form/textarea.vue';
 import * as os from '@client/os';
 import { Hpml } from '@client/scripts/hpml/evaluator';
 import { HpmlTextInput } from '@client/scripts/hpml';
diff --git a/src/client/components/page/page.textarea.vue b/src/client/components/page/page.textarea.vue
index 974c7f2c57..cf953bf041 100644
--- a/src/client/components/page/page.textarea.vue
+++ b/src/client/components/page/page.textarea.vue
@@ -6,7 +6,7 @@
 import { TextBlock } from '@client/scripts/hpml/block';
 import { Hpml } from '@client/scripts/hpml/evaluator';
 import { defineComponent, PropType } from 'vue';
-import MkTextarea from '../ui/textarea.vue';
+import MkTextarea from '../form/textarea.vue';
 
 export default defineComponent({
 	components: {
diff --git a/src/client/components/poll-editor.vue b/src/client/components/poll-editor.vue
index 0a9a1c6a03..b28a1c8baa 100644
--- a/src/client/components/poll-editor.vue
+++ b/src/client/components/poll-editor.vue
@@ -51,9 +51,9 @@
 import { defineComponent } from 'vue';
 import { addTime } from '../../prelude/time';
 import { formatDateTimeString } from '@/misc/format-time-string';
-import MkInput from './ui/input.vue';
-import MkSelect from './ui/select.vue';
-import MkSwitch from './ui/switch.vue';
+import MkInput from './form/input.vue';
+import MkSelect from './form/select.vue';
+import MkSwitch from './form/switch.vue';
 import MkButton from './ui/button.vue';
 
 export default defineComponent({
diff --git a/src/client/components/sample.vue b/src/client/components/sample.vue
index bce02466f6..c8b46a80e7 100644
--- a/src/client/components/sample.vue
+++ b/src/client/components/sample.vue
@@ -30,10 +30,10 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkRadio from '@client/components/ui/radio.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSwitch from '@client/components/form/switch.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkRadio from '@client/components/form/radio.vue';
 import * as os from '@client/os';
 import * as config from '@client/config';
 
diff --git a/src/client/components/signin.vue b/src/client/components/signin.vue
index 69f527b7d6..d6e1ee8b68 100755
--- a/src/client/components/signin.vue
+++ b/src/client/components/signin.vue
@@ -1,17 +1,17 @@
 <template>
 <form class="eppvobhk _monolithic_" :class="{ signing, totpLogin }" @submit.prevent="onSubmit">
-	<div class="auth _section">
+	<div class="auth _section _formRoot">
 		<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
 		<div class="normal-signin" v-if="!totpLogin">
-			<MkInput v-model="username" :placeholder="$ts.username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:modelValue="onUsernameChange" data-cy-signin-username>
+			<MkInput class="_formBlock" v-model="username" :placeholder="$ts.username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:modelValue="onUsernameChange" data-cy-signin-username>
 				<template #prefix>@</template>
 				<template #suffix>@{{ host }}</template>
 			</MkInput>
-			<MkInput v-model="password" :placeholder="$ts.password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required data-cy-signin-password>
+			<MkInput class="_formBlock" v-model="password" :placeholder="$ts.password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required data-cy-signin-password>
 				<template #prefix><i class="fas fa-lock"></i></template>
 				<template #caption><button class="_textButton" @click="resetPassword" type="button">{{ $ts.forgotPassword }}</button></template>
 			</MkInput>
-			<MkButton type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton>
+			<MkButton class="_formBlock" type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton>
 		</div>
 		<div class="2fa-signin" v-if="totpLogin" :class="{ securityKeys: user && user.securityKeys }">
 			<div v-if="user && user.securityKeys" class="twofa-group tap-group">
@@ -49,7 +49,7 @@
 import { defineComponent } from 'vue';
 import { toUnicode } from 'punycode/';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import { apiUrl, host } from '@client/config';
 import { byteify, hexify } from '@client/scripts/2fa';
 import * as os from '@client/os';
diff --git a/src/client/components/signup.vue b/src/client/components/signup.vue
index d332274111..f555c1df6d 100644
--- a/src/client/components/signup.vue
+++ b/src/client/components/signup.vue
@@ -1,11 +1,11 @@
 <template>
-<form class="qlvuhzng" @submit.prevent="onSubmit" :autocomplete="Math.random()">
+<form class="qlvuhzng _formRoot" @submit.prevent="onSubmit" :autocomplete="Math.random()">
 	<template v-if="meta">
-		<MkInput class="_inputNoTopMargin" v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
+		<MkInput class="_formBlock" v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required>
 			<template #label>{{ $ts.invitationCode }}</template>
 			<template #prefix><i class="fas fa-key"></i></template>
 		</MkInput>
-		<MkInput class="_inputNoTopMargin" v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeUsername" data-cy-signup-username>
+		<MkInput class="_formBlock" v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:modelValue="onChangeUsername" data-cy-signup-username>
 			<template #label>{{ $ts.username }} <div class="_button _help" v-tooltip:dialog="$ts.usernameInfo"><i class="far fa-question-circle"></i></div></template>
 			<template #prefix>@</template>
 			<template #suffix>@{{ host }}</template>
@@ -19,7 +19,7 @@
 				<span v-if="usernameState == 'max-range'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.tooLong }}</span>
 			</template>
 		</MkInput>
-		<MkInput v-model="password" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePassword" data-cy-signup-password>
+		<MkInput class="_formBlock" v-model="password" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePassword" data-cy-signup-password>
 			<template #label>{{ $ts.password }}</template>
 			<template #prefix><i class="fas fa-lock"></i></template>
 			<template #caption>
@@ -28,7 +28,7 @@
 				<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="fas fa-check fa-fw"></i> {{ $ts.strongPassword }}</span>
 			</template>
 		</MkInput>
-		<MkInput v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePasswordRetype" data-cy-signup-password-retype>
+		<MkInput class="_formBlock" v-model="retypedPassword" type="password" :autocomplete="Math.random()" required @update:modelValue="onChangePasswordRetype" data-cy-signup-password-retype>
 			<template #label>{{ $ts.password }} ({{ $ts.retype }})</template>
 			<template #prefix><i class="fas fa-lock"></i></template>
 			<template #caption>
@@ -36,7 +36,7 @@
 				<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="fas fa-exclamation-triangle fa-fw"></i> {{ $ts.passwordNotMatched }}</span>
 			</template>
 		</MkInput>
-		<label v-if="meta.tosUrl" class="tou">
+		<label v-if="meta.tosUrl" class="_formBlock tou">
 			<input type="checkbox" v-model="ToSAgreement">
 			<I18n :src="$ts.agreeTo">
 				<template #0>
@@ -44,9 +44,9 @@
 				</template>
 			</I18n>
 		</label>
-		<captcha v-if="meta.enableHcaptcha" class="captcha" provider="hcaptcha" ref="hcaptcha" v-model:value="hCaptchaResponse" :sitekey="meta.hcaptchaSiteKey"/>
-		<captcha v-if="meta.enableRecaptcha" class="captcha" provider="recaptcha" ref="recaptcha" v-model:value="reCaptchaResponse" :sitekey="meta.recaptchaSiteKey"/>
-		<MkButton type="submit" :disabled="shouldDisableSubmitting" primary data-cy-signup-submit>{{ $ts.start }}</MkButton>
+		<captcha v-if="meta.enableHcaptcha" class="_formBlock captcha" provider="hcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :sitekey="meta.hcaptchaSiteKey"/>
+		<captcha v-if="meta.enableRecaptcha" class="_formBlock captcha" provider="recaptcha" ref="recaptcha" v-model="reCaptchaResponse" :sitekey="meta.recaptchaSiteKey"/>
+		<MkButton class="_formBlock" type="submit" :disabled="shouldDisableSubmitting" primary data-cy-signup-submit>{{ $ts.start }}</MkButton>
 	</template>
 </form>
 </template>
@@ -57,8 +57,8 @@ const getPasswordStrength = require('syuilo-password-strength');
 import { toUnicode } from 'punycode/';
 import { host, url } from '@client/config';
 import MkButton from './ui/button.vue';
-import MkInput from './ui/input.vue';
-import MkSwitch from './ui/switch.vue';
+import MkInput from './form/input.vue';
+import MkSwitch from './form/switch.vue';
 import * as os from '@client/os';
 import { login } from '@client/account';
 
diff --git a/src/client/components/tab.vue b/src/client/components/tab.vue
index 3902b7f98f..7705fc3d6d 100644
--- a/src/client/components/tab.vue
+++ b/src/client/components/tab.vue
@@ -3,7 +3,7 @@ import { defineComponent, h, resolveDirective, withDirectives } from 'vue';
 
 export default defineComponent({
 	props: {
-		value: {
+		modelValue: {
 			required: true,
 		},
 	},
@@ -13,11 +13,11 @@ export default defineComponent({
 		return withDirectives(h('div', {
 			class: 'pxhvhrfw',
 		}, options.map(option => withDirectives(h('button', {
-			class: ['_button', { active: this.value === option.props.value }],
+			class: ['_button', { active: this.modelValue === option.props.modelValue }],
 			key: option.key,
-			disabled: this.value === option.props.value,
+			disabled: this.modelValue === option.props.modelValue,
 			onClick: () => {
-				this.$emit('update:value', option.props.value);
+				this.$emit('update:modelValue', option.props.modelValue);
 			}
 		}, option.children), [
 			[resolveDirective('click-anime')]
diff --git a/src/client/components/taskmanager.api-window.vue b/src/client/components/taskmanager.api-window.vue
index c9b2c43413..807e4a0075 100644
--- a/src/client/components/taskmanager.api-window.vue
+++ b/src/client/components/taskmanager.api-window.vue
@@ -9,7 +9,7 @@
 	<template #header>Req Viewer</template>
 
 	<div class="rlkneywz">
-		<MkTab v-model:value="tab" style="border-bottom: solid 0.5px var(--divider);">
+		<MkTab v-model="tab" style="border-bottom: solid 0.5px var(--divider);">
 			<option value="req">Request</option>
 			<option value="res">Response</option>
 		</MkTab>
diff --git a/src/client/components/taskmanager.vue b/src/client/components/taskmanager.vue
index cb8cb78748..6f3d1b0354 100644
--- a/src/client/components/taskmanager.vue
+++ b/src/client/components/taskmanager.vue
@@ -4,7 +4,7 @@
 		<i class="fas fa-terminal" style="margin-right: 0.5em;"></i>Task Manager
 	</template>
 	<div class="qljqmnzj _monospace">
-		<MkTab v-model:value="tab" style="border-bottom: solid 0.5px var(--divider);">
+		<MkTab v-model="tab" style="border-bottom: solid 0.5px var(--divider);">
 			<option value="windows">Windows</option>
 			<option value="stream">Stream</option>
 			<option value="streamPool">Stream (Pool)</option>
diff --git a/src/client/components/token-generate-window.vue b/src/client/components/token-generate-window.vue
index fe61f61efa..86312564cc 100644
--- a/src/client/components/token-generate-window.vue
+++ b/src/client/components/token-generate-window.vue
@@ -31,9 +31,9 @@
 import { defineComponent } from 'vue';
 import { kinds } from '@/misc/api-permissions';
 import XModalWindow from '@client/components/ui/modal-window.vue';
-import MkInput from './ui/input.vue';
-import MkTextarea from './ui/textarea.vue';
-import MkSwitch from './ui/switch.vue';
+import MkInput from './form/input.vue';
+import MkTextarea from './form/textarea.vue';
+import MkSwitch from './form/switch.vue';
 import MkButton from './ui/button.vue';
 import MkInfo from './ui/info.vue';
 
diff --git a/src/client/components/ui/button.vue b/src/client/components/ui/button.vue
index d6ac42994f..6e3cd485c8 100644
--- a/src/client/components/ui/button.vue
+++ b/src/client/components/ui/button.vue
@@ -181,14 +181,6 @@ export default defineComponent({
 		outline-offset: 2px;
 	}
 
-	&.inline + .bghgjjyj {
-		margin-left: 12px;
-	}
-
-	&:not(.inline) + .bghgjjyj {
-		margin-top: 16px;
-	}
-
 	&.inline {
 		display: inline-block;
 		width: auto;
diff --git a/src/client/components/ui/radios.vue b/src/client/components/ui/radios.vue
deleted file mode 100644
index 8a62b87683..0000000000
--- a/src/client/components/ui/radios.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<script lang="ts">
-import { defineComponent, h } from 'vue';
-import MkRadio from '@client/components/ui/radio.vue';
-
-export default defineComponent({
-	components: {
-		MkRadio
-	},
-	props: {
-		modelValue: {
-			required: false
-		},
-	},
-	data() {
-		return {
-			value: this.modelValue,
-		}
-	},
-	watch: {
-		value() {
-			this.$emit('update:modelValue', this.value);
-		}
-	},
-	render() {
-		const label = this.$slots.desc();
-		let options = this.$slots.default();
-
-		// なぜかFragmentになることがあるため
-		if (options.length === 1 && options[0].props == null) options = options[0].children;
-
-		return h('div', {
-			class: 'novjtcto'
-		}, [
-			h('div', label),
-			...options.map(option => h(MkRadio, {
-				key: option.key,
-				value: option.props.value,
-				modelValue: this.value,
-				'onUpdate:modelValue': value => this.value = value,
-			}, option.children))
-		]);
-	}
-});
-</script>
-
-<style lang="scss">
-.novjtcto {
-	margin: 32px 0;
-
-	&:first-child {
-		margin-top: 0;
-	}
-
-	&:last-child {
-		margin-bottom: 0;
-	}
-}
-</style>
diff --git a/src/client/components/ui/range.vue b/src/client/components/ui/range.vue
deleted file mode 100644
index 4cfe66a8fc..0000000000
--- a/src/client/components/ui/range.vue
+++ /dev/null
@@ -1,139 +0,0 @@
-<template>
-<div class="timctyfi" :class="{ focused, disabled }">
-	<div class="icon"><slot name="icon"></slot></div>
-	<span class="label"><slot name="label"></slot></span>
-	<input
-		type="range"
-		ref="input"
-		v-model="v"
-		:disabled="disabled"
-		:min="min"
-		:max="max"
-		:step="step"
-		:autofocus="autofocus"
-		@focus="focused = true"
-		@blur="focused = false"
-		@input="$emit('update:value', $event.target.value)"
-	/>
-</div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-	props: {
-		value: {
-			type: Number,
-			required: false,
-			default: 0
-		},
-		disabled: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-		min: {
-			type: Number,
-			required: false,
-			default: 0
-		},
-		max: {
-			type: Number,
-			required: false,
-			default: 100
-		},
-		step: {
-			type: Number,
-			required: false,
-			default: 1
-		},
-		autofocus: {
-			type: Boolean,
-			required: false
-		}
-	},
-	data() {
-		return {
-			v: this.value,
-			focused: false
-		};
-	},
-	watch: {
-		value(v) {
-			this.v = parseFloat(v);
-		}
-	},
-	mounted() {
-		if (this.autofocus) {
-			this.$nextTick(() => {
-				this.$refs.input.focus();
-			});
-		}
-	}
-});
-</script>
-
-<style lang="scss" scoped>
-.timctyfi {
-	position: relative;
-	margin: 8px;
-
-	> .icon {
-		display: inline-block;
-		width: 24px;
-		text-align: center;
-	}
-
-	> .title {
-		pointer-events: none;
-		font-size: 16px;
-		color: var(--inputLabel);
-		overflow: hidden;
-	}
-
-	> input {
-		-webkit-appearance: none;
-		-moz-appearance: none;
-		appearance: none;
-		background: var(--X10);
-		height: 7px;
-		margin: 0 8px;
-		outline: 0;
-		border: 0;
-		border-radius: 7px;
-
-		&.disabled {
-			opacity: 0.6;
-			cursor: not-allowed;
-		}
-
-		&::-webkit-slider-thumb {
-			-webkit-appearance: none;
-			appearance: none;
-			cursor: pointer;
-			width: 20px;
-			height: 20px;
-			display: block;
-			border-radius: 50%;
-			border: none;
-			background: var(--accent);
-			box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
-			box-sizing: content-box;
-		}
-
-		&::-moz-range-thumb {
-			-moz-appearance: none;
-			appearance: none;
-			cursor: pointer;
-			width: 20px;
-			height: 20px;
-			display: block;
-			border-radius: 50%;
-			border: none;
-			background: var(--accent);
-			box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
-		}
-	}
-}
-</style>
diff --git a/src/client/components/ui/select.vue b/src/client/components/ui/select.vue
deleted file mode 100644
index e9d43d8a64..0000000000
--- a/src/client/components/ui/select.vue
+++ /dev/null
@@ -1,262 +0,0 @@
-<template>
-<div class="vblkjoeq">
-	<div class="label" @click="focus"><slot name="label"></slot></div>
-	<div class="input" :class="{ inline, disabled, focused }">
-		<div class="prefix" ref="prefixEl"><slot name="prefix"></slot></div>
-		<select ref="inputEl"
-			v-model="v"
-			:disabled="disabled"
-			:required="required"
-			:readonly="readonly"
-			:placeholder="placeholder"
-			@focus="focused = true"
-			@blur="focused = false"
-			@input="onInput"
-		>
-			<slot></slot>
-		</select>
-		<div class="suffix" ref="suffixEl"><i class="fas fa-chevron-down"></i></div>
-	</div>
-	<div class="caption"><slot name="caption"></slot></div>
-
-	<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
-</div>
-</template>
-
-<script lang="ts">
-import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
-import MkButton from './button.vue';
-
-export default defineComponent({
-	components: {
-		MkButton,
-	},
-
-	props: {
-		modelValue: {
-			required: true
-		},
-		required: {
-			type: Boolean,
-			required: false
-		},
-		readonly: {
-			type: Boolean,
-			required: false
-		},
-		disabled: {
-			type: Boolean,
-			required: false
-		},
-		placeholder: {
-			type: String,
-			required: false
-		},
-		autofocus: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-		inline: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-		manualSave: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-	},
-
-	emits: ['change', 'update:modelValue'],
-
-	setup(props, context) {
-		const { modelValue, autofocus } = toRefs(props);
-		const v = ref(modelValue.value);
-		const focused = ref(false);
-		const changed = ref(false);
-		const invalid = ref(false);
-		const filled = computed(() => v.value !== '' && v.value != null);
-		const inputEl = ref(null);
-		const prefixEl = ref(null);
-		const suffixEl = ref(null);
-
-		const focus = () => inputEl.value.focus();
-		const onInput = (ev) => {
-			changed.value = true;
-			context.emit('change', ev);
-		};
-
-		const updated = () => {
-			changed.value = false;
-			context.emit('update:modelValue', v.value);
-		};
-
-		watch(modelValue, newValue => {
-			v.value = newValue;
-		});
-
-		watch(v, newValue => {
-			if (!props.manualSave) {
-				updated();
-			}
-
-			invalid.value = inputEl.value.validity.badInput;
-		});
-
-		onMounted(() => {
-			nextTick(() => {
-				if (autofocus.value) {
-					focus();
-				}
-
-				// このコンポーネントが作成された時、非表示状態である場合がある
-				// 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する
-				const clock = setInterval(() => {
-					if (prefixEl.value) {
-						if (prefixEl.value.offsetWidth) {
-							inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + 'px';
-						}
-					}
-					if (suffixEl.value) {
-						if (suffixEl.value.offsetWidth) {
-							inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + 'px';
-						}
-					}
-				}, 100);
-
-				onUnmounted(() => {
-					clearInterval(clock);
-				});
-			});
-		});
-
-		return {
-			v,
-			focused,
-			invalid,
-			changed,
-			filled,
-			inputEl,
-			prefixEl,
-			suffixEl,
-			focus,
-			onInput,
-			updated,
-		};
-	},
-});
-</script>
-
-<style lang="scss" scoped>
-.vblkjoeq {
-	margin: 1.5em 0;
-
-	> .label {
-		font-size: 0.85em;
-		padding: 0 0 8px 12px;
-		user-select: none;
-
-		&:empty {
-			display: none;
-		}
-	}
-
-	> .caption {
-		font-size: 0.8em;
-		padding: 8px 0 0 12px;
-		color: var(--fgTransparentWeak);
-
-		&:empty {
-			display: none;
-		}
-	}
-
-	> .input {
-		$height: 42px;
-		position: relative;
-
-		> select {
-			appearance: none;
-			-webkit-appearance: none;
-			display: block;
-			height: $height;
-			width: 100%;
-			margin: 0;
-			padding: 0 12px;
-			font: inherit;
-			font-weight: normal;
-			font-size: 1em;
-			color: var(--fg);
-			background: var(--panel);
-			border: solid 1px var(--inputBorder);
-			border-radius: 6px;
-			outline: none;
-			box-shadow: none;
-			box-sizing: border-box;
-			cursor: pointer;
-			transition: border-color 0.1s ease-out;
-
-			&:hover {
-				border-color: var(--inputBorderHover);
-			}
-		}
-
-		> .prefix,
-		> .suffix {
-			display: flex;
-			align-items: center;
-			position: absolute;
-			z-index: 1;
-			top: 0;
-			padding: 0 12px;
-			font-size: 1em;
-			height: $height;
-			pointer-events: none;
-
-			&:empty {
-				display: none;
-			}
-
-			> * {
-				display: inline-block;
-				min-width: 16px;
-				max-width: 150px;
-				overflow: hidden;
-				white-space: nowrap;
-				text-overflow: ellipsis;
-			}
-		}
-
-		> .prefix {
-			left: 0;
-			padding-right: 6px;
-		}
-
-		> .suffix {
-			right: 0;
-			padding-left: 6px;
-		}
-
-		&.inline {
-			display: inline-block;
-			margin: 0;
-		}
-
-		&.focused {
-			> select {
-				border-color: var(--accent);
-			}
-		}
-
-		&.disabled {
-			opacity: 0.7;
-
-			&, * {
-				cursor: not-allowed !important;
-			}
-		}
-	}
-}
-</style>
diff --git a/src/client/components/ui/switch.vue b/src/client/components/ui/switch.vue
deleted file mode 100644
index 7aa9c0619d..0000000000
--- a/src/client/components/ui/switch.vue
+++ /dev/null
@@ -1,144 +0,0 @@
-<template>
-<div
-	class="ziffeoms"
-	:class="{ disabled, checked }"
-	role="switch"
-	:aria-checked="checked"
-	:aria-disabled="disabled"
-	@click.prevent="toggle"
->
-	<input
-		type="checkbox"
-		ref="input"
-		:disabled="disabled"
-		@keydown.enter="toggle"
-	>
-	<span class="button">
-		<span></span>
-	</span>
-	<span class="label">
-		<span><slot></slot></span>
-		<p><slot name="caption"></slot></p>
-	</span>
-</div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-	props: {
-		modelValue: {
-			type: Boolean,
-			default: false
-		},
-		disabled: {
-			type: Boolean,
-			default: false
-		}
-	},
-	computed: {
-		checked(): boolean {
-			return this.modelValue;
-		}
-	},
-	methods: {
-		toggle() {
-			if (this.disabled) return;
-			this.$emit('update:modelValue', !this.checked);
-		}
-	}
-});
-</script>
-
-<style lang="scss" scoped>
-.ziffeoms {
-	position: relative;
-	display: flex;
-	margin: 32px 0;
-	cursor: pointer;
-	transition: all 0.3s;
-
-	&:first-child {
-		margin-top: 0;
-	}
-
-	&:last-child {
-		margin-bottom: 0;
-	}
-
-	> * {
-		user-select: none;
-	}
-
-	&.disabled {
-		opacity: 0.6;
-		cursor: not-allowed;
-	}
-
-	&.checked {
-		> .button {
-			background-color: var(--X10);
-			border-color: var(--X10);
-
-			> * {
-				background-color: var(--accent);
-				transform: translateX(14px);
-			}
-		}
-	}
-
-	> input {
-		position: absolute;
-		width: 0;
-		height: 0;
-		opacity: 0;
-		margin: 0;
-	}
-
-	> .button {
-		position: relative;
-		display: inline-block;
-		flex-shrink: 0;
-		margin: 3px 0 0 0;
-		width: 34px;
-		height: 14px;
-		background: var(--X6);
-		outline: none;
-		border-radius: 14px;
-		transition: inherit;
-
-		> * {
-			position: absolute;
-			top: -3px;
-			left: 0;
-			border-radius: 100%;
-			transition: background-color 0.3s, transform 0.3s;
-			width: 20px;
-			height: 20px;
-			background-color: #fff;
-			box-shadow: 0 2px 1px -1px rgba(#000, 0.2), 0 1px 1px 0 rgba(#000, 0.14), 0 1px 3px 0 rgba(#000, 0.12);
-		}
-	}
-
-	> .label {
-		margin-left: 8px;
-		display: block;
-		cursor: pointer;
-		transition: inherit;
-		color: var(--fg);
-
-		> span {
-			display: block;
-			line-height: 20px;
-			transition: inherit;
-		}
-
-		> p {
-			margin: 0;
-			color: var(--fgTransparentWeak);
-			font-size: 90%;
-		}
-	}
-}
-</style>
diff --git a/src/client/components/ui/textarea.vue b/src/client/components/ui/textarea.vue
deleted file mode 100644
index 08ac3182a9..0000000000
--- a/src/client/components/ui/textarea.vue
+++ /dev/null
@@ -1,254 +0,0 @@
-<template>
-<div class="adhpbeos">
-	<div class="label" @click="focus"><slot name="label"></slot></div>
-	<div class="input" :class="{ disabled, focused, tall, pre }">
-		<textarea ref="inputEl"
-			:class="{ code, _monospace: code }"
-			v-model="v"
-			:disabled="disabled"
-			:required="required"
-			:readonly="readonly"
-			:placeholder="placeholder"
-			:pattern="pattern"
-			:autocomplete="autocomplete"
-			:spellcheck="spellcheck"
-			@focus="focused = true"
-			@blur="focused = false"
-			@keydown="onKeydown($event)"
-			@input="onInput"
-		></textarea>
-	</div>
-	<div class="caption"><slot name="caption"></slot></div>
-
-	<MkButton v-if="manualSave && changed" @click="updated" primary><i class="fas fa-save"></i> {{ $ts.save }}</MkButton>
-</div>
-</template>
-
-<script lang="ts">
-import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
-import MkButton from './button.vue';
-import { debounce } from 'throttle-debounce';
-
-export default defineComponent({
-	components: {
-		MkButton,
-	},
-
-	props: {
-		modelValue: {
-			required: true
-		},
-		type: {
-			type: String,
-			required: false
-		},
-		required: {
-			type: Boolean,
-			required: false
-		},
-		readonly: {
-			type: Boolean,
-			required: false
-		},
-		disabled: {
-			type: Boolean,
-			required: false
-		},
-		pattern: {
-			type: String,
-			required: false
-		},
-		placeholder: {
-			type: String,
-			required: false
-		},
-		autofocus: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-		autocomplete: {
-			required: false
-		},
-		spellcheck: {
-			required: false
-		},
-		code: {
-			type: Boolean,
-			required: false
-		},
-		tall: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-		pre: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-		debounce: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-		manualSave: {
-			type: Boolean,
-			required: false,
-			default: false
-		},
-	},
-
-	emits: ['change', 'keydown', 'enter', 'update:modelValue'],
-
-	setup(props, context) {
-		const { modelValue, autofocus } = toRefs(props);
-		const v = ref(modelValue.value);
-		const focused = ref(false);
-		const changed = ref(false);
-		const invalid = ref(false);
-		const filled = computed(() => v.value !== '' && v.value != null);
-		const inputEl = ref(null);
-
-		const focus = () => inputEl.value.focus();
-		const onInput = (ev) => {
-			changed.value = true;
-			context.emit('change', ev);
-		};
-		const onKeydown = (ev: KeyboardEvent) => {
-			context.emit('keydown', ev);
-
-			if (ev.code === 'Enter') {
-				context.emit('enter');
-			}
-		};
-
-		const updated = () => {
-			changed.value = false;
-			context.emit('update:modelValue', v.value);
-		};
-
-		const debouncedUpdated = debounce(1000, updated);
-
-		watch(modelValue, newValue => {
-			v.value = newValue;
-		});
-
-		watch(v, newValue => {
-			if (!props.manualSave) {
-				if (props.debounce) {
-					debouncedUpdated();
-				} else {
-					updated();
-				}
-			}
-
-			invalid.value = inputEl.value.validity.badInput;
-		});
-
-		onMounted(() => {
-			nextTick(() => {
-				if (autofocus.value) {
-					focus();
-				}
-			});
-		});
-
-		return {
-			v,
-			focused,
-			invalid,
-			changed,
-			filled,
-			inputEl,
-			focus,
-			onInput,
-			onKeydown,
-			updated,
-		};
-	},
-});
-</script>
-
-<style lang="scss" scoped>
-.adhpbeos {
-	margin: 1.5em 0;
-
-	> .label {
-		font-size: 0.85em;
-		padding: 0 0 8px 12px;
-		user-select: none;
-
-		&:empty {
-			display: none;
-		}
-	}
-
-	> .caption {
-		font-size: 0.8em;
-		padding: 8px 0 0 12px;
-		color: var(--fgTransparentWeak);
-
-		&:empty {
-			display: none;
-		}
-	}
-
-	> .input {
-		position: relative;
-
-		> textarea {
-			appearance: none;
-			-webkit-appearance: none;
-			display: block;
-			width: 100%;
-			min-width: 100%;
-			max-width: 100%;
-			min-height: 130px;
-			margin: 0;
-			padding: 12px;
-			font: inherit;
-			font-weight: normal;
-			font-size: 1em;
-			color: var(--fg);
-			background: var(--panel);
-			border: solid 0.5px var(--inputBorder);
-			border-radius: 6px;
-			outline: none;
-			box-shadow: none;
-			box-sizing: border-box;
-			transition: border-color 0.1s ease-out;
-
-			&:hover {
-				border-color: var(--inputBorderHover);
-			}
-		}
-
-		&.focused {
-			> textarea {
-				border-color: var(--accent);
-			}
-		}
-
-		&.disabled {
-			opacity: 0.7;
-
-			&, * {
-				cursor: not-allowed !important;
-			}
-		}
-
-		&.tall {
-			> textarea {
-				min-height: 200px;
-			}
-		}
-
-		&.pre {
-			> textarea {
-				white-space: pre;
-			}
-		}
-	}
-}
-</style>
diff --git a/src/client/components/user-select-dialog.vue b/src/client/components/user-select-dialog.vue
index 87c32dab25..0f3ee2a126 100644
--- a/src/client/components/user-select-dialog.vue
+++ b/src/client/components/user-select-dialog.vue
@@ -10,7 +10,7 @@
 	<template #header>{{ $ts.selectUser }}</template>
 	<div class="tbhwbxda _monolithic_">
 		<div class="_section">
-			<div class="_inputSplit _inputNoTopMargin _inputNoBottomMargin">
+			<div class="_inputSplit">
 				<MkInput v-model="username" class="input" @update:modelValue="search" ref="username">
 					<template #label>{{ $ts.username }}</template>
 					<template #prefix>@</template>
@@ -52,7 +52,7 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import MkInput from './ui/input.vue';
+import MkInput from './form/input.vue';
 import XModalWindow from '@client/components/ui/modal-window.vue';
 import * as os from '@client/os';
 
diff --git a/src/client/components/widgets.vue b/src/client/components/widgets.vue
index 150d61c027..aef5de453c 100644
--- a/src/client/components/widgets.vue
+++ b/src/client/components/widgets.vue
@@ -30,7 +30,7 @@
 <script lang="ts">
 import { defineComponent, defineAsyncComponent } from 'vue';
 import { v4 as uuid } from 'uuid';
-import MkSelect from '@client/components/ui/select.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkButton from '@client/components/ui/button.vue';
 import { widgets as widgetDefs } from '@client/widgets';
 
diff --git a/src/client/pages/about-misskey.vue b/src/client/pages/about-misskey.vue
index 384c7e8ccb..d2c0ec0550 100644
--- a/src/client/pages/about-misskey.vue
+++ b/src/client/pages/about-misskey.vue
@@ -2,15 +2,15 @@
 <div style="overflow: clip;">
 	<FormBase class="znqjceqz">
 		<div id="debug"></div>
-		<section class="_formItem about">
-			<div class="_formPanel panel" :class="{ playing: easterEggEngine != null }" ref="about">
+		<section class="_debobigegoItem about">
+			<div class="_debobigegoPanel panel" :class="{ playing: easterEggEngine != null }" ref="about">
 				<img src="/static-assets/client/about-icon.png" alt="" class="icon" @load="iconLoaded" draggable="false" @click="gravity"/>
 				<div class="misskey">Misskey</div>
 				<div class="version">v{{ version }}</div>
 				<span class="emoji" v-for="emoji in easterEggEmojis" :key="emoji.id" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }"><MkEmoji class="emoji" :emoji="emoji.emoji" :custom-emojis="$instance.emojis" :is-reaction="false" :normal="true" :no-style="true"/></span>
 			</div>
 		</section>
-		<section class="_formItem" style="text-align: center; padding: 0 16px;">
+		<section class="_debobigegoItem" style="text-align: center; padding: 0 16px;">
 			{{ $ts._aboutMisskey.about }}<br><MkA class="_link" to="/docs/general/misskey">{{ $ts.learnMore }}</MkA>
 		</section>
 		<FormGroup>
@@ -55,10 +55,10 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import { version } from '@client/config';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
 import MkLink from '@client/components/link.vue';
 import { physics } from '@client/scripts/physics';
 import * as symbols from '@client/symbols';
diff --git a/src/client/pages/about.vue b/src/client/pages/about.vue
index bdd4c78827..2c580c293a 100644
--- a/src/client/pages/about.vue
+++ b/src/client/pages/about.vue
@@ -1,7 +1,7 @@
 <template>
 <FormBase>
-	<div class="_formItem">
-		<div class="_formPanel fwhjspax">
+	<div class="_debobigegoItem">
+		<div class="_debobigegoPanel fwhjspax">
 			<img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
 			<span class="name">{{ $instance.name || host }}</span>
 		</div>
@@ -59,12 +59,12 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import { version, instanceName } from '@client/config';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import number from '@client/filters/number';
 import * as symbols from '@client/symbols';
diff --git a/src/client/pages/advanced-theme-editor.vue b/src/client/pages/advanced-theme-editor.vue
index c03d88b82d..8a63d74887 100644
--- a/src/client/pages/advanced-theme-editor.vue
+++ b/src/client/pages/advanced-theme-editor.vue
@@ -4,7 +4,7 @@
 		<div class="_content">
 			<details>
 				<summary>{{ $ts.import }}</summary>
-				<MkTextarea v-model:value="themeToImport">
+				<MkTextarea v-model="themeToImport">
 					{{ $ts._theme.importInfo }}
 				</MkTextarea>
 				<MkButton :disabled="!themeToImport.trim()" @click="importTheme">{{ $ts.import }}</MkButton>
@@ -14,9 +14,9 @@
 	<section class="_section">
 		<div class="_content _card _gap">
 			<div class="_content">
-				<MkInput v-model:value="name" required><span>{{ $ts.name }}</span></MkInput>
-				<MkInput v-model:value="author" required><span>{{ $ts.author }}</span></MkInput>
-				<MkTextarea v-model:value="description"><span>{{ $ts.description }}</span></MkTextarea>
+				<MkInput v-model="name" required><span>{{ $ts.name }}</span></MkInput>
+				<MkInput v-model="author" required><span>{{ $ts.author }}</span></MkInput>
+				<MkTextarea v-model="description"><span>{{ $ts.description }}</span></MkTextarea>
 				<div class="_inputs">
 					<div v-text="$ts._theme.base" />
 					<MkRadio v-model="baseTheme" value="light">{{ $ts.light }}</MkRadio>
@@ -41,31 +41,31 @@
 							<!-- color -->
 							<div v-else-if="typeof v === 'string'" class="color">
 								<input type="color" :value="v" @input="colorChanged($event.target.value, i)"/>
-								<MkInput class="select" :value="v" @update:value="colorChanged($event, i)"/>
+								<MkInput class="select" :value="v" @update:modelValue="colorChanged($event, i)"/>
 							</div>
 							<!-- ref const -->
-							<MkInput v-else-if="v.type === 'refConst'" v-model:value="v.key">
+							<MkInput v-else-if="v.type === 'refConst'" v-model="v.key">
 								<template #prefix>$</template>
 								<span>{{ $ts.name }}</span>
 							</MkInput>
 							<!-- ref props -->
-							<MkSelect class="select" v-else-if="v.type === 'refProp'" v-model:value="v.key">
+							<MkSelect class="select" v-else-if="v.type === 'refProp'" v-model="v.key">
 								<option v-for="key in themeProps" :value="key" :key="key">{{ $t('_theme.keys.' + key) }}</option>
 							</MkSelect>
 							<!-- func -->
 							<template v-else-if="v.type === 'func'">
-								<MkSelect class="select" v-model:value="v.name">
+								<MkSelect class="select" v-model="v.name">
 									<template #label>{{ $ts._theme.funcKind }}</template>
 									<option v-for="n in ['alpha', 'darken', 'lighten']" :value="n" :key="n">{{ $t('_theme.' + n) }}</option>
 								</MkSelect>
-								<MkInput type="number" v-model:value="v.arg"><span>{{ $ts._theme.argument }}</span></MkInput>
-								<MkSelect class="select" v-model:value="v.value">
+								<MkInput type="number" v-model="v.arg"><span>{{ $ts._theme.argument }}</span></MkInput>
+								<MkSelect class="select" v-model="v.value">
 									<template #label>{{ $ts._theme.basedProp }}</template>
 									<option v-for="key in themeProps" :value="key" :key="key">{{ $t('_theme.keys.' + key) }}</option>
 								</MkSelect>
 							</template>
 							<!-- CSS -->
-							<MkInput v-else-if="v.type === 'css'" v-model:value="v.value">
+							<MkInput v-else-if="v.type === 'css'" v-model="v.value">
 								<span>CSS</span>
 							</MkInput>
 						</div>
@@ -95,11 +95,11 @@ import { defineComponent } from 'vue';
 import * as JSON5 from 'json5';
 import { toUnicode } from 'punycode/';
 
-import MkRadio from '@client/components/ui/radio.vue';
+import MkRadio from '@client/components/form/radio.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkSample from '@client/components/sample.vue';
 
 import { convertToMisskeyTheme, ThemeValue, convertToViewModel, ThemeViewModel } from '@client/scripts/theme-editor';
diff --git a/src/client/pages/api-console.vue b/src/client/pages/api-console.vue
index c6d459fd6d..9aa7d4ea4d 100644
--- a/src/client/pages/api-console.vue
+++ b/src/client/pages/api-console.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="_root">
 	<div class="_block" style="padding: 24px;">
-		<MkInput v-model="endpoint" :datalist="endpoints" @update:modelValue="onEndpointChange()" class="_inputNoTopMargin">
+		<MkInput v-model="endpoint" :datalist="endpoints" @update:modelValue="onEndpointChange()" class="">
 			<template #label>Endpoint</template>
 		</MkInput>
 		<MkTextarea v-model="body" code>
@@ -27,9 +27,9 @@
 import { defineComponent } from 'vue';
 import * as JSON5 from 'json5';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkSwitch from '@client/components/form/switch.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/channel-editor.vue b/src/client/pages/channel-editor.vue
index eeea0b70aa..67e27896ce 100644
--- a/src/client/pages/channel-editor.vue
+++ b/src/client/pages/channel-editor.vue
@@ -27,9 +27,9 @@
 
 <script lang="ts">
 import { computed, defineComponent } from 'vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import { selectFile } from '@client/scripts/select-file';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
diff --git a/src/client/pages/channels.vue b/src/client/pages/channels.vue
index 7e3302959b..fd1408c253 100644
--- a/src/client/pages/channels.vue
+++ b/src/client/pages/channels.vue
@@ -1,7 +1,7 @@
 <template>
 <div>
 	<div class="_section" style="padding: 0;" v-if="$i">
-		<MkTab class="_content" v-model:value="tab">
+		<MkTab class="_content" v-model="tab">
 			<option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._channel.featured }}</option>
 			<option value="following"><i class="fas fa-heart"></i> {{ $ts._channel.following }}</option>
 			<option value="owned"><i class="fas fa-edit"></i> {{ $ts._channel.owned }}</option>
diff --git a/src/client/pages/docs.vue b/src/client/pages/docs.vue
index be4d4255db..629dc2be53 100644
--- a/src/client/pages/docs.vue
+++ b/src/client/pages/docs.vue
@@ -2,7 +2,7 @@
 <div class="vtaihdtm">
 	<div class="body">
 		<div class="search">
-			<MkInput v-model="query" :debounce="true" type="search" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search">
+			<MkInput v-model="query" :debounce="true" type="search" class="" :placeholder="$ts.search">
 				<template #prefix><i class="fas fa-search"></i></template>
 			</MkInput>
 		</div>
@@ -57,7 +57,7 @@ import { defineComponent } from 'vue';
 import { url, lang } from '@client/config';
 import * as symbols from '@client/symbols';
 import MkFolder from '@client/components/ui/folder.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 
 export default defineComponent({
 	components: {
diff --git a/src/client/pages/emojis.category.vue b/src/client/pages/emojis.category.vue
index 7fee792854..d7737523d2 100644
--- a/src/client/pages/emojis.category.vue
+++ b/src/client/pages/emojis.category.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="driuhtrh">
 	<div class="query">
-		<MkInput v-model="q" class="_inputNoTopMargin _inputNoBottomMargin" :placeholder="$ts.search">
+		<MkInput v-model="q" class="" :placeholder="$ts.search">
 			<template #prefix><i class="fas fa-search"></i></template>
 		</MkInput>
 
@@ -31,8 +31,8 @@
 <script lang="ts">
 import { defineComponent, computed } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkFolder from '@client/components/ui/folder.vue';
 import MkTab from '@client/components/tab.vue';
 import * as os from '@client/os';
diff --git a/src/client/pages/explore.vue b/src/client/pages/explore.vue
index 7054940a1a..7e0e8ea27b 100644
--- a/src/client/pages/explore.vue
+++ b/src/client/pages/explore.vue
@@ -75,7 +75,7 @@
 import { computed, defineComponent } from 'vue';
 import XUserList from '@client/components/user-list.vue';
 import MkFolder from '@client/components/ui/folder.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import number from '@client/filters/number';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
diff --git a/src/client/pages/federation.vue b/src/client/pages/federation.vue
index 2afe70eea6..aac94e00af 100644
--- a/src/client/pages/federation.vue
+++ b/src/client/pages/federation.vue
@@ -1,11 +1,11 @@
 <template>
 <div class="taeiyria">
 	<div class="query">
-		<MkInput v-model="host" :debounce="true" class="_inputNoTopMargin">
+		<MkInput v-model="host" :debounce="true" class="">
 			<template #prefix><i class="fas fa-search"></i></template>
 			<template #label>{{ $ts.host }}</template>
 		</MkInput>
-		<div class="_inputSplit _inputNoBottomMargin">
+		<div class="_inputSplit">
 			<MkSelect v-model="state">
 				<template #label>{{ $ts.state }}</template>
 				<option value="all">{{ $ts.all }}</option>
@@ -96,8 +96,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkPagination from '@client/components/ui/pagination.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
diff --git a/src/client/pages/gallery/edit.vue b/src/client/pages/gallery/edit.vue
index cd6a0defdd..8e74b068ef 100644
--- a/src/client/pages/gallery/edit.vue
+++ b/src/client/pages/gallery/edit.vue
@@ -1,23 +1,23 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormInput v-model:value="title">
+		<FormInput v-model="title">
 			<span>{{ $ts.title }}</span>
 		</FormInput>
 
-		<FormTextarea v-model:value="description" :max="500">
+		<FormTextarea v-model="description" :max="500">
 			<span>{{ $ts.description }}</span>
 		</FormTextarea>
 
 		<FormGroup>
-			<div v-for="file in files" :key="file.id" class="_formItem _formPanel wqugxsfx" :style="{ backgroundImage: file ? `url(${ file.thumbnailUrl })` : null }">
+			<div v-for="file in files" :key="file.id" class="_debobigegoItem _debobigegoPanel wqugxsfx" :style="{ backgroundImage: file ? `url(${ file.thumbnailUrl })` : null }">
 				<div class="name">{{ file.name }}</div>
 				<button class="remove _button" @click="remove(file)" v-tooltip="$ts.remove"><i class="fas fa-times"></i></button>
 			</div>
 			<FormButton @click="selectFile" primary><i class="fas fa-plus"></i> {{ $ts.attachFile }}</FormButton>
 		</FormGroup>
 
-		<FormSwitch v-model:value="isSensitive">{{ $ts.markAsSensitive }}</FormSwitch>
+		<FormSwitch v-model="isSensitive">{{ $ts.markAsSensitive }}</FormSwitch>
 
 		<FormButton v-if="postId" @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
 		<FormButton v-else @click="save" primary><i class="fas fa-save"></i> {{ $ts.publish }}</FormButton>
@@ -29,14 +29,14 @@
 
 <script lang="ts">
 import { computed, defineComponent } from 'vue';
-import FormButton from '@client/components/form/button.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormTuple from '@client/components/form/tuple.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormTuple from '@client/components/debobigego/tuple.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import { selectFile } from '@client/scripts/select-file';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
diff --git a/src/client/pages/gallery/index.vue b/src/client/pages/gallery/index.vue
index 9e726e70f2..ffc599513e 100644
--- a/src/client/pages/gallery/index.vue
+++ b/src/client/pages/gallery/index.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="xprsixdl _root">
-	<MkTab v-model:value="tab" v-if="$i">
+	<MkTab v-model="tab" v-if="$i">
 		<option value="explore"><i class="fas fa-icons"></i> {{ $ts.gallery }}</option>
 		<option value="liked"><i class="fas fa-heart"></i> {{ $ts._gallery.liked }}</option>
 		<option value="my"><i class="fas fa-edit"></i> {{ $ts._gallery.my }}</option>
@@ -46,7 +46,7 @@
 import { computed, defineComponent } from 'vue';
 import XUserList from '@client/components/user-list.vue';
 import MkFolder from '@client/components/ui/folder.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import MkButton from '@client/components/ui/button.vue';
 import MkTab from '@client/components/tab.vue';
 import MkPagination from '@client/components/ui/pagination.vue';
diff --git a/src/client/pages/instance-info.vue b/src/client/pages/instance-info.vue
index 7d03c0847d..4fbf104f0c 100644
--- a/src/client/pages/instance-info.vue
+++ b/src/client/pages/instance-info.vue
@@ -3,8 +3,8 @@
 	<FormGroup v-if="instance">
 		<template #label>{{ instance.host }}</template>
 		<FormGroup>
-			<div class="_formItem">
-				<div class="_formPanel fnfelxur">
+			<div class="_debobigegoItem">
+				<div class="_debobigegoPanel fnfelxur">
 					<img :src="instance.iconUrl || instance.faviconUrl" alt="" class="icon"/>
 				</div>
 			</div>
@@ -60,9 +60,9 @@
 				<template #value>{{ instance.openRegistrations ? $ts.yes : $ts.no }}</template>
 			</FormKeyValueView>
 		</FormGroup>
-		<div class="_formItem">
-			<div class="_formLabel">{{ $ts.statistics }}</div>
-			<div class="_formPanel cmhjzshl">
+		<div class="_debobigegoItem">
+			<div class="_debobigegoLabel">{{ $ts.statistics }}</div>
+			<div class="_debobigegoPanel cmhjzshl">
 				<div class="selects">
 					<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
 						<option value="requests">{{ $ts._instanceCharts.requests }}</option>
@@ -136,15 +136,15 @@
 <script lang="ts">
 import { defineAsyncComponent, defineComponent } from 'vue';
 import Chart from 'chart.js';
-import FormObjectView from '@client/components/form/object-view.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import FormObjectView from '@client/components/debobigego/object-view.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
+import MkSelect from '@client/components/form/select.vue';
 import * as os from '@client/os';
 import number from '@client/filters/number';
 import bytes from '@client/filters/bytes';
diff --git a/src/client/pages/instance/abuses.vue b/src/client/pages/instance/abuses.vue
index ac20ebabe5..a66847938d 100644
--- a/src/client/pages/instance/abuses.vue
+++ b/src/client/pages/instance/abuses.vue
@@ -24,10 +24,10 @@
 			</div>
 			<!-- TODO
 			<div class="inputs" style="display: flex; padding-top: 1.2em;">
-				<MkInput v-model:value="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.reports.reload()">
+				<MkInput v-model="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.reports.reload()">
 					<span>{{ $ts.username }}</span>
 				</MkInput>
-				<MkInput v-model:value="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.reports.reload()" :disabled="pagination.params().origin === 'local'">
+				<MkInput v-model="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:modelValue="$refs.reports.reload()" :disabled="pagination.params().origin === 'local'">
 					<span>{{ $ts.host }}</span>
 				</MkInput>
 			</div>
@@ -65,8 +65,8 @@
 import { defineComponent } from 'vue';
 import { parseAcct } from '@/misc/acct';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkPagination from '@client/components/ui/pagination.vue';
 import { acct } from '@client/filters/user';
 import * as os from '@client/os';
diff --git a/src/client/pages/instance/ads.vue b/src/client/pages/instance/ads.vue
index 50c8c29cbf..8742d0bda1 100644
--- a/src/client/pages/instance/ads.vue
+++ b/src/client/pages/instance/ads.vue
@@ -44,9 +44,9 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkRadio from '@client/components/ui/radio.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkRadio from '@client/components/form/radio.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/instance/announcements.vue b/src/client/pages/instance/announcements.vue
index d48e3737ad..35d676cf28 100644
--- a/src/client/pages/instance/announcements.vue
+++ b/src/client/pages/instance/announcements.vue
@@ -25,8 +25,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/instance/bot-protection.vue b/src/client/pages/instance/bot-protection.vue
index 449b8a233d..731f114cc2 100644
--- a/src/client/pages/instance/bot-protection.vue
+++ b/src/client/pages/instance/bot-protection.vue
@@ -9,43 +9,43 @@
 		</FormRadios>
 
 		<template v-if="provider === 'hcaptcha'">
-			<div class="_formItem _formNoConcat" v-sticky-container>
-				<div class="_formLabel">hCaptcha</div>
+			<div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
+				<div class="_debobigegoLabel">hCaptcha</div>
 				<div class="main">
-					<FormInput v-model:value="hcaptchaSiteKey">
+					<FormInput v-model="hcaptchaSiteKey">
 						<template #prefix><i class="fas fa-key"></i></template>
 						<span>{{ $ts.hcaptchaSiteKey }}</span>
 					</FormInput>
-					<FormInput v-model:value="hcaptchaSecretKey">
+					<FormInput v-model="hcaptchaSecretKey">
 						<template #prefix><i class="fas fa-key"></i></template>
 						<span>{{ $ts.hcaptchaSecretKey }}</span>
 					</FormInput>
 				</div>
 			</div>
-			<div class="_formItem _formNoConcat" v-sticky-container>
-				<div class="_formLabel">{{ $ts.preview }}</div>
-				<div class="_formPanel" style="padding: var(--formContentHMargin);">
+			<div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
+				<div class="_debobigegoLabel">{{ $ts.preview }}</div>
+				<div class="_debobigegoPanel" style="padding: var(--debobigegoContentHMargin);">
 					<MkCaptcha provider="hcaptcha" :sitekey="hcaptchaSiteKey || '10000000-ffff-ffff-ffff-000000000001'"/>
 				</div>
 			</div>
 		</template>
 		<template v-else-if="provider === 'recaptcha'">
-			<div class="_formItem _formNoConcat" v-sticky-container>
-				<div class="_formLabel">reCAPTCHA</div>
+			<div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
+				<div class="_debobigegoLabel">reCAPTCHA</div>
 				<div class="main">
-					<FormInput v-model:value="recaptchaSiteKey">
+					<FormInput v-model="recaptchaSiteKey">
 						<template #prefix><i class="fas fa-key"></i></template>
 						<span>{{ $ts.recaptchaSiteKey }}</span>
 					</FormInput>
-					<FormInput v-model:value="recaptchaSecretKey">
+					<FormInput v-model="recaptchaSecretKey">
 						<template #prefix><i class="fas fa-key"></i></template>
 						<span>{{ $ts.recaptchaSecretKey }}</span>
 					</FormInput>
 				</div>
 			</div>
-			<div v-if="recaptchaSiteKey" class="_formItem _formNoConcat" v-sticky-container>
-				<div class="_formLabel">{{ $ts.preview }}</div>
-				<div class="_formPanel" style="padding: var(--formContentHMargin);">
+			<div v-if="recaptchaSiteKey" class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
+				<div class="_debobigegoLabel">{{ $ts.preview }}</div>
+				<div class="_debobigegoPanel" style="padding: var(--debobigegoContentHMargin);">
 					<MkCaptcha provider="recaptcha" :sitekey="recaptchaSiteKey"/>
 				</div>
 			</div>
@@ -58,13 +58,13 @@
 
 <script lang="ts">
 import { defineAsyncComponent, defineComponent } from 'vue';
-import FormRadios from '@client/components/form/radios.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormRadios from '@client/components/debobigego/radios.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/database.vue b/src/client/pages/instance/database.vue
index a41d61ce2b..a8a1e9a54a 100644
--- a/src/client/pages/instance/database.vue
+++ b/src/client/pages/instance/database.vue
@@ -18,11 +18,11 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSuspense from '@client/components/form/suspense.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import bytes from '@client/filters/bytes';
diff --git a/src/client/pages/instance/email-settings.vue b/src/client/pages/instance/email-settings.vue
index 9965a1420f..251354a43a 100644
--- a/src/client/pages/instance/email-settings.vue
+++ b/src/client/pages/instance/email-settings.vue
@@ -1,30 +1,30 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormSwitch v-model:value="enableEmail">{{ $ts.enableEmail }}<template #desc>{{ $ts.emailConfigInfo }}</template></FormSwitch>
+		<FormSwitch v-model="enableEmail">{{ $ts.enableEmail }}<template #desc>{{ $ts.emailConfigInfo }}</template></FormSwitch>
 
 		<template v-if="enableEmail">
-			<FormInput v-model:value="email" type="email">
+			<FormInput v-model="email" type="email">
 				<span>{{ $ts.emailAddress }}</span>
 			</FormInput>
 
-			<div class="_formItem _formNoConcat" v-sticky-container>
-				<div class="_formLabel">{{ $ts.smtpConfig }}</div>
+			<div class="_debobigegoItem _debobigegoNoConcat" v-sticky-container>
+				<div class="_debobigegoLabel">{{ $ts.smtpConfig }}</div>
 				<div class="main">
-					<FormInput v-model:value="smtpHost">
+					<FormInput v-model="smtpHost">
 						<span>{{ $ts.smtpHost }}</span>
 					</FormInput>
-					<FormInput v-model:value="smtpPort" type="number">
+					<FormInput v-model="smtpPort" type="number">
 						<span>{{ $ts.smtpPort }}</span>
 					</FormInput>
-					<FormInput v-model:value="smtpUser">
+					<FormInput v-model="smtpUser">
 						<span>{{ $ts.smtpUser }}</span>
 					</FormInput>
-					<FormInput v-model:value="smtpPass" type="password">
+					<FormInput v-model="smtpPass" type="password">
 						<span>{{ $ts.smtpPass }}</span>
 					</FormInput>
 					<FormInfo>{{ $ts.emptyToDisableSmtpAuth }}</FormInfo>
-					<FormSwitch v-model:value="smtpSecure">{{ $ts.smtpSecure }}<template #desc>{{ $ts.smtpSecureInfo }}</template></FormSwitch>
+					<FormSwitch v-model="smtpSecure">{{ $ts.smtpSecure }}<template #desc>{{ $ts.smtpSecureInfo }}</template></FormSwitch>
 				</div>
 			</div>
 
@@ -38,13 +38,13 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/emoji-edit-dialog.vue b/src/client/pages/instance/emoji-edit-dialog.vue
index 7e9bdc80dd..bd8b2061ae 100644
--- a/src/client/pages/instance/emoji-edit-dialog.vue
+++ b/src/client/pages/instance/emoji-edit-dialog.vue
@@ -31,7 +31,7 @@
 import { defineComponent } from 'vue';
 import XModalWindow from '@client/components/ui/modal-window.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 import { unique } from '../../../prelude/array';
 
diff --git a/src/client/pages/instance/emojis.vue b/src/client/pages/instance/emojis.vue
index 7badc9da02..6118d869e9 100644
--- a/src/client/pages/instance/emojis.vue
+++ b/src/client/pages/instance/emojis.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="ogwlenmc">
-	<MkTab v-model:value="tab">
+	<MkTab v-model="tab">
 		<option value="local">{{ $ts.local }}</option>
 		<option value="remote">{{ $ts.remote }}</option>
 	</MkTab>
@@ -56,7 +56,7 @@
 <script lang="ts">
 import { computed, defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import MkPagination from '@client/components/ui/pagination.vue';
 import MkTab from '@client/components/tab.vue';
 import { selectFile } from '@client/scripts/select-file';
diff --git a/src/client/pages/instance/file-dialog.vue b/src/client/pages/instance/file-dialog.vue
index 8a03a11de7..02d83e5022 100644
--- a/src/client/pages/instance/file-dialog.vue
+++ b/src/client/pages/instance/file-dialog.vue
@@ -37,7 +37,7 @@
 <script lang="ts">
 import { computed, defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
+import MkSwitch from '@client/components/form/switch.vue';
 import XModalWindow from '@client/components/ui/modal-window.vue';
 import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue';
 import Progress from '@client/scripts/loading';
diff --git a/src/client/pages/instance/files-settings.vue b/src/client/pages/instance/files-settings.vue
index 614c7d4dbb..8bf4613a76 100644
--- a/src/client/pages/instance/files-settings.vue
+++ b/src/client/pages/instance/files-settings.vue
@@ -1,23 +1,23 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormSwitch v-model:value="cacheRemoteFiles">
+		<FormSwitch v-model="cacheRemoteFiles">
 			{{ $ts.cacheRemoteFiles }}
 			<template #desc>{{ $ts.cacheRemoteFilesDescription }}</template>
 		</FormSwitch>
 
-		<FormSwitch v-model:value="proxyRemoteFiles">
+		<FormSwitch v-model="proxyRemoteFiles">
 			{{ $ts.proxyRemoteFiles }}
 			<template #desc>{{ $ts.proxyRemoteFilesDescription }}</template>
 		</FormSwitch>
 
-		<FormInput v-model:value="localDriveCapacityMb" type="number">
+		<FormInput v-model="localDriveCapacityMb" type="number">
 			<span>{{ $ts.driveCapacityPerLocalAccount }}</span>
 			<template #suffix>MB</template>
 			<template #desc>{{ $ts.inMb }}</template>
 		</FormInput>
 
-		<FormInput v-model:value="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">
+		<FormInput v-model="remoteDriveCapacityMb" type="number" :disabled="!cacheRemoteFiles">
 			<span>{{ $ts.driveCapacityPerRemoteAccount }}</span>
 			<template #suffix>MB</template>
 			<template #desc>{{ $ts.inMb }}</template>
@@ -30,12 +30,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/files.vue b/src/client/pages/instance/files.vue
index b7f472b7c8..df2431ad02 100644
--- a/src/client/pages/instance/files.vue
+++ b/src/client/pages/instance/files.vue
@@ -63,8 +63,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkPagination from '@client/components/ui/pagination.vue';
 import MkDriveFileThumbnail from '@client/components/drive-file-thumbnail.vue';
 import bytes from '@client/filters/bytes';
diff --git a/src/client/pages/instance/index.vue b/src/client/pages/instance/index.vue
index 612bfa762a..657a654e51 100644
--- a/src/client/pages/instance/index.vue
+++ b/src/client/pages/instance/index.vue
@@ -3,8 +3,8 @@
 	<div class="nav" v-if="!narrow || page == null">
 		<FormBase>
 			<FormGroup>
-				<div class="_formItem">
-					<div class="_formPanel lxpfedzu">
+				<div class="_debobigegoItem">
+					<div class="_debobigegoPanel lxpfedzu">
 						<img :src="$instance.iconUrl || '/favicon.ico'" alt="" class="icon"/>
 					</div>
 				</div>
@@ -56,10 +56,10 @@
 <script lang="ts">
 import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue';
 import { i18n } from '@client/i18n';
-import FormLink from '@client/components/form/link.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import { scroll } from '@client/scripts/scroll';
 import * as symbols from '@client/symbols';
 import * as os from '@client/os';
diff --git a/src/client/pages/instance/instance-block.vue b/src/client/pages/instance/instance-block.vue
index ed5740f339..a00970d85b 100644
--- a/src/client/pages/instance/instance-block.vue
+++ b/src/client/pages/instance/instance-block.vue
@@ -1,7 +1,7 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormTextarea v-model:value="blockedHosts">
+		<FormTextarea v-model="blockedHosts">
 			<span>{{ $ts.blockedInstances }}</span>
 			<template #desc>{{ $ts.blockedInstancesDescription }}</template>
 		</FormTextarea>
@@ -13,14 +13,14 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/instance.vue b/src/client/pages/instance/instance.vue
index c39f0d1ecb..6117f090de 100644
--- a/src/client/pages/instance/instance.vue
+++ b/src/client/pages/instance/instance.vue
@@ -127,9 +127,9 @@ import { defineComponent, markRaw } from 'vue';
 import Chart from 'chart.js';
 import XModalWindow from '@client/components/ui/modal-window.vue';
 import MkUsersDialog from '@client/components/users-dialog.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
+import MkSwitch from '@client/components/form/switch.vue';
 import MkInfo from '@client/components/ui/info.vue';
 import bytes from '@client/filters/bytes';
 import number from '@client/filters/number';
diff --git a/src/client/pages/instance/integrations-discord.vue b/src/client/pages/instance/integrations-discord.vue
index c7508918f8..c33b24f17f 100644
--- a/src/client/pages/instance/integrations-discord.vue
+++ b/src/client/pages/instance/integrations-discord.vue
@@ -1,19 +1,19 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormSwitch v-model:value="enableDiscordIntegration">
+		<FormSwitch v-model="enableDiscordIntegration">
 			{{ $ts.enable }}
 		</FormSwitch>
 
 		<template v-if="enableDiscordIntegration">
 			<FormInfo>Callback URL: {{ `${url}/api/dc/cb` }}</FormInfo>
 		
-			<FormInput v-model:value="discordClientId">
+			<FormInput v-model="discordClientId">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Client ID
 			</FormInput>
 
-			<FormInput v-model:value="discordClientSecret">
+			<FormInput v-model="discordClientSecret">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Client Secret
 			</FormInput>
@@ -26,12 +26,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/integrations-github.vue b/src/client/pages/instance/integrations-github.vue
index 16586b15b4..cdf85868ff 100644
--- a/src/client/pages/instance/integrations-github.vue
+++ b/src/client/pages/instance/integrations-github.vue
@@ -1,19 +1,19 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormSwitch v-model:value="enableGithubIntegration">
+		<FormSwitch v-model="enableGithubIntegration">
 			{{ $ts.enable }}
 		</FormSwitch>
 
 		<template v-if="enableGithubIntegration">
 			<FormInfo>Callback URL: {{ `${url}/api/gh/cb` }}</FormInfo>
 		
-			<FormInput v-model:value="githubClientId">
+			<FormInput v-model="githubClientId">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Client ID
 			</FormInput>
 
-			<FormInput v-model:value="githubClientSecret">
+			<FormInput v-model="githubClientSecret">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Client Secret
 			</FormInput>
@@ -26,12 +26,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/integrations-twitter.vue b/src/client/pages/instance/integrations-twitter.vue
index b08b7f40a5..ed7d097d0a 100644
--- a/src/client/pages/instance/integrations-twitter.vue
+++ b/src/client/pages/instance/integrations-twitter.vue
@@ -1,19 +1,19 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormSwitch v-model:value="enableTwitterIntegration">
+		<FormSwitch v-model="enableTwitterIntegration">
 			{{ $ts.enable }}
 		</FormSwitch>
 
 		<template v-if="enableTwitterIntegration">
 			<FormInfo>Callback URL: {{ `${url}/api/tw/cb` }}</FormInfo>
 		
-			<FormInput v-model:value="twitterConsumerKey">
+			<FormInput v-model="twitterConsumerKey">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Consumer Key
 			</FormInput>
 
-			<FormInput v-model:value="twitterConsumerSecret">
+			<FormInput v-model="twitterConsumerSecret">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Consumer Secret
 			</FormInput>
@@ -26,12 +26,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/integrations.vue b/src/client/pages/instance/integrations.vue
index 7debedc367..bfd9e2f349 100644
--- a/src/client/pages/instance/integrations.vue
+++ b/src/client/pages/instance/integrations.vue
@@ -19,14 +19,14 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormLink from '@client/components/form/link.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/logs.vue b/src/client/pages/instance/logs.vue
index 4eee816f96..74aea0fc45 100644
--- a/src/client/pages/instance/logs.vue
+++ b/src/client/pages/instance/logs.vue
@@ -31,9 +31,9 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSelect from '@client/components/ui/select.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSelect from '@client/components/form/select.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/instance/metrics.vue b/src/client/pages/instance/metrics.vue
index 283b5939f0..1606063aee 100644
--- a/src/client/pages/instance/metrics.vue
+++ b/src/client/pages/instance/metrics.vue
@@ -1,7 +1,7 @@
 <template>
-<div class="_formItem">
-	<div class="_formLabel"><i class="fas fa-microchip"></i> {{ $ts.cpuAndMemory }}</div>
-	<div class="_formPanel xhexznfu">
+<div class="_debobigegoItem">
+	<div class="_debobigegoLabel"><i class="fas fa-microchip"></i> {{ $ts.cpuAndMemory }}</div>
+	<div class="_debobigegoPanel xhexznfu">
 		<div>
 			<canvas :ref="cpumem"></canvas>
 		</div>
@@ -16,9 +16,9 @@
 		</div>
 	</div>
 </div>
-<div class="_formItem">
-	<div class="_formLabel"><i class="fas fa-hdd"></i> {{ $ts.disk }}</div>
-	<div class="_formPanel xhexznfu">
+<div class="_debobigegoItem">
+	<div class="_debobigegoLabel"><i class="fas fa-hdd"></i> {{ $ts.disk }}</div>
+	<div class="_debobigegoPanel xhexznfu">
 		<div>
 			<canvas :ref="disk"></canvas>
 		</div>
@@ -33,9 +33,9 @@
 		</div>
 	</div>
 </div>
-<div class="_formItem">
-	<div class="_formLabel"><i class="fas fa-exchange-alt"></i> {{ $ts.network }}</div>
-	<div class="_formPanel xhexznfu">
+<div class="_debobigegoItem">
+	<div class="_debobigegoLabel"><i class="fas fa-exchange-alt"></i> {{ $ts.network }}</div>
+	<div class="_debobigegoPanel xhexznfu">
 		<div>
 			<canvas :ref="net"></canvas>
 		</div>
@@ -54,8 +54,8 @@
 import { defineComponent, markRaw } from 'vue';
 import Chart from 'chart.js';
 import MkButton from '@client/components/ui/button.vue';
-import MkSelect from '@client/components/ui/select.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkSelect from '@client/components/form/select.vue';
+import MkInput from '@client/components/form/input.vue';
 import MkContainer from '@client/components/ui/container.vue';
 import MkFolder from '@client/components/ui/folder.vue';
 import MkwFederation from '../../widgets/federation.vue';
diff --git a/src/client/pages/instance/object-storage.vue b/src/client/pages/instance/object-storage.vue
index 814aeb6e48..ba6a249685 100644
--- a/src/client/pages/instance/object-storage.vue
+++ b/src/client/pages/instance/object-storage.vue
@@ -1,59 +1,59 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormSwitch v-model:value="useObjectStorage">{{ $ts.useObjectStorage }}</FormSwitch>
+		<FormSwitch v-model="useObjectStorage">{{ $ts.useObjectStorage }}</FormSwitch>
 
 		<template v-if="useObjectStorage">
-			<FormInput v-model:value="objectStorageBaseUrl">
+			<FormInput v-model="objectStorageBaseUrl">
 				<span>{{ $ts.objectStorageBaseUrl }}</span>
 				<template #desc>{{ $ts.objectStorageBaseUrlDesc }}</template>
 			</FormInput>
 
-			<FormInput v-model:value="objectStorageBucket">
+			<FormInput v-model="objectStorageBucket">
 				<span>{{ $ts.objectStorageBucket }}</span>
 				<template #desc>{{ $ts.objectStorageBucketDesc }}</template>
 			</FormInput>
 
-			<FormInput v-model:value="objectStoragePrefix">
+			<FormInput v-model="objectStoragePrefix">
 				<span>{{ $ts.objectStoragePrefix }}</span>
 				<template #desc>{{ $ts.objectStoragePrefixDesc }}</template>
 			</FormInput>
 
-			<FormInput v-model:value="objectStorageEndpoint">
+			<FormInput v-model="objectStorageEndpoint">
 				<span>{{ $ts.objectStorageEndpoint }}</span>
 				<template #desc>{{ $ts.objectStorageEndpointDesc }}</template>
 			</FormInput>
 
-			<FormInput v-model:value="objectStorageRegion">
+			<FormInput v-model="objectStorageRegion">
 				<span>{{ $ts.objectStorageRegion }}</span>
 				<template #desc>{{ $ts.objectStorageRegionDesc }}</template>
 			</FormInput>
 
-			<FormInput v-model:value="objectStorageAccessKey">
+			<FormInput v-model="objectStorageAccessKey">
 				<template #prefix><i class="fas fa-key"></i></template>
 				<span>Access key</span>
 			</FormInput>
 
-			<FormInput v-model:value="objectStorageSecretKey">
+			<FormInput v-model="objectStorageSecretKey">
 				<template #prefix><i class="fas fa-key"></i></template>
 				<span>Secret key</span>
 			</FormInput>
 
-			<FormSwitch v-model:value="objectStorageUseSSL">
+			<FormSwitch v-model="objectStorageUseSSL">
 				{{ $ts.objectStorageUseSSL }}
 				<template #desc>{{ $ts.objectStorageUseSSLDesc }}</template>
 			</FormSwitch>
 
-			<FormSwitch v-model:value="objectStorageUseProxy">
+			<FormSwitch v-model="objectStorageUseProxy">
 				{{ $ts.objectStorageUseProxy }}
 				<template #desc>{{ $ts.objectStorageUseProxyDesc }}</template>
 			</FormSwitch>
 
-			<FormSwitch v-model:value="objectStorageSetPublicRead">
+			<FormSwitch v-model="objectStorageSetPublicRead">
 				{{ $ts.objectStorageSetPublicRead }}
 			</FormSwitch>
 
-			<FormSwitch v-model:value="objectStorageS3ForcePathStyle">
+			<FormSwitch v-model="objectStorageS3ForcePathStyle">
 				s3ForcePathStyle
 			</FormSwitch>
 		</template>
@@ -65,12 +65,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/other-settings.vue b/src/client/pages/instance/other-settings.vue
index 4fa80b2b2c..b9f9ce30f7 100644
--- a/src/client/pages/instance/other-settings.vue
+++ b/src/client/pages/instance/other-settings.vue
@@ -2,17 +2,17 @@
 <FormBase>
 	<FormSuspense :p="init">
 		<FormGroup>
-			<FormInput v-model:value="summalyProxy">
+			<FormInput v-model="summalyProxy">
 				<template #prefix><i class="fas fa-link"></i></template>
 				Summaly Proxy URL
 			</FormInput>
 		</FormGroup>
 		<FormGroup>
-			<FormInput v-model:value="deeplAuthKey">
+			<FormInput v-model="deeplAuthKey">
 				<template #prefix><i class="fas fa-key"></i></template>
 				DeepL Auth Key
 			</FormInput>
-			<FormSwitch v-model:value="deeplIsPro">
+			<FormSwitch v-model="deeplIsPro">
 				Pro account
 			</FormSwitch>
 		</FormGroup>
@@ -23,12 +23,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/overview.vue b/src/client/pages/instance/overview.vue
index 0d7a5d1501..28dcfc03bf 100644
--- a/src/client/pages/instance/overview.vue
+++ b/src/client/pages/instance/overview.vue
@@ -17,8 +17,8 @@
 			</FormGroup>
 		</FormSuspense>
 	
-		<div class="_formItem">
-			<div class="_formPanel">
+		<div class="_debobigegoItem">
+			<div class="_debobigegoPanel">
 				<MkInstanceStats :chart-limit="300" :detailed="true"/>
 			</div>
 		</div>
@@ -47,18 +47,18 @@
 
 <script lang="ts">
 import { computed, defineComponent, markRaw } from 'vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import MkInstanceStats from '@client/components/instance-stats.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkSelect from '@client/components/ui/select.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkSelect from '@client/components/form/select.vue';
+import MkInput from '@client/components/form/input.vue';
 import MkContainer from '@client/components/ui/container.vue';
 import MkFolder from '@client/components/ui/folder.vue';
 import { version, url } from '@client/config';
diff --git a/src/client/pages/instance/proxy-account.vue b/src/client/pages/instance/proxy-account.vue
index 3e2df8dcb4..a80ecccb05 100644
--- a/src/client/pages/instance/proxy-account.vue
+++ b/src/client/pages/instance/proxy-account.vue
@@ -16,14 +16,14 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/queue.chart.vue b/src/client/pages/instance/queue.chart.vue
index 53d790598a..887fe9a574 100644
--- a/src/client/pages/instance/queue.chart.vue
+++ b/src/client/pages/instance/queue.chart.vue
@@ -1,7 +1,7 @@
 <template>
-<div class="_formItem">
-	<div class="_formLabel"><slot name="title"></slot></div>
-	<div class="_formPanel pumxzjhg">
+<div class="_debobigegoItem">
+	<div class="_debobigegoLabel"><slot name="title"></slot></div>
+	<div class="_debobigegoPanel pumxzjhg">
 		<div class="_table status">
 			<div class="_row">
 				<div class="_cell"><div class="_label">Process</div>{{ number(activeSincePrevTick) }}</div>
diff --git a/src/client/pages/instance/queue.vue b/src/client/pages/instance/queue.vue
index e8ec0bc97d..031bda2bed 100644
--- a/src/client/pages/instance/queue.vue
+++ b/src/client/pages/instance/queue.vue
@@ -14,8 +14,8 @@
 import { defineComponent, markRaw } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
 import XQueue from './queue.chart.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/instance/relays.vue b/src/client/pages/instance/relays.vue
index a3e4e7d1da..cb9b27a625 100644
--- a/src/client/pages/instance/relays.vue
+++ b/src/client/pages/instance/relays.vue
@@ -2,8 +2,8 @@
 <FormBase class="relaycxt">
 	<FormButton @click="addRelay" primary><i class="fas fa-plus"></i> {{ $ts.addRelay }}</FormButton>
 
-	<div class="_formItem" v-for="relay in relays" :key="relay.inbox">
-		<div class="_formPanel" style="padding: 16px;">
+	<div class="_debobigegoItem" v-for="relay in relays" :key="relay.inbox">
+		<div class="_debobigegoPanel" style="padding: 16px;">
 			<div>{{ relay.inbox }}</div>
 			<div>{{ $t(`_relayStatus.${relay.status}`) }}</div>
 			<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="fas fa-trash-alt"></i> {{ $ts.remove }}</MkButton>
@@ -15,9 +15,9 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormButton from '@client/components/form/button.vue';
+import MkInput from '@client/components/form/input.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/instance/security.vue b/src/client/pages/instance/security.vue
index e3397a113b..53f923643a 100644
--- a/src/client/pages/instance/security.vue
+++ b/src/client/pages/instance/security.vue
@@ -8,7 +8,7 @@
 			<template #suffix v-else>{{ $ts.none }} ({{ $ts.notRecommended }})</template>
 		</FormLink>
 
-		<FormSwitch v-model:value="enableRegistration">{{ $ts.enableRegistration }}</FormSwitch>
+		<FormSwitch v-model="enableRegistration">{{ $ts.enableRegistration }}</FormSwitch>
 
 		<FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
 	</FormSuspense>
@@ -17,13 +17,13 @@
 
 <script lang="ts">
 import { defineAsyncComponent, defineComponent } from 'vue';
-import FormLink from '@client/components/form/link.vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/service-worker.vue b/src/client/pages/instance/service-worker.vue
index a52932bb75..9fa10def07 100644
--- a/src/client/pages/instance/service-worker.vue
+++ b/src/client/pages/instance/service-worker.vue
@@ -1,18 +1,18 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormSwitch v-model:value="enableServiceWorker">
+		<FormSwitch v-model="enableServiceWorker">
 			{{ $ts.enableServiceworker }}
 			<template #desc>{{ $ts.serviceworkerInfo }}</template>
 		</FormSwitch>
 
 		<template v-if="enableServiceWorker">
-			<FormInput v-model:value="swPublicKey">
+			<FormInput v-model="swPublicKey">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Public key
 			</FormInput>
 
-			<FormInput v-model:value="swPrivateKey">
+			<FormInput v-model="swPrivateKey">
 				<template #prefix><i class="fas fa-key"></i></template>
 				Private key
 			</FormInput>
@@ -25,12 +25,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/settings.vue b/src/client/pages/instance/settings.vue
index b68d784897..2ce9361d08 100644
--- a/src/client/pages/instance/settings.vue
+++ b/src/client/pages/instance/settings.vue
@@ -1,50 +1,50 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<FormInput v-model:value="name">
+		<FormInput v-model="name">
 			<span>{{ $ts.instanceName }}</span>
 		</FormInput>
 
-		<FormTextarea v-model:value="description">
+		<FormTextarea v-model="description">
 			<span>{{ $ts.instanceDescription }}</span>
 		</FormTextarea>
 
-		<FormInput v-model:value="iconUrl">
+		<FormInput v-model="iconUrl">
 			<template #prefix><i class="fas fa-link"></i></template>
 			<span>{{ $ts.iconUrl }}</span>
 		</FormInput>
 
-		<FormInput v-model:value="bannerUrl">
+		<FormInput v-model="bannerUrl">
 			<template #prefix><i class="fas fa-link"></i></template>
 			<span>{{ $ts.bannerUrl }}</span>
 		</FormInput>
 
-		<FormInput v-model:value="backgroundImageUrl">
+		<FormInput v-model="backgroundImageUrl">
 			<template #prefix><i class="fas fa-link"></i></template>
 			<span>{{ $ts.backgroundImageUrl }}</span>
 		</FormInput>
 
-		<FormInput v-model:value="tosUrl">
+		<FormInput v-model="tosUrl">
 			<template #prefix><i class="fas fa-link"></i></template>
 			<span>{{ $ts.tosUrl }}</span>
 		</FormInput>
 
-		<FormInput v-model:value="maintainerName">
+		<FormInput v-model="maintainerName">
 			<span>{{ $ts.maintainerName }}</span>
 		</FormInput>
 
-		<FormInput v-model:value="maintainerEmail" type="email">
+		<FormInput v-model="maintainerEmail" type="email">
 			<template #prefix><i class="fas fa-envelope"></i></template>
 			<span>{{ $ts.maintainerEmail }}</span>
 		</FormInput>
 
-		<FormInput v-model:value="maxNoteTextLength" type="number">
+		<FormInput v-model="maxNoteTextLength" type="number">
 			<template #prefix><i class="fas fa-pencil-alt"></i></template>
 			<span>{{ $ts.maxNoteTextLength }}</span>
 		</FormInput>
 
-		<FormSwitch v-model:value="enableLocalTimeline">{{ $ts.enableLocalTimeline }}</FormSwitch>
-		<FormSwitch v-model:value="enableGlobalTimeline">{{ $ts.enableGlobalTimeline }}</FormSwitch>
+		<FormSwitch v-model="enableLocalTimeline">{{ $ts.enableLocalTimeline }}</FormSwitch>
+		<FormSwitch v-model="enableGlobalTimeline">{{ $ts.enableGlobalTimeline }}</FormSwitch>
 		<FormInfo>{{ $ts.disablingTimelinesInfo }}</FormInfo>
 
 		<FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
@@ -54,14 +54,14 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { fetchInstance } from '@client/instance';
diff --git a/src/client/pages/instance/users.vue b/src/client/pages/instance/users.vue
index 8db62683ba..7671387f01 100644
--- a/src/client/pages/instance/users.vue
+++ b/src/client/pages/instance/users.vue
@@ -67,8 +67,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSelect from '@client/components/form/select.vue';
 import MkPagination from '@client/components/ui/pagination.vue';
 import { acct } from '@client/filters/user';
 import * as os from '@client/os';
diff --git a/src/client/pages/mfm-cheat-sheet.vue b/src/client/pages/mfm-cheat-sheet.vue
index 314b5e2a5f..5ff4317627 100644
--- a/src/client/pages/mfm-cheat-sheet.vue
+++ b/src/client/pages/mfm-cheat-sheet.vue
@@ -286,7 +286,7 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
 import * as symbols from '@client/symbols';
 
 export default defineComponent({
diff --git a/src/client/pages/my-antennas/editor.vue b/src/client/pages/my-antennas/editor.vue
index 882d48e643..972a4e0243 100644
--- a/src/client/pages/my-antennas/editor.vue
+++ b/src/client/pages/my-antennas/editor.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="shaynizk">
 	<div class="form">
-		<MkInput v-model="name" class="_inputNoTopMargin">
+		<MkInput v-model="name" class="">
 			<template #label>{{ $ts.name }}</template>
 		</MkInput>
 		<MkSelect v-model="src">
@@ -47,10 +47,10 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkSelect from '@client/components/ui/select.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkSelect from '@client/components/form/select.vue';
+import MkSwitch from '@client/components/form/switch.vue';
 import { getAcct } from '@/misc/acct';
 import * as os from '@client/os';
 
diff --git a/src/client/pages/my-groups/index.vue b/src/client/pages/my-groups/index.vue
index 9f153ff9cc..34f82f8a71 100644
--- a/src/client/pages/my-groups/index.vue
+++ b/src/client/pages/my-groups/index.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="">
 	<div class="_section" style="padding: 0;">
-		<MkTab v-model:value="tab">
+		<MkTab v-model="tab">
 			<option value="owned">{{ $ts.ownedGroups }}</option>
 			<option value="joined">{{ $ts.joinedGroups }}</option>
 			<option value="invites"><i class="fas fa-envelope-open-text"></i> {{ $ts.invites }}</option>
diff --git a/src/client/pages/page-editor/els/page-editor.el.button.vue b/src/client/pages/page-editor/els/page-editor.el.button.vue
index 3a43817cf6..85e9d7e711 100644
--- a/src/client/pages/page-editor/els/page-editor.el.button.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.button.vue
@@ -40,9 +40,9 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkSelect from '@client/components/ui/select.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
+import MkSelect from '@client/components/form/select.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSwitch from '@client/components/form/switch.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.canvas.vue b/src/client/pages/page-editor/els/page-editor.el.canvas.vue
index d8d5b990ca..c40d69a7c1 100644
--- a/src/client/pages/page-editor/els/page-editor.el.canvas.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.canvas.vue
@@ -22,7 +22,7 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.counter.vue b/src/client/pages/page-editor/els/page-editor.el.counter.vue
index 973de50fc2..de7994e3ba 100644
--- a/src/client/pages/page-editor/els/page-editor.el.counter.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.counter.vue
@@ -20,7 +20,7 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.if.vue b/src/client/pages/page-editor/els/page-editor.el.if.vue
index 6eb0c7709f..52f4dac22e 100644
--- a/src/client/pages/page-editor/els/page-editor.el.if.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.if.vue
@@ -19,7 +19,7 @@
 			</optgroup>
 		</MkSelect>
 
-		<XBlocks class="children" v-model:value="value.children" :hpml="hpml"/>
+		<XBlocks class="children" v-model="value.children" :hpml="hpml"/>
 	</section>
 </XContainer>
 </template>
@@ -28,7 +28,7 @@
 import { defineComponent, defineAsyncComponent } from 'vue';
 import { v4 as uuid } from 'uuid';
 import XContainer from '../page-editor.container.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkSelect from '@client/components/form/select.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.note.vue b/src/client/pages/page-editor/els/page-editor.el.note.vue
index 5766564c1a..9feec395b7 100644
--- a/src/client/pages/page-editor/els/page-editor.el.note.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.note.vue
@@ -18,8 +18,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSwitch from '@client/components/form/switch.vue';
 import XNote from '@client/components/note.vue';
 import XNoteDetailed from '@client/components/note-detailed.vue';
 import * as os from '@client/os';
diff --git a/src/client/pages/page-editor/els/page-editor.el.number-input.vue b/src/client/pages/page-editor/els/page-editor.el.number-input.vue
index 892e7e1caa..57b1397824 100644
--- a/src/client/pages/page-editor/els/page-editor.el.number-input.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.number-input.vue
@@ -20,7 +20,7 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.post.vue b/src/client/pages/page-editor/els/page-editor.el.post.vue
index 4215b159d3..e21ccfd345 100644
--- a/src/client/pages/page-editor/els/page-editor.el.post.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.post.vue
@@ -13,9 +13,9 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSwitch from '@client/components/form/switch.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.radio-button.vue b/src/client/pages/page-editor/els/page-editor.el.radio-button.vue
index 88be96f35d..62fb231f79 100644
--- a/src/client/pages/page-editor/els/page-editor.el.radio-button.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.radio-button.vue
@@ -14,8 +14,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.section.vue b/src/client/pages/page-editor/els/page-editor.el.section.vue
index 16ef2598f9..75bdf120c0 100644
--- a/src/client/pages/page-editor/els/page-editor.el.section.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.section.vue
@@ -11,7 +11,7 @@
 	</template>
 
 	<section class="ilrvjyvi">
-		<XBlocks class="children" v-model:value="value.children" :hpml="hpml"/>
+		<XBlocks class="children" v-model="value.children" :hpml="hpml"/>
 	</section>
 </XContainer>
 </template>
diff --git a/src/client/pages/page-editor/els/page-editor.el.switch.vue b/src/client/pages/page-editor/els/page-editor.el.switch.vue
index ade1291410..cf15f58c82 100644
--- a/src/client/pages/page-editor/els/page-editor.el.switch.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.switch.vue
@@ -13,8 +13,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkSwitch from '@client/components/form/switch.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.text-input.vue b/src/client/pages/page-editor/els/page-editor.el.text-input.vue
index 3c8fcc04af..210199befd 100644
--- a/src/client/pages/page-editor/els/page-editor.el.text-input.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.text-input.vue
@@ -13,7 +13,7 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue b/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue
index a4fbb08ffe..14f36db2a1 100644
--- a/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue
+++ b/src/client/pages/page-editor/els/page-editor.el.textarea-input.vue
@@ -13,8 +13,8 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XContainer from '../page-editor.container.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkInput from '@client/components/form/input.vue';
 import * as os from '@client/os';
 
 export default defineComponent({
diff --git a/src/client/pages/page-editor/page-editor.blocks.vue b/src/client/pages/page-editor/page-editor.blocks.vue
index 0065b16c8c..c27162a26e 100644
--- a/src/client/pages/page-editor/page-editor.blocks.vue
+++ b/src/client/pages/page-editor/page-editor.blocks.vue
@@ -32,7 +32,7 @@ export default defineComponent({
 	},
 
 	props: {
-		value: {
+		modelValue: {
 			type: Array,
 			required: true
 		},
@@ -41,15 +41,15 @@ export default defineComponent({
 		},
 	},
 
-	emits: ['update:value'],
+	emits: ['update:modelValue'],
 
 	computed: {
 		blocks: {
 			get() {
-				return this.value;
+				return this.modelValue;
 			},
 			set(value) {
-				this.$emit('update:value', value);
+				this.$emit('update:modelValue', value);
 			}
 		}
 	},
@@ -62,17 +62,16 @@ export default defineComponent({
 				v,
 				...this.blocks.slice(i + 1)
 			];
-			this.$emit('update:value', newValue);
+			this.$emit('update:modelValue', newValue);
 		},
 
 		removeItem(el) {
-			console.log(el);
 			const i = this.blocks.findIndex(x => x.id === el.id);
 			const newValue = [
 				...this.blocks.slice(0, i),
 				...this.blocks.slice(i + 1)
 			];
-			this.$emit('update:value', newValue);
+			this.$emit('update:modelValue', newValue);
 		},
 	}
 });
diff --git a/src/client/pages/page-editor/page-editor.script-block.vue b/src/client/pages/page-editor/page-editor.script-block.vue
index fedcd7b317..3313fc1ba9 100644
--- a/src/client/pages/page-editor/page-editor.script-block.vue
+++ b/src/client/pages/page-editor/page-editor.script-block.vue
@@ -7,23 +7,23 @@
 		</button>
 	</template>
 
-	<section v-if="value.type === null" class="pbglfege" @click="changeType()">
+	<section v-if="modelValue.type === null" class="pbglfege" @click="changeType()">
 		{{ $ts._pages.script.emptySlot }}
 	</section>
-	<section v-else-if="value.type === 'text'" class="tbwccoaw">
-		<input v-model="value.value"/>
+	<section v-else-if="modelValue.type === 'text'" class="tbwccoaw">
+		<input v-model="modelValue.value"/>
 	</section>
-	<section v-else-if="value.type === 'multiLineText'" class="tbwccoaw">
-		<textarea v-model="value.value"></textarea>
+	<section v-else-if="modelValue.type === 'multiLineText'" class="tbwccoaw">
+		<textarea v-model="modelValue.value"></textarea>
 	</section>
-	<section v-else-if="value.type === 'textList'" class="tbwccoaw">
-		<textarea v-model="value.value" :placeholder="$ts._pages.script.blocks._textList.info"></textarea>
+	<section v-else-if="modelValue.type === 'textList'" class="tbwccoaw">
+		<textarea v-model="modelValue.value" :placeholder="$ts._pages.script.blocks._textList.info"></textarea>
 	</section>
-	<section v-else-if="value.type === 'number'" class="tbwccoaw">
-		<input v-model="value.value" type="number"/>
+	<section v-else-if="modelValue.type === 'number'" class="tbwccoaw">
+		<input v-model="modelValue.value" type="number"/>
 	</section>
-	<section v-else-if="value.type === 'ref'" class="hpdwcrvs">
-		<select v-model="value.value">
+	<section v-else-if="modelValue.type === 'ref'" class="hpdwcrvs">
+		<select v-model="modelValue.value">
 			<option v-for="v in hpml.getVarsByType(getExpectedType ? getExpectedType() : null).filter(x => x.name !== name)" :value="v.name">{{ v.name }}</option>
 			<optgroup :label="$ts._pages.script.argVariables">
 				<option v-for="v in fnSlots" :value="v.name">{{ v.name }}</option>
@@ -36,21 +36,21 @@
 			</optgroup>
 		</select>
 	</section>
-	<section v-else-if="value.type === 'aiScriptVar'" class="tbwccoaw">
-		<input v-model="value.value"/>
+	<section v-else-if="modelValue.type === 'aiScriptVar'" class="tbwccoaw">
+		<input v-model="modelValue.value"/>
 	</section>
-	<section v-else-if="value.type === 'fn'" class="" style="padding:0 16px 16px 16px;">
+	<section v-else-if="modelValue.type === 'fn'" class="" style="padding:0 16px 16px 16px;">
 		<MkTextarea v-model="slots">
 			<template #label>{{ $ts._pages.script.blocks._fn.slots }}</template>
 			<template #caption>{{ $t('_pages.script.blocks._fn.slots-info') }}</template>
 		</MkTextarea>
-		<XV v-if="value.value.expression" v-model:value="value.value.expression" :title="$t(`_pages.script.blocks._fn.arg1`)" :get-expected-type="() => null" :hpml="hpml" :fn-slots="value.value.slots" :name="name"/>
+		<XV v-if="modelValue.value.expression" v-model="modelValue.value.expression" :title="$t(`_pages.script.blocks._fn.arg1`)" :get-expected-type="() => null" :hpml="hpml" :fn-slots="value.value.slots" :name="name"/>
 	</section>
-	<section v-else-if="value.type.startsWith('fn:')" class="" style="padding:16px;">
-		<XV v-for="(x, i) in value.args" v-model:value="value.args[i]" :title="hpml.getVarByName(value.type.split(':')[1]).value.slots[i].name" :get-expected-type="() => null" :hpml="hpml" :name="name" :key="i"/>
+	<section v-else-if="modelValue.type.startsWith('fn:')" class="" style="padding:16px;">
+		<XV v-for="(x, i) in modelValue.args" v-model="value.args[i]" :title="hpml.getVarByName(modelValue.type.split(':')[1]).value.slots[i].name" :get-expected-type="() => null" :hpml="hpml" :name="name" :key="i"/>
 	</section>
 	<section v-else class="" style="padding:16px;">
-		<XV v-for="(x, i) in value.args" v-model:value="value.args[i]" :title="$t(`_pages.script.blocks._${value.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :hpml="hpml" :name="name" :fn-slots="fnSlots" :key="i"/>
+		<XV v-for="(x, i) in modelValue.args" v-model="modelValue.args[i]" :title="$t(`_pages.script.blocks._${modelValue.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :hpml="hpml" :name="name" :fn-slots="fnSlots" :key="i"/>
 	</section>
 </XContainer>
 </template>
@@ -59,7 +59,7 @@
 import { defineAsyncComponent, defineComponent } from 'vue';
 import { v4 as uuid } from 'uuid';
 import XContainer from './page-editor.container.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
 import { blockDefs } from '@client/scripts/hpml/index';
 import * as os from '@client/os';
 import { isLiteralValue } from '@client/scripts/hpml/expr';
@@ -78,7 +78,7 @@ export default defineComponent({
 			required: false,
 			default: null
 		},
-		value: {
+		modelValue: {
 			required: true
 		},
 		title: {
@@ -113,21 +113,21 @@ export default defineComponent({
 
 	computed: {
 		icon(): any {
-			if (this.value.type === null) return null;
-			if (this.value.type.startsWith('fn:')) return 'fas fa-plug';
-			return blockDefs.find(x => x.type === this.value.type).icon;
+			if (this.modelValue.type === null) return null;
+			if (this.modelValue.type.startsWith('fn:')) return 'fas fa-plug';
+			return blockDefs.find(x => x.type === this.modelValue.type).icon;
 		},
 		typeText(): any {
-			if (this.value.type === null) return null;
-			if (this.value.type.startsWith('fn:')) return this.value.type.split(':')[1];
-			return this.$t(`_pages.script.blocks.${this.value.type}`);
+			if (this.modelValue.type === null) return null;
+			if (this.modelValue.type.startsWith('fn:')) return this.modelValue.type.split(':')[1];
+			return this.$t(`_pages.script.blocks.${this.modelValue.type}`);
 		},
 	},
 
 	watch: {
 		slots: {
 			handler() {
-				this.value.value.slots = this.slots.split('\n').map(x => ({
+				this.modelValue.value.slots = this.slots.split('\n').map(x => ({
 					name: x,
 					type: null
 				}));
@@ -137,24 +137,24 @@ export default defineComponent({
 	},
 
 	created() {
-		if (this.value.value == null) this.value.value = null;
+		if (this.modelValue.value == null) this.modelValue.value = null;
 
-		if (this.value.value && this.value.value.slots) this.slots = this.value.value.slots.map(x => x.name).join('\n');
+		if (this.modelValue.value && this.modelValue.value.slots) this.slots = this.modelValue.value.slots.map(x => x.name).join('\n');
 
-		this.$watch(() => this.value.type, (t) => {
+		this.$watch(() => this.modelValue.type, (t) => {
 			this.warn = null;
 
-			if (this.value.type === 'fn') {
+			if (this.modelValue.type === 'fn') {
 				const id = uuid();
-				this.value.value = {
+				this.modelValue.value = {
 					slots: [],
 					expression: { id, type: null }
 				};
 				return;
 			}
 
-			if (this.value.type && this.value.type.startsWith('fn:')) {
-				const fnName = this.value.type.split(':')[1];
+			if (this.modelValue.type && this.modelValue.type.startsWith('fn:')) {
+				const fnName = this.modelValue.type.split(':')[1];
 				const fn = this.hpml.getVarByName(fnName);
 
 				const empties = [];
@@ -162,29 +162,29 @@ export default defineComponent({
 					const id = uuid();
 					empties.push({ id, type: null });
 				}
-				this.value.args = empties;
+				this.modelValue.args = empties;
 				return;
 			}
 
-			if (isLiteralValue(this.value)) return;
+			if (isLiteralValue(this.modelValue)) return;
 
 			const empties = [];
-			for (let i = 0; i < funcDefs[this.value.type].in.length; i++) {
+			for (let i = 0; i < funcDefs[this.modelValue.type].in.length; i++) {
 				const id = uuid();
 				empties.push({ id, type: null });
 			}
-			this.value.args = empties;
+			this.modelValue.args = empties;
 
-			for (let i = 0; i < funcDefs[this.value.type].in.length; i++) {
-				const inType = funcDefs[this.value.type].in[i];
+			for (let i = 0; i < funcDefs[this.modelValue.type].in.length; i++) {
+				const inType = funcDefs[this.modelValue.type].in[i];
 				if (typeof inType !== 'number') {
-					if (inType === 'number') this.value.args[i].type = 'number';
-					if (inType === 'string') this.value.args[i].type = 'text';
+					if (inType === 'number') this.modelValue.args[i].type = 'number';
+					if (inType === 'string') this.modelValue.args[i].type = 'text';
 				}
 			}
 		});
 
-		this.$watch(() => this.value.args, (args) => {
+		this.$watch(() => this.modelValue.args, (args) => {
 			if (args == null) {
 				this.warn = null;
 				return;
@@ -202,8 +202,8 @@ export default defineComponent({
 		});
 
 		this.$watch(() => this.hpml.variables, () => {
-			if (this.type != null && this.value) {
-				this.error = this.hpml.typeCheck(this.value);
+			if (this.type != null && this.modelValue) {
+				this.error = this.hpml.typeCheck(this.modelValue);
 			}
 		}, {
 			deep: true
@@ -221,11 +221,11 @@ export default defineComponent({
 				showCancelButton: true
 			});
 			if (canceled) return;
-			this.value.type = type;
+			this.modelValue.type = type;
 		},
 
 		_getExpectedType(slot: number) {
-			return this.hpml.getExpectedType(this.value, slot);
+			return this.hpml.getExpectedType(this.modelValue, slot);
 		}
 	}
 });
diff --git a/src/client/pages/page-editor/page-editor.vue b/src/client/pages/page-editor/page-editor.vue
index dc6896ba12..2d617bee75 100644
--- a/src/client/pages/page-editor/page-editor.vue
+++ b/src/client/pages/page-editor/page-editor.vue
@@ -47,7 +47,7 @@
 	<MkContainer :foldable="true" :expanded="true" class="_gap">
 		<template #header><i class="fas fa-sticky-note"></i> {{ $ts._pages.contents }}</template>
 		<div style="padding: 16px;">
-			<XBlocks class="content" v-model:value="content" :hpml="hpml"/>
+			<XBlocks class="content" v-model="content" :hpml="hpml"/>
 
 			<MkButton @click="add()" v-if="!readonly"><i class="fas fa-plus"></i></MkButton>
 		</div>
@@ -94,12 +94,12 @@ import 'vue-prism-editor/dist/prismeditor.min.css';
 import { v4 as uuid } from 'uuid';
 import XVariable from './page-editor.script-block.vue';
 import XBlocks from './page-editor.blocks.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
 import MkContainer from '@client/components/ui/container.vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkSelect from '@client/components/ui/select.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkSelect from '@client/components/form/select.vue';
+import MkSwitch from '@client/components/form/switch.vue';
+import MkInput from '@client/components/form/input.vue';
 import { blockDefs } from '@client/scripts/hpml/index';
 import { HpmlTypeChecker } from '@client/scripts/hpml/type-checker';
 import { url } from '@client/config';
diff --git a/src/client/pages/pages.vue b/src/client/pages/pages.vue
index 52a860be13..80fc53a961 100644
--- a/src/client/pages/pages.vue
+++ b/src/client/pages/pages.vue
@@ -1,6 +1,6 @@
 <template>
 <div>
-	<MkTab v-model:value="tab" v-if="$i">
+	<MkTab v-model="tab" v-if="$i">
 		<option value="featured"><i class="fas fa-fire-alt"></i> {{ $ts._pages.featured }}</option>
 		<option value="my"><i class="fas fa-edit"></i> {{ $ts._pages.my }}</option>
 		<option value="liked"><i class="fas fa-heart"></i> {{ $ts._pages.liked }}</option>
diff --git a/src/client/pages/reset-password.vue b/src/client/pages/reset-password.vue
index c331382132..6dd9f24259 100644
--- a/src/client/pages/reset-password.vue
+++ b/src/client/pages/reset-password.vue
@@ -1,6 +1,6 @@
 <template>
 <FormBase v-if="token">
-	<FormInput v-model:value="password" type="password">
+	<FormInput v-model="password" type="password">
 		<template #prefix><i class="fas fa-lock"></i></template>
 		<span>{{ $ts.newPassword }}</span>
 	</FormInput>
@@ -11,11 +11,11 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/reversi/game.setting.vue b/src/client/pages/reversi/game.setting.vue
index 1cc623b790..52757b0032 100644
--- a/src/client/pages/reversi/game.setting.vue
+++ b/src/client/pages/reversi/game.setting.vue
@@ -127,8 +127,8 @@
 import { defineComponent } from 'vue';
 import * as maps from '../../../games/reversi/maps';
 import MkButton from '@client/components/ui/button.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import MkRadio from '@client/components/ui/radio.vue';
+import MkSwitch from '@client/components/form/switch.vue';
+import MkRadio from '@client/components/form/radio.vue';
 
 export default defineComponent({
 	components: {
diff --git a/src/client/pages/room/room.vue b/src/client/pages/room/room.vue
index 365ed5b803..671dca3577 100644
--- a/src/client/pages/room/room.vue
+++ b/src/client/pages/room/room.vue
@@ -57,7 +57,7 @@ import XPreview from './preview.vue';
 const storeItems = require('@client/scripts/room/furnitures.json5');
 import { query as urlQuery } from '../../../prelude/url';
 import MkButton from '@client/components/ui/button.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkSelect from '@client/components/form/select.vue';
 import { selectFile } from '@client/scripts/select-file';
 import * as os from '@client/os';
 import { ColdDeviceStorage } from '@client/store';
diff --git a/src/client/pages/settings/2fa.vue b/src/client/pages/settings/2fa.vue
index 48b06eaa24..386e7c635a 100644
--- a/src/client/pages/settings/2fa.vue
+++ b/src/client/pages/settings/2fa.vue
@@ -72,11 +72,11 @@ import { hostname } from '@client/config';
 import { byteify, hexify, stringify } from '@client/scripts/2fa';
 import MkButton from '@client/components/ui/button.vue';
 import MkInfo from '@client/components/ui/info.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSwitch from '@client/components/form/switch.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/settings/account-info.vue b/src/client/pages/settings/account-info.vue
index 4d851b7b12..16ce91b12f 100644
--- a/src/client/pages/settings/account-info.vue
+++ b/src/client/pages/settings/account-info.vue
@@ -134,11 +134,11 @@
 import { defineAsyncComponent, defineComponent } from 'vue';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
 import * as os from '@client/os';
 import number from '@client/filters/number';
 import bytes from '@client/filters/bytes';
diff --git a/src/client/pages/settings/accounts.vue b/src/client/pages/settings/accounts.vue
index ca6f53776a..d2966cc216 100644
--- a/src/client/pages/settings/accounts.vue
+++ b/src/client/pages/settings/accounts.vue
@@ -3,8 +3,8 @@
 	<FormSuspense :p="init">
 		<FormButton @click="addAccount" primary><i class="fas fa-plus"></i> {{ $ts.addAccount }}</FormButton>
 
-		<div class="_formItem _button" v-for="account in accounts" :key="account.id" @click="menu(account, $event)">
-			<div class="_formPanel lcjjdxlm">
+		<div class="_debobigegoItem _button" v-for="account in accounts" :key="account.id" @click="menu(account, $event)">
+			<div class="_debobigegoPanel lcjjdxlm">
 				<div class="avatar">
 					<MkAvatar :user="account" class="avatar"/>
 				</div>
@@ -24,11 +24,11 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSuspense from '@client/components/form/suspense.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import { getAccounts, addAccount, login } from '@client/account';
@@ -47,6 +47,7 @@ export default defineComponent({
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.accounts,
 				icon: 'fas fa-users',
+				bg: 'var(--bg)',
 			},
 			storedAccounts: getAccounts().then(accounts => accounts.filter(x => x.id !== this.$i.id)),
 			accounts: null,
diff --git a/src/client/pages/settings/api.vue b/src/client/pages/settings/api.vue
index 396d4405c3..5c7496e2f9 100644
--- a/src/client/pages/settings/api.vue
+++ b/src/client/pages/settings/api.vue
@@ -10,10 +10,10 @@
 import { defineComponent } from 'vue';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -30,7 +30,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: 'API',
-				icon: 'fas fa-key'
+				icon: 'fas fa-key',
+				bg: 'var(--bg)',
 			},
 			isDesktop: window.innerWidth >= 1100,
 		};
diff --git a/src/client/pages/settings/apps.vue b/src/client/pages/settings/apps.vue
index c864920ce1..da4f672adf 100644
--- a/src/client/pages/settings/apps.vue
+++ b/src/client/pages/settings/apps.vue
@@ -8,7 +8,7 @@
 			</div>
 		</template>
 		<template #default="{items}">
-			<div class="_formPanel bfomjevm" v-for="token in items" :key="token.id">
+			<div class="_debobigegoPanel bfomjevm" v-for="token in items" :key="token.id">
 				<img class="icon" :src="token.iconUrl" alt="" v-if="token.iconUrl"/>
 				<div class="body">
 					<div class="name">{{ token.name }}</div>
@@ -39,12 +39,12 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormPagination from '@client/components/form/pagination.vue';
+import FormPagination from '@client/components/debobigego/pagination.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -61,6 +61,7 @@ export default defineComponent({
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.installedApps,
 				icon: 'fas fa-plug',
+				bg: 'var(--bg)',
 			},
 			pagination: {
 				endpoint: 'i/apps',
diff --git a/src/client/pages/settings/custom-css.vue b/src/client/pages/settings/custom-css.vue
index 0781eeebd7..fd473a11fa 100644
--- a/src/client/pages/settings/custom-css.vue
+++ b/src/client/pages/settings/custom-css.vue
@@ -2,7 +2,7 @@
 <FormBase>
 	<FormInfo warn>{{ $ts.customCssWarn }}</FormInfo>
 
-	<FormTextarea v-model:value="localCustomCss" manual-save tall class="_monospace" style="tab-size: 2;">
+	<FormTextarea v-model="localCustomCss" manual-save tall class="_monospace" style="tab-size: 2;">
 		<span>{{ $ts.local }}</span>
 	</FormTextarea>
 </FormBase>
@@ -13,11 +13,11 @@ import { defineComponent } from 'vue';
 import FormTextarea from '@client/components/form/textarea.vue';
 import FormSelect from '@client/components/form/select.vue';
 import FormRadios from '@client/components/form/radios.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormInfo from '@client/components/form/info.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
 import * as os from '@client/os';
 import { ColdDeviceStorage } from '@client/store';
 import { unisonReload } from '@client/scripts/unison-reload';
@@ -42,7 +42,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.customCss,
-				icon: 'fas fa-code'
+				icon: 'fas fa-code',
+				bg: 'var(--bg)',
 			},
 			localCustomCss: localStorage.getItem('customCss')
 		}
diff --git a/src/client/pages/settings/deck.vue b/src/client/pages/settings/deck.vue
index 05f3061ca1..2b49ef956c 100644
--- a/src/client/pages/settings/deck.vue
+++ b/src/client/pages/settings/deck.vue
@@ -2,10 +2,10 @@
 <FormBase>
 	<FormGroup>
 		<template #label>{{ $ts.defaultNavigationBehaviour }}</template>
-		<FormSwitch v-model:value="navWindow">{{ $ts.openInWindow }}</FormSwitch>
+		<FormSwitch v-model="navWindow">{{ $ts.openInWindow }}</FormSwitch>
 	</FormGroup>
 
-	<FormSwitch v-model:value="alwaysShowMainColumn">{{ $ts._deck.alwaysShowMainColumn }}</FormSwitch>
+	<FormSwitch v-model="alwaysShowMainColumn">{{ $ts._deck.alwaysShowMainColumn }}</FormSwitch>
 
 	<FormRadios v-model="columnAlign">
 		<template #desc>{{ $ts._deck.columnAlign }}</template>
@@ -20,7 +20,7 @@
 		<option :value="48">{{ $ts.wide }}</option>
 	</FormRadios>
 
-	<FormInput v-model:value="columnMargin" type="number">
+	<FormInput v-model="columnMargin" type="number">
 		<span>{{ $ts._deck.columnMargin }}</span>
 		<template #suffix>px</template>
 	</FormInput>
@@ -32,11 +32,11 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import FormSwitch from '@client/components/form/switch.vue';
-import FormLink from '@client/components/form/link.vue';
+import FormLink from '@client/components/debobigego/link.vue';
 import FormRadios from '@client/components/form/radios.vue';
 import FormInput from '@client/components/form/input.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import { deckStore } from '@client/ui/deck/deck-store';
 import * as os from '@client/os';
 import { unisonReload } from '@client/scripts/unison-reload';
@@ -58,7 +58,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.deck,
-				icon: 'fas fa-columns'
+				icon: 'fas fa-columns',
+				bg: 'var(--bg)',
 			},
 		}
 	},
diff --git a/src/client/pages/settings/delete-account.vue b/src/client/pages/settings/delete-account.vue
index 3af1879857..6bac214e04 100644
--- a/src/client/pages/settings/delete-account.vue
+++ b/src/client/pages/settings/delete-account.vue
@@ -9,10 +9,10 @@
 
 <script lang="ts">
 import { defineAsyncComponent, defineComponent } from 'vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import { debug } from '@client/config';
 import { signout } from '@client/account';
@@ -32,7 +32,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts._accountDelete.accountDelete,
-				icon: 'fas fa-exclamation-triangle'
+				icon: 'fas fa-exclamation-triangle',
+				bg: 'var(--bg)',
 			},
 			debug,
 		}
diff --git a/src/client/pages/settings/drive.vue b/src/client/pages/settings/drive.vue
index 83068a8335..177bf058f3 100644
--- a/src/client/pages/settings/drive.vue
+++ b/src/client/pages/settings/drive.vue
@@ -2,8 +2,8 @@
 <FormBase class="">
 	<FormGroup v-if="!fetching">
 		<template #label>{{ $ts.usageAmount }}</template>
-		<div class="_formItem uawsfosz">
-			<div class="_formPanel">
+		<div class="_debobigegoItem uawsfosz">
+			<div class="_debobigegoPanel">
 				<div class="meter"><div :style="meterStyle"></div></div>
 			</div>
 		</div>
@@ -17,9 +17,9 @@
 		</FormKeyValueView>
 	</FormGroup>
 
-	<div class="_formItem">
-		<div class="_formLabel">{{ $ts.statistics }}</div>
-		<div class="_formPanel">
+	<div class="_debobigegoItem">
+		<div class="_debobigegoLabel">{{ $ts.statistics }}</div>
+		<div class="_debobigegoPanel">
 			<div ref="chart"></div>
 		</div>
 	</div>
@@ -36,10 +36,10 @@
 import { defineComponent } from 'vue';
 import * as tinycolor from 'tinycolor2';
 import ApexCharts from 'apexcharts';
-import FormButton from '@client/components/form/button.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormBase from '@client/components/form/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormBase from '@client/components/debobigego/base.vue';
 import * as os from '@client/os';
 import bytes from '@client/filters/bytes';
 import * as symbols from '@client/symbols';
@@ -58,7 +58,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.drive,
-				icon: 'fas fa-cloud'
+				icon: 'fas fa-cloud',
+				bg: 'var(--bg)',
 			},
 			fetching: true,
 			usage: null,
diff --git a/src/client/pages/settings/email-address.vue b/src/client/pages/settings/email-address.vue
index 28eeeb6b73..f98b22ada7 100644
--- a/src/client/pages/settings/email-address.vue
+++ b/src/client/pages/settings/email-address.vue
@@ -1,7 +1,7 @@
 <template>
 <FormBase>
 	<FormGroup>
-		<FormInput v-model:value="emailAddress" type="email">
+		<FormInput v-model="emailAddress" type="email">
 			{{ $ts.emailAddress }}
 			<template #desc v-if="$i.email && !$i.emailVerified">{{ $ts.verificationEmailSent }}</template>
 			<template #desc v-else-if="emailAddress === $i.email && $i.emailVerified">{{ $ts.emailVerified }}</template>
@@ -13,10 +13,10 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormButton from '@client/components/form/button.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import FormInput from '@client/components/form/input.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -34,7 +34,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.emailAddress,
-				icon: 'fas fa-envelope'
+				icon: 'fas fa-envelope',
+				bg: 'var(--bg)',
 			},
 			emailAddress: null,
 			code: null,
diff --git a/src/client/pages/settings/email-notification.vue b/src/client/pages/settings/email-notification.vue
index ac3402568a..1b78621c3f 100644
--- a/src/client/pages/settings/email-notification.vue
+++ b/src/client/pages/settings/email-notification.vue
@@ -1,22 +1,22 @@
 <template>
 <FormBase>
 	<FormGroup>
-		<FormSwitch v-model:value="mention">
+		<FormSwitch v-model="mention">
 			{{ $ts._notification._types.mention }}
 		</FormSwitch>
-		<FormSwitch v-model:value="reply">
+		<FormSwitch v-model="reply">
 			{{ $ts._notification._types.reply }}
 		</FormSwitch>
-		<FormSwitch v-model:value="quote">
+		<FormSwitch v-model="quote">
 			{{ $ts._notification._types.quote }}
 		</FormSwitch>
-		<FormSwitch v-model:value="follow">
+		<FormSwitch v-model="follow">
 			{{ $ts._notification._types.follow }}
 		</FormSwitch>
-		<FormSwitch v-model:value="receiveFollowRequest">
+		<FormSwitch v-model="receiveFollowRequest">
 			{{ $ts._notification._types.receiveFollowRequest }}
 		</FormSwitch>
-		<FormSwitch v-model:value="groupInvited">
+		<FormSwitch v-model="groupInvited">
 			{{ $ts._notification._types.groupInvited }}
 		</FormSwitch>
 	</FormGroup>
@@ -25,10 +25,10 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormButton from '@client/components/form/button.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import FormSwitch from '@client/components/form/switch.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 import * as symbols from '@client/symbols';
@@ -47,7 +47,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.emailNotification,
-				icon: 'fas fa-envelope'
+				icon: 'fas fa-envelope',
+				bg: 'var(--bg)',
 			},
 
 			mention: this.$i.emailNotificationTypes.includes('mention'),
diff --git a/src/client/pages/settings/email.vue b/src/client/pages/settings/email.vue
index aa20d9d94e..adc62133ac 100644
--- a/src/client/pages/settings/email.vue
+++ b/src/client/pages/settings/email.vue
@@ -14,7 +14,7 @@
 		{{ $ts.emailNotification }}
 	</FormLink>
 
-	<FormSwitch :value="$i.receiveAnnouncementEmail" @update:value="onChangeReceiveAnnouncementEmail">
+	<FormSwitch :value="$i.receiveAnnouncementEmail" @update:modelValue="onChangeReceiveAnnouncementEmail">
 		{{ $ts.receiveAnnouncementFromInstance }}
 	</FormSwitch>
 </FormBase>
@@ -22,11 +22,11 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormButton from '@client/components/form/button.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormSwitch from '@client/components/form/switch.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -45,7 +45,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.email,
-				icon: 'fas fa-envelope'
+				icon: 'fas fa-envelope',
+				bg: 'var(--bg)',
 			},
 		}
 	},
diff --git a/src/client/pages/settings/experimental-features.vue b/src/client/pages/settings/experimental-features.vue
index f8d5e419e9..971c45a628 100644
--- a/src/client/pages/settings/experimental-features.vue
+++ b/src/client/pages/settings/experimental-features.vue
@@ -8,11 +8,11 @@
 import { defineAsyncComponent, defineComponent } from 'vue';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/settings/general.vue b/src/client/pages/settings/general.vue
index f8e8e6b24b..59dd251948 100644
--- a/src/client/pages/settings/general.vue
+++ b/src/client/pages/settings/general.vue
@@ -1,8 +1,8 @@
 <template>
 <FormBase>
-	<FormSwitch v-model:value="showFixedPostForm">{{ $ts.showFixedPostForm }}</FormSwitch>
+	<FormSwitch v-model="showFixedPostForm">{{ $ts.showFixedPostForm }}</FormSwitch>
 
-	<FormSelect v-model:value="lang">
+	<FormSelect v-model="lang">
 		<template #label>{{ $ts.uiLanguage }}</template>
 		<option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</option>
 		<template #caption>
@@ -16,13 +16,13 @@
 
 	<FormGroup>
 		<template #label>{{ $ts.behavior }}</template>
-		<FormSwitch v-model:value="imageNewTab">{{ $ts.openImageInNewTab }}</FormSwitch>
-		<FormSwitch v-model:value="enableInfiniteScroll">{{ $ts.enableInfiniteScroll }}</FormSwitch>
-		<FormSwitch v-model:value="useReactionPickerForContextMenu">{{ $ts.useReactionPickerForContextMenu }}</FormSwitch>
-		<FormSwitch v-model:value="disablePagesScript">{{ $ts.disablePagesScript }}</FormSwitch>
+		<FormSwitch v-model="imageNewTab">{{ $ts.openImageInNewTab }}</FormSwitch>
+		<FormSwitch v-model="enableInfiniteScroll">{{ $ts.enableInfiniteScroll }}</FormSwitch>
+		<FormSwitch v-model="useReactionPickerForContextMenu">{{ $ts.useReactionPickerForContextMenu }}</FormSwitch>
+		<FormSwitch v-model="disablePagesScript">{{ $ts.disablePagesScript }}</FormSwitch>
 	</FormGroup>
 
-	<FormSelect v-model:value="serverDisconnectedBehavior">
+	<FormSelect v-model="serverDisconnectedBehavior">
 		<template #label>{{ $ts.whenServerDisconnected }}</template>
 		<option value="reload">{{ $ts._serverDisconnectedBehavior.reload }}</option>
 		<option value="dialog">{{ $ts._serverDisconnectedBehavior.dialog }}</option>
@@ -31,22 +31,22 @@
 
 	<FormGroup>
 		<template #label>{{ $ts.appearance }}</template>
-		<FormSwitch v-model:value="disableAnimatedMfm">{{ $ts.disableAnimatedMfm }}</FormSwitch>
-		<FormSwitch v-model:value="reduceAnimation">{{ $ts.reduceUiAnimation }}</FormSwitch>
-		<FormSwitch v-model:value="useBlurEffect">{{ $ts.useBlurEffect }}</FormSwitch>
-		<FormSwitch v-model:value="useBlurEffectForModal">{{ $ts.useBlurEffectForModal }}</FormSwitch>
-		<FormSwitch v-model:value="showGapBetweenNotesInTimeline">{{ $ts.showGapBetweenNotesInTimeline }}</FormSwitch>
-		<FormSwitch v-model:value="loadRawImages">{{ $ts.loadRawImages }}</FormSwitch>
-		<FormSwitch v-model:value="disableShowingAnimatedImages">{{ $ts.disableShowingAnimatedImages }}</FormSwitch>
-		<FormSwitch v-model:value="squareAvatars">{{ $ts.squareAvatars }}</FormSwitch>
-		<FormSwitch v-model:value="useSystemFont">{{ $ts.useSystemFont }}</FormSwitch>
-		<FormSwitch v-model:value="useOsNativeEmojis">{{ $ts.useOsNativeEmojis }}
+		<FormSwitch v-model="disableAnimatedMfm">{{ $ts.disableAnimatedMfm }}</FormSwitch>
+		<FormSwitch v-model="reduceAnimation">{{ $ts.reduceUiAnimation }}</FormSwitch>
+		<FormSwitch v-model="useBlurEffect">{{ $ts.useBlurEffect }}</FormSwitch>
+		<FormSwitch v-model="useBlurEffectForModal">{{ $ts.useBlurEffectForModal }}</FormSwitch>
+		<FormSwitch v-model="showGapBetweenNotesInTimeline">{{ $ts.showGapBetweenNotesInTimeline }}</FormSwitch>
+		<FormSwitch v-model="loadRawImages">{{ $ts.loadRawImages }}</FormSwitch>
+		<FormSwitch v-model="disableShowingAnimatedImages">{{ $ts.disableShowingAnimatedImages }}</FormSwitch>
+		<FormSwitch v-model="squareAvatars">{{ $ts.squareAvatars }}</FormSwitch>
+		<FormSwitch v-model="useSystemFont">{{ $ts.useSystemFont }}</FormSwitch>
+		<FormSwitch v-model="useOsNativeEmojis">{{ $ts.useOsNativeEmojis }}
 			<div><Mfm text="🍮🍦🍭🍩🍰🍫🍬🥞🍪" :key="useOsNativeEmojis"/></div>
 		</FormSwitch>
 	</FormGroup>
 
 	<FormGroup>
-		<FormSwitch v-model:value="aiChanMode">{{ $ts.aiChanMode }}</FormSwitch>
+		<FormSwitch v-model="aiChanMode">{{ $ts.aiChanMode }}</FormSwitch>
 	</FormGroup>
 
 	<FormRadios v-model="fontSize">
@@ -57,14 +57,14 @@
 		<option value="veryLarge"><span style="font-size: 20px;">Aa</span></option>
 	</FormRadios>
 
-	<FormSelect v-model:value="instanceTicker">
+	<FormSelect v-model="instanceTicker">
 		<template #label>{{ $ts.instanceTicker }}</template>
 		<option value="none">{{ $ts._instanceTicker.none }}</option>
 		<option value="remote">{{ $ts._instanceTicker.remote }}</option>
 		<option value="always">{{ $ts._instanceTicker.always }}</option>
 	</FormSelect>
 
-	<FormSelect v-model:value="nsfw">
+	<FormSelect v-model="nsfw">
 		<template #label>{{ $ts.nsfw }}</template>
 		<option value="respect">{{ $ts._nsfw.respect }}</option>
 		<option value="ignore">{{ $ts._nsfw.ignore }}</option>
@@ -73,10 +73,10 @@
 
 	<FormGroup>
 		<template #label>{{ $ts.defaultNavigationBehaviour }}</template>
-		<FormSwitch v-model:value="defaultSideView">{{ $ts.openInSideView }}</FormSwitch>
+		<FormSwitch v-model="defaultSideView">{{ $ts.openInSideView }}</FormSwitch>
 	</FormGroup>
 
-	<FormSelect v-model:value="chatOpenBehavior">
+	<FormSelect v-model="chatOpenBehavior">
 		<template #label>{{ $ts.chatOpenBehavior }}</template>
 		<option value="page">{{ $ts.showInPage }}</option>
 		<option value="window">{{ $ts.openInWindow }}</option>
@@ -91,13 +91,13 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormSelect from '@client/components/form/select.vue';
-import FormRadios from '@client/components/form/radios.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormSelect from '@client/components/debobigego/select.vue';
+import FormRadios from '@client/components/debobigego/radios.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import MkLink from '@client/components/link.vue';
 import { langs } from '@client/config';
 import { defaultStore } from '@client/store';
@@ -124,7 +124,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.general,
-				icon: 'fas fa-cogs'
+				icon: 'fas fa-cogs',
+				bg: 'var(--bg)'
 			},
 			langs,
 			lang: localStorage.getItem('lang'),
diff --git a/src/client/pages/settings/import-export.vue b/src/client/pages/settings/import-export.vue
index e77efb4429..5f1ed43340 100644
--- a/src/client/pages/settings/import-export.vue
+++ b/src/client/pages/settings/import-export.vue
@@ -28,9 +28,9 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import * as os from '@client/os';
 import { selectFile } from '@client/scripts/select-file';
 import * as symbols from '@client/symbols';
@@ -48,7 +48,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.importAndExport,
-				icon: 'fas fa-boxes'
+				icon: 'fas fa-boxes',
+				bg: 'var(--bg)',
 			},
 		}
 	},
diff --git a/src/client/pages/settings/index.link.vue b/src/client/pages/settings/index.link.vue
new file mode 100644
index 0000000000..37d06bc22e
--- /dev/null
+++ b/src/client/pages/settings/index.link.vue
@@ -0,0 +1,97 @@
+<template>
+<div class="qmfkfnzj">
+	<a class="main _button" :href="to" target="_blank" v-if="external">
+		<span class="icon"><slot name="icon"></slot></span>
+		<span class="text"><slot></slot></span>
+	</a>
+	<MkA class="main _button" :class="{ active }" :to="to" :behavior="behavior" v-else>
+		<span class="icon"><slot name="icon"></slot></span>
+		<span class="text"><slot></slot></span>
+	</MkA>
+</div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+	props: {
+		to: {
+			type: String,
+			required: true
+		},
+		active: {
+			type: Boolean,
+			required: false
+		},
+		external: {
+			type: Boolean,
+			required: false
+		},
+		behavior: {
+			type: String,
+			required: false,
+		},
+	},
+	data() {
+		return {
+		};
+	}
+});
+</script>
+
+<style lang="scss" scoped>
+.qmfkfnzj {
+	> .main {
+		display: flex;
+		align-items: center;
+		width: 100%;
+		box-sizing: border-box;
+		padding: 10px 16px 10px 14px;
+		border-radius: 999px;
+		font-size: 0.9em;
+
+		&:hover {
+			text-decoration: none;
+			background: var(--panelHighlight);
+		}
+
+		&.active {
+			color: var(--accent);
+			background: var(--accentedBg);
+		}
+
+		> .icon {
+			width: 32px;
+			margin-right: 2px;
+			flex-shrink: 0;
+			text-align: center;
+			opacity: 0.8;
+
+			&:empty {
+				display: none;
+
+				& + .text {
+					padding-left: 4px;
+				}
+			}
+		}
+
+		> .text {
+			white-space: nowrap;
+			text-overflow: ellipsis;
+			overflow: hidden;
+			padding-right: 12px;
+		}
+
+		> .right {
+			margin-left: auto;
+			opacity: 0.7;
+
+			> .text:not(:empty) {
+				margin-right: 0.75em;
+			}
+		}
+	}
+}
+</style>
diff --git a/src/client/pages/settings/index.vue b/src/client/pages/settings/index.vue
index 3fb5f5f1e6..f3d118e4f0 100644
--- a/src/client/pages/settings/index.vue
+++ b/src/client/pages/settings/index.vue
@@ -1,50 +1,48 @@
 <template>
 <div class="vvcocwet" :class="{ wide: !narrow }" ref="el">
 	<div class="nav" v-if="!narrow || page == null">
-		<FormBase>
-			<FormGroup>
-				<div class="_formItem">
-					<div class="_formPanel lwjxoukj">
-						<MkAvatar :user="$i" class="avatar"/>
-					</div>
+		<FormGroup>
+			<div class="_debobigegoItem">
+				<div class="_debobigegoPanel lwjxoukj">
+					<MkAvatar :user="$i" class="avatar"/>
 				</div>
-				<FormLink :active="page === 'accounts'" replace to="/settings/accounts"><template #icon><i class="fas fa-users"></i></template>{{ $ts.accounts }}</FormLink>
-			</FormGroup>
-			<FormInfo v-if="emailNotConfigured" warn>{{ $ts.emailNotConfiguredWarning }} <MkA to="/settings/email" class="_link">{{ $ts.configure }}</MkA></FormInfo>
-			<FormGroup>
-				<template #label>{{ $ts.basicSettings }}</template>
-				<FormLink :active="page === 'profile'" replace to="/settings/profile"><template #icon><i class="fas fa-user"></i></template>{{ $ts.profile }}</FormLink>
-				<FormLink :active="page === 'privacy'" replace to="/settings/privacy"><template #icon><i class="fas fa-lock-open"></i></template>{{ $ts.privacy }}</FormLink>
-				<FormLink :active="page === 'reaction'" replace to="/settings/reaction"><template #icon><i class="fas fa-laugh"></i></template>{{ $ts.reaction }}</FormLink>
-				<FormLink :active="page === 'drive'" replace to="/settings/drive"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.drive }}</FormLink>
-				<FormLink :active="page === 'notifications'" replace to="/settings/notifications"><template #icon><i class="fas fa-bell"></i></template>{{ $ts.notifications }}</FormLink>
-				<FormLink :active="page === 'email'" replace to="/settings/email"><template #icon><i class="fas fa-envelope"></i></template>{{ $ts.email }}</FormLink>
-				<FormLink :active="page === 'integration'" replace to="/settings/integration"><template #icon><i class="fas fa-share-alt"></i></template>{{ $ts.integration }}</FormLink>
-				<FormLink :active="page === 'security'" replace to="/settings/security"><template #icon><i class="fas fa-lock"></i></template>{{ $ts.security }}</FormLink>
-			</FormGroup>
-			<FormGroup>
-				<template #label>{{ $ts.clientSettings }}</template>
-				<FormLink :active="page === 'general'" replace to="/settings/general"><template #icon><i class="fas fa-cogs"></i></template>{{ $ts.general }}</FormLink>
-				<FormLink :active="page === 'theme'" replace to="/settings/theme"><template #icon><i class="fas fa-palette"></i></template>{{ $ts.theme }}</FormLink>
-				<FormLink :active="page === 'menu'" replace to="/settings/menu"><template #icon><i class="fas fa-list-ul"></i></template>{{ $ts.menu }}</FormLink>
-				<FormLink :active="page === 'sounds'" replace to="/settings/sounds"><template #icon><i class="fas fa-music"></i></template>{{ $ts.sounds }}</FormLink>
-				<FormLink :active="page === 'plugin'" replace to="/settings/plugin"><template #icon><i class="fas fa-plug"></i></template>{{ $ts.plugins }}</FormLink>
-			</FormGroup>
-			<FormGroup>
-				<template #label>{{ $ts.otherSettings }}</template>
-				<FormLink :active="page === 'import-export'" replace to="/settings/import-export"><template #icon><i class="fas fa-boxes"></i></template>{{ $ts.importAndExport }}</FormLink>
-				<FormLink :active="page === 'mute-block'" replace to="/settings/mute-block"><template #icon><i class="fas fa-ban"></i></template>{{ $ts.muteAndBlock }}</FormLink>
-				<FormLink :active="page === 'word-mute'" replace to="/settings/word-mute"><template #icon><i class="fas fa-comment-slash"></i></template>{{ $ts.wordMute }}</FormLink>
-				<FormLink :active="page === 'api'" replace to="/settings/api"><template #icon><i class="fas fa-key"></i></template>API</FormLink>
-				<FormLink :active="page === 'other'" replace to="/settings/other"><template #icon><i class="fas fa-ellipsis-h"></i></template>{{ $ts.other }}</FormLink>
-			</FormGroup>
-			<FormGroup>
-				<FormButton @click="clear">{{ $ts.clearCache }}</FormButton>
-			</FormGroup>
-			<FormGroup>
-				<FormButton @click="logout" danger>{{ $ts.logout }}</FormButton>
-			</FormGroup>
-		</FormBase>
+			</div>
+			<XLink :active="page === 'accounts'" replace to="/settings/accounts"><template #icon><i class="fas fa-users"></i></template>{{ $ts.accounts }}</XLink>
+		</FormGroup>
+		<FormInfo v-if="emailNotConfigured" warn>{{ $ts.emailNotConfiguredWarning }} <MkA to="/settings/email" class="_link">{{ $ts.configure }}</MkA></FormInfo>
+		<FormGroup>
+			<template #label>{{ $ts.basicSettings }}</template>
+			<XLink :active="page === 'profile'" replace to="/settings/profile"><template #icon><i class="fas fa-user"></i></template>{{ $ts.profile }}</XLink>
+			<XLink :active="page === 'privacy'" replace to="/settings/privacy"><template #icon><i class="fas fa-lock-open"></i></template>{{ $ts.privacy }}</XLink>
+			<XLink :active="page === 'reaction'" replace to="/settings/reaction"><template #icon><i class="fas fa-laugh"></i></template>{{ $ts.reaction }}</XLink>
+			<XLink :active="page === 'drive'" replace to="/settings/drive"><template #icon><i class="fas fa-cloud"></i></template>{{ $ts.drive }}</XLink>
+			<XLink :active="page === 'notifications'" replace to="/settings/notifications"><template #icon><i class="fas fa-bell"></i></template>{{ $ts.notifications }}</XLink>
+			<XLink :active="page === 'email'" replace to="/settings/email"><template #icon><i class="fas fa-envelope"></i></template>{{ $ts.email }}</XLink>
+			<XLink :active="page === 'integration'" replace to="/settings/integration"><template #icon><i class="fas fa-share-alt"></i></template>{{ $ts.integration }}</XLink>
+			<XLink :active="page === 'security'" replace to="/settings/security"><template #icon><i class="fas fa-lock"></i></template>{{ $ts.security }}</XLink>
+		</FormGroup>
+		<FormGroup>
+			<template #label>{{ $ts.clientSettings }}</template>
+			<XLink :active="page === 'general'" replace to="/settings/general"><template #icon><i class="fas fa-cogs"></i></template>{{ $ts.general }}</XLink>
+			<XLink :active="page === 'theme'" replace to="/settings/theme"><template #icon><i class="fas fa-palette"></i></template>{{ $ts.theme }}</XLink>
+			<XLink :active="page === 'menu'" replace to="/settings/menu"><template #icon><i class="fas fa-list-ul"></i></template>{{ $ts.menu }}</XLink>
+			<XLink :active="page === 'sounds'" replace to="/settings/sounds"><template #icon><i class="fas fa-music"></i></template>{{ $ts.sounds }}</XLink>
+			<XLink :active="page === 'plugin'" replace to="/settings/plugin"><template #icon><i class="fas fa-plug"></i></template>{{ $ts.plugins }}</XLink>
+		</FormGroup>
+		<FormGroup>
+			<template #label>{{ $ts.otherSettings }}</template>
+			<XLink :active="page === 'import-export'" replace to="/settings/import-export"><template #icon><i class="fas fa-boxes"></i></template>{{ $ts.importAndExport }}</XLink>
+			<XLink :active="page === 'mute-block'" replace to="/settings/mute-block"><template #icon><i class="fas fa-ban"></i></template>{{ $ts.muteAndBlock }}</XLink>
+			<XLink :active="page === 'word-mute'" replace to="/settings/word-mute"><template #icon><i class="fas fa-comment-slash"></i></template>{{ $ts.wordMute }}</XLink>
+			<XLink :active="page === 'api'" replace to="/settings/api"><template #icon><i class="fas fa-key"></i></template>API</XLink>
+			<XLink :active="page === 'other'" replace to="/settings/other"><template #icon><i class="fas fa-ellipsis-h"></i></template>{{ $ts.other }}</XLink>
+		</FormGroup>
+		<FormGroup>
+			<FormButton @click="clear">{{ $ts.clearCache }}</FormButton>
+		</FormGroup>
+		<FormGroup>
+			<FormButton @click="logout" danger>{{ $ts.logout }}</FormButton>
+		</FormGroup>
 	</div>
 	<div class="main">
 		<component :is="component" :key="page" @info="onInfo" v-bind="pageProps"/>
@@ -55,11 +53,11 @@
 <script lang="ts">
 import { computed, defineAsyncComponent, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue';
 import { i18n } from '@client/i18n';
-import FormLink from '@client/components/form/link.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormInfo from '@client/components/form/info.vue';
+import XLink from './index.link.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
 import { scroll } from '@client/scripts/scroll';
 import { signout } from '@client/account';
 import { unisonReload } from '@client/scripts/unison-reload';
@@ -70,7 +68,7 @@ import { $i } from '@client/account';
 export default defineComponent({
 	components: {
 		FormBase,
-		FormLink,
+		XLink,
 		FormGroup,
 		FormButton,
 		FormInfo,
@@ -210,14 +208,13 @@ export default defineComponent({
 .vvcocwet {
 	&.wide {
 		display: flex;
-		max-width: 1100px;
+		max-width: 1000px;
 		margin: 0 auto;
 		height: 100%;
 
 		> .nav {
 			width: 32%;
 			box-sizing: border-box;
-			border-right: solid 0.5px var(--divider);
 			overflow: auto;
 		}
 
diff --git a/src/client/pages/settings/integration.vue b/src/client/pages/settings/integration.vue
index f1c0a88afc..7f398dde9d 100644
--- a/src/client/pages/settings/integration.vue
+++ b/src/client/pages/settings/integration.vue
@@ -1,26 +1,26 @@
 <template>
 <FormBase>
-	<div class="_formItem" v-if="enableTwitterIntegration">
-		<div class="_formLabel"><i class="fab fa-twitter"></i> Twitter</div>
-		<div class="_formPanel" style="padding: 16px;">
+	<div class="_debobigegoItem" v-if="enableTwitterIntegration">
+		<div class="_debobigegoLabel"><i class="fab fa-twitter"></i> Twitter</div>
+		<div class="_debobigegoPanel" style="padding: 16px;">
 			<p v-if="integrations.twitter">{{ $ts.connectedTo }}: <a :href="`https://twitter.com/${integrations.twitter.screenName}`" rel="nofollow noopener" target="_blank">@{{ integrations.twitter.screenName }}</a></p>
 			<MkButton v-if="integrations.twitter" @click="disconnectTwitter" danger>{{ $ts.disconnectService }}</MkButton>
 			<MkButton v-else @click="connectTwitter" primary>{{ $ts.connectService }}</MkButton>
 		</div>
 	</div>
 
-	<div class="_formItem" v-if="enableDiscordIntegration">
-		<div class="_formLabel"><i class="fab fa-discord"></i> Discord</div>
-		<div class="_formPanel" style="padding: 16px;">
+	<div class="_debobigegoItem" v-if="enableDiscordIntegration">
+		<div class="_debobigegoLabel"><i class="fab fa-discord"></i> Discord</div>
+		<div class="_debobigegoPanel" style="padding: 16px;">
 			<p v-if="integrations.discord">{{ $ts.connectedTo }}: <a :href="`https://discord.com/users/${integrations.discord.id}`" rel="nofollow noopener" target="_blank">@{{ integrations.discord.username }}#{{ integrations.discord.discriminator }}</a></p>
 			<MkButton v-if="integrations.discord" @click="disconnectDiscord" danger>{{ $ts.disconnectService }}</MkButton>
 			<MkButton v-else @click="connectDiscord" primary>{{ $ts.connectService }}</MkButton>
 		</div>
 	</div>
 
-	<div class="_formItem" v-if="enableGithubIntegration">
-		<div class="_formLabel"><i class="fab fa-github"></i> GitHub</div>
-		<div class="_formPanel" style="padding: 16px;">
+	<div class="_debobigegoItem" v-if="enableGithubIntegration">
+		<div class="_debobigegoLabel"><i class="fab fa-github"></i> GitHub</div>
+		<div class="_debobigegoPanel" style="padding: 16px;">
 			<p v-if="integrations.github">{{ $ts.connectedTo }}: <a :href="`https://github.com/${integrations.github.login}`" rel="nofollow noopener" target="_blank">@{{ integrations.github.login }}</a></p>
 			<MkButton v-if="integrations.github" @click="disconnectGithub" danger>{{ $ts.disconnectService }}</MkButton>
 			<MkButton v-else @click="connectGithub" primary>{{ $ts.connectService }}</MkButton>
@@ -32,7 +32,7 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import { apiUrl } from '@client/config';
-import FormBase from '@client/components/form/base.vue';
+import FormBase from '@client/components/debobigego/base.vue';
 import MkButton from '@client/components/ui/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
@@ -49,7 +49,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.integration,
-				icon: 'fas fa-share-alt'
+				icon: 'fas fa-share-alt',
+				bg: 'var(--bg)',
 			},
 			apiUrl,
 			twitterForm: null,
diff --git a/src/client/pages/settings/menu.vue b/src/client/pages/settings/menu.vue
index 4b315145e1..31472eb0c1 100644
--- a/src/client/pages/settings/menu.vue
+++ b/src/client/pages/settings/menu.vue
@@ -1,6 +1,6 @@
 <template>
 <FormBase>
-	<FormTextarea v-model:value="items" tall manual-save>
+	<FormTextarea v-model="items" tall manual-save>
 		<span>{{ $ts.menu }}</span>
 		<template #desc><button class="_textButton" @click="addItem">{{ $ts.addItem }}</button></template>
 	</FormTextarea>
@@ -19,12 +19,10 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormRadios from '@client/components/form/radios.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormRadios from '@client/components/debobigego/radios.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import { menuDef } from '@client/menu';
 import { defaultStore } from '@client/store';
@@ -45,7 +43,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.menu,
-				icon: 'fas fa-list-ul'
+				icon: 'fas fa-list-ul',
+				bg: 'var(--bg)',
 			},
 			menuDef: menuDef,
 			items: defaultStore.state.menu.join('\n'),
diff --git a/src/client/pages/settings/mute-block.vue b/src/client/pages/settings/mute-block.vue
index dde0199e18..18b2fc0af4 100644
--- a/src/client/pages/settings/mute-block.vue
+++ b/src/client/pages/settings/mute-block.vue
@@ -1,6 +1,6 @@
 <template>
 <FormBase>
-	<MkTab v-model:value="tab" style="margin-bottom: var(--margin);">
+	<MkTab v-model="tab" style="margin-bottom: var(--margin);">
 		<option value="mute">{{ $ts.mutedUsers }}</option>
 		<option value="block">{{ $ts.blockedUsers }}</option>
 	</MkTab>
@@ -35,10 +35,10 @@
 import { defineComponent } from 'vue';
 import MkPagination from '@client/components/ui/pagination.vue';
 import MkTab from '@client/components/tab.vue';
-import FormInfo from '@client/components/form/info.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import { userPage } from '@client/filters/user';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
@@ -59,7 +59,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.muteAndBlock,
-				icon: 'fas fa-ban'
+				icon: 'fas fa-ban',
+				bg: 'var(--bg)',
 			},
 			tab: 'mute',
 			mutingPagination: {
diff --git a/src/client/pages/settings/notifications.vue b/src/client/pages/settings/notifications.vue
index ec95452ba2..1ef350335c 100644
--- a/src/client/pages/settings/notifications.vue
+++ b/src/client/pages/settings/notifications.vue
@@ -11,10 +11,10 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormButton from '@client/components/form/button.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import { notificationTypes } from '../../../types';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
@@ -33,7 +33,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.notifications,
-				icon: 'fas fa-bell'
+				icon: 'fas fa-bell',
+				bg: 'var(--bg)',
 			},
 		}
 	},
diff --git a/src/client/pages/settings/other.vue b/src/client/pages/settings/other.vue
index 21b5439041..2eb922453f 100644
--- a/src/client/pages/settings/other.vue
+++ b/src/client/pages/settings/other.vue
@@ -2,18 +2,18 @@
 <FormBase>
 	<FormLink to="/settings/update">Misskey Update</FormLink>
 
-	<FormSwitch :value="$i.injectFeaturedNote" @update:value="onChangeInjectFeaturedNote">
+	<FormSwitch :value="$i.injectFeaturedNote" @update:modelValue="onChangeInjectFeaturedNote">
 		{{ $ts.showFeaturedNotesInTimeline }}
 	</FormSwitch>
 
-	<FormSwitch v-model:value="reportError">{{ $ts.sendErrorReports }}<template #desc>{{ $ts.sendErrorReportsDescription }}</template></FormSwitch>
+	<FormSwitch v-model="reportError">{{ $ts.sendErrorReports }}<template #desc>{{ $ts.sendErrorReportsDescription }}</template></FormSwitch>
 
 	<FormLink to="/settings/account-info">{{ $ts.accountInfo }}</FormLink>
 	<FormLink to="/settings/experimental-features">{{ $ts.experimentalFeatures }}</FormLink>
 
 	<FormGroup>
 		<template #label>{{ $ts.developer }}</template>
-		<FormSwitch v-model:value="debug" @update:value="changeDebug">
+		<FormSwitch v-model="debug" @update:modelValue="changeDebug">
 			DEBUG MODE
 		</FormSwitch>
 		<template v-if="debug">
@@ -34,10 +34,10 @@
 import { defineAsyncComponent, defineComponent } from 'vue';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import { debug } from '@client/config';
 import { defaultStore } from '@client/store';
@@ -60,7 +60,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.other,
-				icon: 'fas fa-ellipsis-h'
+				icon: 'fas fa-ellipsis-h',
+				bg: 'var(--bg)',
 			},
 			debug,
 		}
diff --git a/src/client/pages/settings/plugin.install.vue b/src/client/pages/settings/plugin.install.vue
index 30cbf58ad7..709ef11abb 100644
--- a/src/client/pages/settings/plugin.install.vue
+++ b/src/client/pages/settings/plugin.install.vue
@@ -3,7 +3,7 @@
 	<FormInfo warn>{{ $ts._plugin.installWarn }}</FormInfo>
 
 	<FormGroup>
-		<FormTextarea v-model:value="code" tall>
+		<FormTextarea v-model="code" tall>
 			<span>{{ $ts.code }}</span>
 		</FormTextarea>
 	</FormGroup>
@@ -20,11 +20,11 @@ import { v4 as uuid } from 'uuid';
 import FormTextarea from '@client/components/form/textarea.vue';
 import FormSelect from '@client/components/form/select.vue';
 import FormRadios from '@client/components/form/radios.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormInfo from '@client/components/form/info.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
 import * as os from '@client/os';
 import { ColdDeviceStorage } from '@client/store';
 import { unisonReload } from '@client/scripts/unison-reload';
@@ -48,7 +48,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts._plugin.install,
-				icon: 'fas fa-download'
+				icon: 'fas fa-download',
+				bg: 'var(--bg)',
 			},
 			code: null,
 		}
diff --git a/src/client/pages/settings/plugin.manage.vue b/src/client/pages/settings/plugin.manage.vue
index 3df87ca084..f1c27f1e3c 100644
--- a/src/client/pages/settings/plugin.manage.vue
+++ b/src/client/pages/settings/plugin.manage.vue
@@ -3,9 +3,9 @@
 	<FormGroup v-for="plugin in plugins" :key="plugin.id">
 		<template #label><span style="display: flex;"><b>{{ plugin.name }}</b><span style="margin-left: auto;">v{{ plugin.version }}</span></span></template>
 
-		<FormSwitch :value="plugin.active" @update:value="changeActive(plugin, $event)">{{ $ts.makeActive }}</FormSwitch>
-		<div class="_formItem">
-			<div class="_formPanel" style="padding: 16px;">
+		<FormSwitch :value="plugin.active" @update:modelValue="changeActive(plugin, $event)">{{ $ts.makeActive }}</FormSwitch>
+		<div class="_debobigegoItem">
+			<div class="_debobigegoPanel" style="padding: 16px;">
 				<div class="_keyValue">
 					<div>{{ $ts.author }}:</div>
 					<div>{{ plugin.author }}</div>
@@ -20,8 +20,8 @@
 				</div>
 			</div>
 		</div>
-		<div class="_formItem">
-			<div class="_formPanel" style="padding: 16px;">
+		<div class="_debobigegoItem">
+			<div class="_debobigegoPanel" style="padding: 16px;">
 				<MkButton @click="config(plugin)" inline v-if="plugin.config"><i class="fas fa-cog"></i> {{ $ts.settings }}</MkButton>
 				<MkButton @click="uninstall(plugin)" inline danger><i class="fas fa-trash-alt"></i> {{ $ts.uninstall }}</MkButton>
 			</div>
@@ -33,11 +33,11 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkSelect from '@client/components/ui/select.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkSelect from '@client/components/form/select.vue';
 import FormSwitch from '@client/components/form/switch.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import * as os from '@client/os';
 import { ColdDeviceStorage } from '@client/store';
 import * as symbols from '@client/symbols';
@@ -58,7 +58,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts._plugin.manage,
-				icon: 'fas fa-plug'
+				icon: 'fas fa-plug',
+				bg: 'var(--bg)',
 			},
 			plugins: ColdDeviceStorage.get('plugins'),
 		}
diff --git a/src/client/pages/settings/plugin.vue b/src/client/pages/settings/plugin.vue
index 13eaca07fd..23f263bbbd 100644
--- a/src/client/pages/settings/plugin.vue
+++ b/src/client/pages/settings/plugin.vue
@@ -7,9 +7,9 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormLink from '@client/components/form/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormLink from '@client/components/debobigego/link.vue';
 import * as os from '@client/os';
 import { ColdDeviceStorage } from '@client/store';
 import * as symbols from '@client/symbols';
@@ -26,7 +26,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.plugins,
-				icon: 'fas fa-plug'
+				icon: 'fas fa-plug',
+				bg: 'var(--bg)',
 			},
 			plugins: ColdDeviceStorage.get('plugins').length,
 		}
diff --git a/src/client/pages/settings/privacy.vue b/src/client/pages/settings/privacy.vue
index 46d8c17ca2..7756158578 100644
--- a/src/client/pages/settings/privacy.vue
+++ b/src/client/pages/settings/privacy.vue
@@ -1,43 +1,43 @@
 <template>
 <FormBase>
 	<FormGroup>
-		<FormSwitch v-model:value="isLocked" @update:value="save()">{{ $ts.makeFollowManuallyApprove }}</FormSwitch>
-		<FormSwitch v-model:value="autoAcceptFollowed" :disabled="!isLocked" @update:value="save()">{{ $ts.autoAcceptFollowed }}</FormSwitch>
+		<FormSwitch v-model="isLocked" @update:modelValue="save()">{{ $ts.makeFollowManuallyApprove }}</FormSwitch>
+		<FormSwitch v-model="autoAcceptFollowed" :disabled="!isLocked" @update:modelValue="save()">{{ $ts.autoAcceptFollowed }}</FormSwitch>
 		<template #caption>{{ $ts.lockedAccountInfo }}</template>
 	</FormGroup>
-	<FormSwitch v-model:value="hideOnlineStatus" @update:value="save()">
+	<FormSwitch v-model="hideOnlineStatus" @update:modelValue="save()">
 		{{ $ts.hideOnlineStatus }}
 		<template #desc>{{ $ts.hideOnlineStatusDescription }}</template>
 	</FormSwitch>
-	<FormSwitch v-model:value="noCrawle" @update:value="save()">
+	<FormSwitch v-model="noCrawle" @update:modelValue="save()">
 		{{ $ts.noCrawle }}
 		<template #desc>{{ $ts.noCrawleDescription }}</template>
 	</FormSwitch>
-	<FormSwitch v-model:value="isExplorable" @update:value="save()">
+	<FormSwitch v-model="isExplorable" @update:modelValue="save()">
 		{{ $ts.makeExplorable }}
 		<template #desc>{{ $ts.makeExplorableDescription }}</template>
 	</FormSwitch>
-	<FormSwitch v-model:value="rememberNoteVisibility" @update:value="save()">{{ $ts.rememberNoteVisibility }}</FormSwitch>
+	<FormSwitch v-model="rememberNoteVisibility" @update:modelValue="save()">{{ $ts.rememberNoteVisibility }}</FormSwitch>
 	<FormGroup v-if="!rememberNoteVisibility">
 		<template #label>{{ $ts.defaultNoteVisibility }}</template>
-		<FormSelect v-model:value="defaultNoteVisibility">
+		<FormSelect v-model="defaultNoteVisibility">
 			<option value="public">{{ $ts._visibility.public }}</option>
 			<option value="home">{{ $ts._visibility.home }}</option>
 			<option value="followers">{{ $ts._visibility.followers }}</option>
 			<option value="specified">{{ $ts._visibility.specified }}</option>
 		</FormSelect>
-		<FormSwitch v-model:value="defaultNoteLocalOnly">{{ $ts._visibility.localOnly }}</FormSwitch>
+		<FormSwitch v-model="defaultNoteLocalOnly">{{ $ts._visibility.localOnly }}</FormSwitch>
 	</FormGroup>
-	<FormSwitch v-model:value="keepCw" @update:value="save()">{{ $ts.keepCw }}</FormSwitch>
+	<FormSwitch v-model="keepCw" @update:modelValue="save()">{{ $ts.keepCw }}</FormSwitch>
 </FormBase>
 </template>
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormSelect from '@client/components/form/select.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormSelect from '@client/components/debobigego/select.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import * as os from '@client/os';
 import { defaultStore } from '@client/store';
 import * as symbols from '@client/symbols';
@@ -56,7 +56,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.privacy,
-				icon: 'fas fa-lock-open'
+				icon: 'fas fa-lock-open',
+				bg: 'var(--bg)',
 			},
 			isLocked: false,
 			autoAcceptFollowed: false,
diff --git a/src/client/pages/settings/profile.vue b/src/client/pages/settings/profile.vue
index de7e86bd12..3c93e93480 100644
--- a/src/client/pages/settings/profile.vue
+++ b/src/client/pages/settings/profile.vue
@@ -1,33 +1,33 @@
 <template>
 <FormBase>
 	<FormGroup>
-		<div class="_formItem _formPanel llvierxe" :style="{ backgroundImage: $i.bannerUrl ? `url(${ $i.bannerUrl })` : null }">
+		<div class="_debobigegoItem _debobigegoPanel llvierxe" :style="{ backgroundImage: $i.bannerUrl ? `url(${ $i.bannerUrl })` : null }">
 			<MkAvatar class="avatar" :user="$i"/>
 		</div>
 		<FormButton @click="changeAvatar" primary>{{ $ts._profile.changeAvatar }}</FormButton>
 		<FormButton @click="changeBanner" primary>{{ $ts._profile.changeBanner }}</FormButton>
 	</FormGroup>
 
-	<FormInput v-model:value="name" :max="30" manual-save>
+	<FormInput v-model="name" :max="30" manual-save>
 		<span>{{ $ts._profile.name }}</span>
 	</FormInput>
 
-	<FormTextarea v-model:value="description" :max="500" tall manual-save>
+	<FormTextarea v-model="description" :max="500" tall manual-save>
 		<span>{{ $ts._profile.description }}</span>
 		<template #desc>{{ $ts._profile.youCanIncludeHashtags }}</template>
 	</FormTextarea>
 
-	<FormInput v-model:value="location" manual-save>
+	<FormInput v-model="location" manual-save>
 		<span>{{ $ts.location }}</span>
 		<template #prefix><i class="fas fa-map-marker-alt"></i></template>
 	</FormInput>
 
-	<FormInput v-model:value="birthday" type="date" manual-save>
+	<FormInput v-model="birthday" type="date" manual-save>
 		<span>{{ $ts.birthday }}</span>
 		<template #prefix><i class="fas fa-birthday-cake"></i></template>
 	</FormInput>
 
-	<FormSelect v-model:value="lang">
+	<FormSelect v-model="lang">
 		<template #label>{{ $ts.language }}</template>
 		<option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</option>
 	</FormSelect>
@@ -37,23 +37,23 @@
 		<template #caption>{{ $ts._profile.metadataDescription }}</template>
 	</FormGroup>
 
-	<FormSwitch v-model:value="isCat">{{ $ts.flagAsCat }}<template #desc>{{ $ts.flagAsCatDescription }}</template></FormSwitch>
+	<FormSwitch v-model="isCat">{{ $ts.flagAsCat }}<template #desc>{{ $ts.flagAsCatDescription }}</template></FormSwitch>
 
-	<FormSwitch v-model:value="isBot">{{ $ts.flagAsBot }}<template #desc>{{ $ts.flagAsBotDescription }}</template></FormSwitch>
+	<FormSwitch v-model="isBot">{{ $ts.flagAsBot }}<template #desc>{{ $ts.flagAsBotDescription }}</template></FormSwitch>
 
-	<FormSwitch v-model:value="alwaysMarkNsfw">{{ $ts.alwaysMarkSensitive }}</FormSwitch>
+	<FormSwitch v-model="alwaysMarkNsfw">{{ $ts.alwaysMarkSensitive }}</FormSwitch>
 </FormBase>
 </template>
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormButton from '@client/components/form/button.vue';
-import FormInput from '@client/components/form/input.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormSelect from '@client/components/form/select.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormSelect from '@client/components/debobigego/select.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import { host, langs } from '@client/config';
 import { selectFile } from '@client/scripts/select-file';
 import * as os from '@client/os';
@@ -76,7 +76,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.profile,
-				icon: 'fas fa-user'
+				icon: 'fas fa-user',
+				bg: 'var(--bg)'
 			},
 			host,
 			langs,
diff --git a/src/client/pages/settings/reaction.vue b/src/client/pages/settings/reaction.vue
index a0024234e4..a5ff46097d 100644
--- a/src/client/pages/settings/reaction.vue
+++ b/src/client/pages/settings/reaction.vue
@@ -1,8 +1,8 @@
 <template>
 <FormBase>
-	<div class="_formItem">
-		<div class="_formLabel">{{ $ts.reactionSettingDescription }}</div>
-		<div class="_formPanel">
+	<div class="_debobigegoItem">
+		<div class="_debobigegoLabel">{{ $ts.reactionSettingDescription }}</div>
+		<div class="_debobigegoPanel">
 			<XDraggable class="zoaiodol" v-model="reactions" :item-key="item => item" animation="150" delay="100" delay-on-touch-only="true">
 				<template #item="{element}">
 					<button class="_button item" @click="remove(element, $event)">
@@ -14,7 +14,7 @@
 				</template>
 			</XDraggable>
 		</div>
-		<div class="_formCaption">{{ $ts.reactionSettingDescription2 }} <button class="_textButton" @click="preview">{{ $ts.preview }}</button></div>
+		<div class="_debobigegoCaption">{{ $ts.reactionSettingDescription2 }} <button class="_textButton" @click="preview">{{ $ts.preview }}</button></div>
 	</div>
 
 	<FormRadios v-model="reactionPickerWidth">
@@ -37,10 +37,10 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import XDraggable from 'vuedraggable';
-import FormInput from '@client/components/form/input.vue';
-import FormRadios from '@client/components/form/radios.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormInput from '@client/components/debobigego/input.vue';
+import FormRadios from '@client/components/debobigego/radios.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import * as os from '@client/os';
 import { defaultStore } from '@client/store';
 import * as symbols from '@client/symbols';
@@ -64,7 +64,8 @@ export default defineComponent({
 				action: {
 					icon: 'fas fa-eye',
 					handler: this.preview
-				}
+				},
+				bg: 'var(--bg)',
 			},
 			reactions: JSON.parse(JSON.stringify(this.$store.state.reactions)),
 		}
diff --git a/src/client/pages/settings/registry.keys.vue b/src/client/pages/settings/registry.keys.vue
index f71589ba4f..d99002e50f 100644
--- a/src/client/pages/settings/registry.keys.vue
+++ b/src/client/pages/settings/registry.keys.vue
@@ -25,11 +25,11 @@ import { defineAsyncComponent, defineComponent } from 'vue';
 import * as JSON5 from 'json5';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -56,7 +56,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.registry,
-				icon: 'fas fa-cogs'
+				icon: 'fas fa-cogs',
+				bg: 'var(--bg)',
 			},
 			keys: null,
 		}
diff --git a/src/client/pages/settings/registry.value.vue b/src/client/pages/settings/registry.value.vue
index 48245ae99f..06be5737e9 100644
--- a/src/client/pages/settings/registry.value.vue
+++ b/src/client/pages/settings/registry.value.vue
@@ -19,7 +19,7 @@
 		</FormGroup>
 
 		<FormGroup>
-			<FormTextarea tall v-model:value="valueForEditor" class="_monospace" style="tab-size: 2;">
+			<FormTextarea tall v-model="valueForEditor" class="_monospace" style="tab-size: 2;">
 				<span>{{ $ts.value }} (JSON)</span>
 			</FormTextarea>
 			<FormButton @click="save" primary><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
@@ -38,14 +38,14 @@
 <script lang="ts">
 import { defineAsyncComponent, defineComponent } from 'vue';
 import * as JSON5 from 'json5';
-import FormInfo from '@client/components/form/info.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
 import FormTextarea from '@client/components/form/textarea.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -76,7 +76,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.registry,
-				icon: 'fas fa-cogs'
+				icon: 'fas fa-cogs',
+				bg: 'var(--bg)',
 			},
 			value: null,
 			valueForEditor: null,
diff --git a/src/client/pages/settings/registry.vue b/src/client/pages/settings/registry.vue
index 5ba1bc751b..e4fb230d5c 100644
--- a/src/client/pages/settings/registry.vue
+++ b/src/client/pages/settings/registry.vue
@@ -13,11 +13,11 @@ import { defineAsyncComponent, defineComponent } from 'vue';
 import * as JSON5 from 'json5';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -38,7 +38,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.registry,
-				icon: 'fas fa-cogs'
+				icon: 'fas fa-cogs',
+				bg: 'var(--bg)',
 			},
 			scopes: null,
 		}
diff --git a/src/client/pages/settings/security.vue b/src/client/pages/settings/security.vue
index b70fa5a9f3..e051685a82 100644
--- a/src/client/pages/settings/security.vue
+++ b/src/client/pages/settings/security.vue
@@ -6,7 +6,7 @@
 	<FormPagination :pagination="pagination">
 		<template #label>{{ $ts.signinHistory }}</template>
 		<template #default="{items}">
-			<div class="_formPanel timnmucd" v-for="item in items" :key="item.id">
+			<div class="_debobigegoPanel timnmucd" v-for="item in items" :key="item.id">
 				<header>
 					<i v-if="item.success" class="fas fa-check icon succ"></i>
 					<i v-else class="fas fa-times-circle icon fail"></i>
@@ -25,11 +25,11 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormBase from '@client/components/form/base.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormPagination from '@client/components/form/pagination.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormPagination from '@client/components/debobigego/pagination.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
@@ -48,7 +48,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.security,
-				icon: 'fas fa-lock'
+				icon: 'fas fa-lock',
+				bg: 'var(--bg)',
 			},
 			pagination: {
 				endpoint: 'i/signin-history',
diff --git a/src/client/pages/settings/sounds.vue b/src/client/pages/settings/sounds.vue
index 1c51685ce8..07310619c8 100644
--- a/src/client/pages/settings/sounds.vue
+++ b/src/client/pages/settings/sounds.vue
@@ -1,6 +1,6 @@
 <template>
 <FormBase>
-	<FormRange v-model:value="masterVolume" :min="0" :max="1" :step="0.05">
+	<FormRange v-model="masterVolume" :min="0" :max="1" :step="0.05">
 		<template #label><i class="fas fa-volume-icon"></i> {{ $ts.masterVolume }}</template>
 	</FormRange>
 
@@ -19,11 +19,11 @@
 
 <script lang="ts">
 import { defineComponent } from 'vue';
-import FormRange from '@client/components/form/range.vue';
-import FormSelect from '@client/components/form/select.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormRange from '@client/components/debobigego/range.vue';
+import FormSelect from '@client/components/debobigego/select.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import * as os from '@client/os';
 import { ColdDeviceStorage } from '@client/store';
 import { playFile } from '@client/scripts/sound';
@@ -71,7 +71,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.sounds,
-				icon: 'fas fa-music'
+				icon: 'fas fa-music',
+				bg: 'var(--bg)',
 			},
 			sounds: {},
 		}
diff --git a/src/client/pages/settings/theme.install.vue b/src/client/pages/settings/theme.install.vue
index d719cc801f..9fbb28929d 100644
--- a/src/client/pages/settings/theme.install.vue
+++ b/src/client/pages/settings/theme.install.vue
@@ -1,7 +1,7 @@
 <template>
 <FormBase>
 	<FormGroup>
-		<FormTextarea v-model:value="installThemeCode">
+		<FormTextarea v-model="installThemeCode">
 			<span>{{ $ts._theme.code }}</span>
 		</FormTextarea>
 		<FormButton @click="() => preview(installThemeCode)" :disabled="installThemeCode == null" inline><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
@@ -17,10 +17,10 @@ import * as JSON5 from 'json5';
 import FormTextarea from '@client/components/form/textarea.vue';
 import FormSelect from '@client/components/form/select.vue';
 import FormRadios from '@client/components/form/radios.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import { applyTheme, validateTheme } from '@client/scripts/theme';
 import * as os from '@client/os';
 import { ColdDeviceStorage } from '@client/store';
@@ -44,7 +44,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts._theme.install,
-				icon: 'fas fa-download'
+				icon: 'fas fa-download',
+				bg: 'var(--bg)',
 			},
 			installThemeCode: null,
 		}
diff --git a/src/client/pages/settings/theme.manage.vue b/src/client/pages/settings/theme.manage.vue
index 7cc7a0169a..da21a47a50 100644
--- a/src/client/pages/settings/theme.manage.vue
+++ b/src/client/pages/settings/theme.manage.vue
@@ -1,6 +1,6 @@
 <template>
 <FormBase>
-	<FormSelect v-model:value="selectedThemeId">
+	<FormSelect v-model="selectedThemeId">
 		<template #label>{{ $ts.theme }}</template>
 		<optgroup :label="$ts._theme.installedThemes">
 			<option v-for="x in installedThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
@@ -31,10 +31,10 @@ import * as JSON5 from 'json5';
 import FormTextarea from '@client/components/form/textarea.vue';
 import FormSelect from '@client/components/form/select.vue';
 import FormRadios from '@client/components/form/radios.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 import FormInput from '@client/components/form/input.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import { Theme, builtinThemes } from '@client/scripts/theme';
 import copyToClipboard from '@client/scripts/copy-to-clipboard';
 import * as os from '@client/os';
@@ -59,7 +59,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts._theme.manage,
-				icon: 'fas fa-folder-open'
+				icon: 'fas fa-folder-open',
+				bg: 'var(--bg)',
 			},
 			installedThemes: getThemes(),
 			builtinThemes,
diff --git a/src/client/pages/settings/theme.vue b/src/client/pages/settings/theme.vue
index 94eddb1b6f..c6be42251c 100644
--- a/src/client/pages/settings/theme.vue
+++ b/src/client/pages/settings/theme.vue
@@ -1,7 +1,7 @@
 <template>
 <FormBase>
 	<FormGroup>
-		<div class="rfqxtzch _formItem _formPanel">
+		<div class="rfqxtzch _debobigegoItem _debobigegoPanel">
 			<div class="darkMode">
 				<div class="toggleWrapper">
 					<input type="checkbox" class="dn" id="dn" v-model="darkMode"/>
@@ -23,11 +23,11 @@
 				</div>
 			</div>
 		</div>
-		<FormSwitch v-model:value="syncDeviceDarkMode">{{ $ts.syncDeviceDarkMode }}</FormSwitch>
+		<FormSwitch v-model="syncDeviceDarkMode">{{ $ts.syncDeviceDarkMode }}</FormSwitch>
 	</FormGroup>
 
 	<template v-if="darkMode">
-		<FormSelect v-model:value="darkThemeId">
+		<FormSelect v-model="darkThemeId">
 			<template #label>{{ $ts.themeForDarkMode }}</template>
 			<optgroup :label="$ts.darkThemes">
 				<option v-for="x in darkThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
@@ -36,7 +36,7 @@
 				<option v-for="x in lightThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
 			</optgroup>
 		</FormSelect>
-		<FormSelect v-model:value="lightThemeId">
+		<FormSelect v-model="lightThemeId">
 			<template #label>{{ $ts.themeForLightMode }}</template>
 			<optgroup :label="$ts.lightThemes">
 				<option v-for="x in lightThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
@@ -47,7 +47,7 @@
 		</FormSelect>
 	</template>
 	<template v-else>
-		<FormSelect v-model:value="lightThemeId">
+		<FormSelect v-model="lightThemeId">
 			<template #label>{{ $ts.themeForLightMode }}</template>
 			<optgroup :label="$ts.lightThemes">
 				<option v-for="x in lightThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
@@ -56,7 +56,7 @@
 				<option v-for="x in darkThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
 			</optgroup>
 		</FormSelect>
-		<FormSelect v-model:value="darkThemeId">
+		<FormSelect v-model="darkThemeId">
 			<template #label>{{ $ts.themeForDarkMode }}</template>
 			<optgroup :label="$ts.darkThemes">
 				<option v-for="x in darkThemes" :value="x.id" :key="x.id">{{ x.name }}</option>
@@ -86,12 +86,12 @@
 
 <script lang="ts">
 import { computed, defineComponent, onActivated, onMounted, ref, watch } from 'vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormSelect from '@client/components/form/select.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormButton from '@client/components/form/button.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormSelect from '@client/components/debobigego/select.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormButton from '@client/components/debobigego/button.vue';
 import { builtinThemes } from '@client/scripts/theme';
 import { selectFile } from '@client/scripts/select-file';
 import { isDeviceDarkmode } from '@client/scripts/is-device-darkmode';
@@ -116,7 +116,8 @@ export default defineComponent({
 	setup(props, { emit }) {
 		const INFO = {
 			title: i18n.locale.theme,
-			icon: 'fas fa-palette'
+			icon: 'fas fa-palette',
+				bg: 'var(--bg)',
 		};
 
 		const installedThemes = ref(getThemes());
diff --git a/src/client/pages/settings/update.vue b/src/client/pages/settings/update.vue
index 8000327d0c..8bc459e936 100644
--- a/src/client/pages/settings/update.vue
+++ b/src/client/pages/settings/update.vue
@@ -32,12 +32,12 @@
 import { defineAsyncComponent, defineComponent } from 'vue';
 import FormSwitch from '@client/components/form/switch.vue';
 import FormSelect from '@client/components/form/select.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormInfo from '@client/components/form/info.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
 import * as os from '@client/os';
 import { version, instanceName } from '@client/config';
 import * as symbols from '@client/symbols';
@@ -60,7 +60,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: 'Misskey Update',
-				icon: 'fas fa-sync-alt'
+				icon: 'fas fa-sync-alt',
+				bg: 'var(--bg)',
 			},
 			version,
 			instanceName,
diff --git a/src/client/pages/settings/word-mute.vue b/src/client/pages/settings/word-mute.vue
index fe3fece844..53948b1b1e 100644
--- a/src/client/pages/settings/word-mute.vue
+++ b/src/client/pages/settings/word-mute.vue
@@ -1,21 +1,21 @@
 <template>
 <div>
-	<MkTab v-model:value="tab">
+	<MkTab v-model="tab">
 		<option value="soft">{{ $ts._wordMute.soft }}</option>
 		<option value="hard">{{ $ts._wordMute.hard }}</option>
 	</MkTab>
 	<FormBase>
-		<div class="_formItem">
+		<div class="_debobigegoItem">
 			<div v-show="tab === 'soft'">
 				<FormInfo>{{ $ts._wordMute.softDescription }}</FormInfo>
-				<FormTextarea v-model:value="softMutedWords">
+				<FormTextarea v-model="softMutedWords">
 					<span>{{ $ts._wordMute.muteWords }}</span>
 					<template #desc>{{ $ts._wordMute.muteWordsDescription }}<br>{{ $ts._wordMute.muteWordsDescription2 }}</template>
 				</FormTextarea>
 			</div>
 			<div v-show="tab === 'hard'">
 				<FormInfo>{{ $ts._wordMute.hardDescription }}</FormInfo>
-				<FormTextarea v-model:value="hardMutedWords">
+				<FormTextarea v-model="hardMutedWords">
 					<span>{{ $ts._wordMute.muteWords }}</span>
 					<template #desc>{{ $ts._wordMute.muteWordsDescription }}<br>{{ $ts._wordMute.muteWordsDescription2 }}</template>
 				</FormTextarea>
@@ -33,10 +33,10 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import FormTextarea from '@client/components/form/textarea.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormInfo from '@client/components/form/info.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormInfo from '@client/components/debobigego/info.vue';
 import MkTab from '@client/components/tab.vue';
 import * as os from '@client/os';
 import number from '@client/filters/number';
@@ -58,7 +58,8 @@ export default defineComponent({
 		return {
 			[symbols.PAGE_INFO]: {
 				title: this.$ts.wordMute,
-				icon: 'fas fa-comment-slash'
+				icon: 'fas fa-comment-slash',
+				bg: 'var(--bg)',
 			},
 			tab: 'soft',
 			softMutedWords: '',
diff --git a/src/client/pages/test.vue b/src/client/pages/test.vue
index 131571e9dd..fbab0112ed 100644
--- a/src/client/pages/test.vue
+++ b/src/client/pages/test.vue
@@ -133,10 +133,10 @@
 <script lang="ts">
 import { defineComponent, defineAsyncComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
-import MkSwitch from '@client/components/ui/switch.vue';
-import MkTextarea from '@client/components/ui/textarea.vue';
-import MkRadio from '@client/components/ui/radio.vue';
+import MkInput from '@client/components/form/input.vue';
+import MkSwitch from '@client/components/form/switch.vue';
+import MkTextarea from '@client/components/form/textarea.vue';
+import MkRadio from '@client/components/form/radio.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
 
diff --git a/src/client/pages/theme-editor.vue b/src/client/pages/theme-editor.vue
index ce8bae4ff5..3b10396ab8 100644
--- a/src/client/pages/theme-editor.vue
+++ b/src/client/pages/theme-editor.vue
@@ -1,8 +1,8 @@
 <template>
 <FormBase class="cwepdizn">
-	<div class="_formItem colorPicker">
-		<div class="_formLabel">{{ $ts.backgroundColor }}</div>
-		<div class="_formPanel colors">
+	<div class="_debobigegoItem colorPicker">
+		<div class="_debobigegoLabel">{{ $ts.backgroundColor }}</div>
+		<div class="_debobigegoPanel colors">
 			<div class="row">
 				<button v-for="color in bgColors.filter(x => x.kind === 'light')" :key="color.color" @click="setBgColor(color)" class="color _button" :class="{ active: theme.props.bg === color.color }">
 					<div class="preview" :style="{ background: color.forPreview }"></div>
@@ -15,9 +15,9 @@
 			</div>
 		</div>
 	</div>
-	<div class="_formItem colorPicker">
-		<div class="_formLabel">{{ $ts.accentColor }}</div>
-		<div class="_formPanel colors">
+	<div class="_debobigegoItem colorPicker">
+		<div class="_debobigegoLabel">{{ $ts.accentColor }}</div>
+		<div class="_debobigegoPanel colors">
 			<div class="row">
 				<button v-for="color in accentColors" :key="color" @click="setAccentColor(color)" class="color rounded _button" :class="{ active: theme.props.accent === color }">
 					<div class="preview" :style="{ background: color }"></div>
@@ -25,9 +25,9 @@
 			</div>
 		</div>
 	</div>
-	<div class="_formItem colorPicker">
-		<div class="_formLabel">{{ $ts.textColor }}</div>
-		<div class="_formPanel colors">
+	<div class="_debobigegoItem colorPicker">
+		<div class="_debobigegoLabel">{{ $ts.textColor }}</div>
+		<div class="_debobigegoPanel colors">
 			<div class="row">
 				<button v-for="color in fgColors" :key="color" @click="setFgColor(color)" class="color char _button" :class="{ active: (theme.props.fg === color.forLight) || (theme.props.fg === color.forDark) }">
 					<div class="preview" :style="{ color: color.forPreview ? color.forPreview : theme.base === 'light' ? '#5f5f5f' : '#dadada' }">A</div>
@@ -37,7 +37,7 @@
 	</div>
 
 	<FormGroup v-if="codeEnabled">
-		<FormTextarea v-model:value="themeCode" tall>
+		<FormTextarea v-model="themeCode" tall>
 			<span>{{ $ts._theme.code }}</span>
 		</FormTextarea>
 		<FormButton @click="applyThemeCode" primary>{{ $ts.apply }}</FormButton>
@@ -45,7 +45,7 @@
 	<FormButton v-else @click="codeEnabled = true"><i class="fas fa-code"></i> {{ $ts.editCode }}</FormButton>
 
 	<FormGroup v-if="descriptionEnabled">
-		<FormTextarea v-model:value="description">
+		<FormTextarea v-model="description">
 			<span>{{ $ts._theme.description }}</span>
 		</FormTextarea>
 	</FormGroup>
@@ -65,10 +65,10 @@ import * as tinycolor from 'tinycolor2';
 import { v4 as uuid} from 'uuid';
 import * as JSON5 from 'json5';
 
-import FormBase from '@client/components/form/base.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormGroup from '@client/components/form/group.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
 
 import { Theme, applyTheme, validateTheme, darkTheme, lightTheme } from '@client/scripts/theme';
 import { host } from '@client/config';
diff --git a/src/client/pages/user-ap-info.vue b/src/client/pages/user-ap-info.vue
index c08a352571..cbdff874ed 100644
--- a/src/client/pages/user-ap-info.vue
+++ b/src/client/pages/user-ap-info.vue
@@ -58,14 +58,14 @@
 
 <script lang="ts">
 import { defineAsyncComponent, defineComponent } from 'vue';
-import FormObjectView from '@client/components/form/object-view.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormObjectView from '@client/components/debobigego/object-view.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import number from '@client/filters/number';
 import bytes from '@client/filters/bytes';
diff --git a/src/client/pages/user-info.vue b/src/client/pages/user-info.vue
index 503982652b..bf67fc853a 100644
--- a/src/client/pages/user-info.vue
+++ b/src/client/pages/user-info.vue
@@ -1,7 +1,7 @@
 <template>
 <FormBase>
 	<FormSuspense :p="init">
-		<div class="_formItem aeakzknw">
+		<div class="_debobigegoItem aeakzknw">
 			<MkAvatar class="avatar" :user="user" :show-indicator="true"/>
 		</div>
 
@@ -20,9 +20,9 @@
 		</FormGroup>
 
 		<FormGroup v-if="iAmModerator">
-			<FormSwitch v-if="user.host == null && $i.isAdmin && (moderator || !user.isAdmin)" @update:value="toggleModerator" v-model:value="moderator">{{ $ts.moderator }}</FormSwitch>
-			<FormSwitch @update:value="toggleSilence" v-model:value="silenced">{{ $ts.silence }}</FormSwitch>
-			<FormSwitch @update:value="toggleSuspend" v-model:value="suspended">{{ $ts.suspend }}</FormSwitch>
+			<FormSwitch v-if="user.host == null && $i.isAdmin && (moderator || !user.isAdmin)" @update:modelValue="toggleModerator" v-model="moderator">{{ $ts.moderator }}</FormSwitch>
+			<FormSwitch @update:modelValue="toggleSilence" v-model="silenced">{{ $ts.silence }}</FormSwitch>
+			<FormSwitch @update:modelValue="toggleSuspend" v-model="suspended">{{ $ts.suspend }}</FormSwitch>
 		</FormGroup>
 
 		<FormGroup>
@@ -56,15 +56,15 @@
 
 <script lang="ts">
 import { computed, defineAsyncComponent, defineComponent } from 'vue';
-import FormObjectView from '@client/components/form/object-view.vue';
-import FormTextarea from '@client/components/form/textarea.vue';
-import FormSwitch from '@client/components/form/switch.vue';
-import FormLink from '@client/components/form/link.vue';
-import FormBase from '@client/components/form/base.vue';
-import FormGroup from '@client/components/form/group.vue';
-import FormButton from '@client/components/form/button.vue';
-import FormKeyValueView from '@client/components/form/key-value-view.vue';
-import FormSuspense from '@client/components/form/suspense.vue';
+import FormObjectView from '@client/components/debobigego/object-view.vue';
+import FormTextarea from '@client/components/debobigego/textarea.vue';
+import FormSwitch from '@client/components/debobigego/switch.vue';
+import FormLink from '@client/components/debobigego/link.vue';
+import FormBase from '@client/components/debobigego/base.vue';
+import FormGroup from '@client/components/debobigego/group.vue';
+import FormButton from '@client/components/debobigego/button.vue';
+import FormKeyValueView from '@client/components/debobigego/key-value-view.vue';
+import FormSuspense from '@client/components/debobigego/suspense.vue';
 import * as os from '@client/os';
 import number from '@client/filters/number';
 import bytes from '@client/filters/bytes';
diff --git a/src/client/pages/user/index.timeline.vue b/src/client/pages/user/index.timeline.vue
index 287e6c8b22..8796ded469 100644
--- a/src/client/pages/user/index.timeline.vue
+++ b/src/client/pages/user/index.timeline.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="yrzkoczt" v-sticky-container>
-	<MkTab v-model:value="with_" class="_gap tab">
+	<MkTab v-model="with_" class="_gap tab">
 		<option :value="null">{{ $ts.notes }}</option>
 		<option value="replies">{{ $ts.notesAndReplies }}</option>
 		<option value="files">{{ $ts.withFiles }}</option>
diff --git a/src/client/pages/welcome.setup.vue b/src/client/pages/welcome.setup.vue
index d0091bef67..dfefecc8fa 100644
--- a/src/client/pages/welcome.setup.vue
+++ b/src/client/pages/welcome.setup.vue
@@ -24,7 +24,7 @@
 <script lang="ts">
 import { defineComponent } from 'vue';
 import MkButton from '@client/components/ui/button.vue';
-import MkInput from '@client/components/ui/input.vue';
+import MkInput from '@client/components/form/input.vue';
 import { host } from '@client/config';
 import * as os from '@client/os';
 import { login } from '@client/account';
diff --git a/src/client/style.scss b/src/client/style.scss
index 0318013f60..5b55ab8caf 100644
--- a/src/client/style.scss
+++ b/src/client/style.scss
@@ -425,12 +425,18 @@ hr {
 	}
 }
 
-._inputNoTopMargin {
-	margin-top: 0 !important;
+._formBlock {
+	margin: 20px 0;
 }
 
-._inputNoBottomMargin {
-	margin-bottom: 0 !important;
+._formRoot {
+	> ._formBlock:first-child {
+		margin-top: 0;
+	}
+
+	> ._formBlock:last-child {
+		margin-bottom: 0;
+	}
 }
 
 ._table {
diff --git a/src/client/ui/_common_/sidebar.vue b/src/client/ui/_common_/sidebar.vue
index 9817a46e30..4bb7bbd985 100644
--- a/src/client/ui/_common_/sidebar.vue
+++ b/src/client/ui/_common_/sidebar.vue
@@ -395,7 +395,7 @@ export default defineComponent({
 						left: 0;
 						right: 0;
 						bottom: 0;
-						border-radius: 8px;
+						border-radius: 999px;
 						background: var(--accentedBg);
 					}
 				}
diff --git a/src/client/ui/chat/note-preview.vue b/src/client/ui/chat/note-preview.vue
index 77949e314b..beb38de644 100644
--- a/src/client/ui/chat/note-preview.vue
+++ b/src/client/ui/chat/note-preview.vue
@@ -6,7 +6,7 @@
 		<div class="body">
 			<p v-if="note.cw != null" class="cw">
 				<span class="text" v-if="note.cw != ''">{{ note.cw }}</span>
-				<XCwButton v-model:value="showContent" :note="note"/>
+				<XCwButton v-model="showContent" :note="note"/>
 			</p>
 			<div class="content" v-show="note.cw == null || showContent">
 				<XSubNote-content class="text" :note="note"/>
diff --git a/src/client/ui/chat/note.sub.vue b/src/client/ui/chat/note.sub.vue
index bb528dd936..a284ba2bf4 100644
--- a/src/client/ui/chat/note.sub.vue
+++ b/src/client/ui/chat/note.sub.vue
@@ -7,7 +7,7 @@
 			<div class="body">
 				<p v-if="note.cw != null" class="cw">
 					<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis" />
-					<XCwButton v-model:value="showContent" :note="note"/>
+					<XCwButton v-model="showContent" :note="note"/>
 				</p>
 				<div class="content" v-show="note.cw == null || showContent">
 					<XSubNote-content class="text" :note="note"/>
diff --git a/src/client/ui/chat/note.vue b/src/client/ui/chat/note.vue
index 6d2b9bbf54..26d44d26aa 100644
--- a/src/client/ui/chat/note.vue
+++ b/src/client/ui/chat/note.vue
@@ -42,7 +42,7 @@
 			<div class="body">
 				<p v-if="appearNote.cw != null" class="cw">
 					<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
-					<XCwButton v-model:value="showContent" :note="appearNote"/>
+					<XCwButton v-model="showContent" :note="appearNote"/>
 				</p>
 				<div class="content" :class="{ collapsed }" v-show="appearNote.cw == null || showContent">
 					<div class="text">
diff --git a/yarn.lock b/yarn.lock
index 61c052c995..fb6a3bbda0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1244,95 +1244,95 @@
   resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44"
   integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==
 
-"@vue/compiler-core@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.13.tgz#901268088b98a53c43be0f02bfa0e3a389ad6bf4"
-  integrity sha512-H8MUuKVCfAT6C0vth/+1LAriKnM+RTFo/5MoFycwRPwworTvkpWq/EuGoIXdLBblo8Y2/bNsOmIBEEoOtrb/bQ==
+"@vue/compiler-core@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.19.tgz#b537dd377ce51fdb64e9b30ebfbff7cd70a64cb9"
+  integrity sha512-8dOPX0YOtaXol0Zf2cfLQ4NU/yHYl2H7DCKsLEZ7gdvPK6ZSEwGLJ7IdghhY2YEshEpC5RB9QKdC5I07z8Dtjg==
   dependencies:
     "@babel/parser" "^7.15.0"
-    "@vue/shared" "3.2.13"
+    "@vue/shared" "3.2.19"
     estree-walker "^2.0.2"
     source-map "^0.6.1"
 
-"@vue/compiler-dom@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.13.tgz#028982494fb9d97807d5275b42355732686f8ed7"
-  integrity sha512-5+2dYgQyNzM97EEgbdAusUpLjulcKkvLM26jOGpd14+qwEcW/KCnns5DGjlZD/tsdEwToOoTDCm+mjx7cO/G1Q==
+"@vue/compiler-dom@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.19.tgz#0607bc90de6af55fde73b09b3c4d0bf8cb597ed8"
+  integrity sha512-WzQoE8rfkFjPtIioc7SSgTsnz9g2oG61DU8KHnzPrRS7fW/lji6H2uCYJfp4Z6kZE8GjnHc1Ljwl3/gxDes0cw==
   dependencies:
-    "@vue/compiler-core" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/compiler-core" "3.2.19"
+    "@vue/shared" "3.2.19"
 
-"@vue/compiler-sfc@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.13.tgz#a38475048aad9c96cf04dfe635129b417e0f9295"
-  integrity sha512-3j970d969aOILykcTstdihP33xH1Onm0wsvcl+rGv9AGxivB9xicRxBw93HCIA4dAPivr42WjHEoci9q2/85uw==
+"@vue/compiler-sfc@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.19.tgz#d412195a98ebd49b84602f171719294a1d9549be"
+  integrity sha512-pLlbgkO1UHTO02MSpa/sFOXUwIDxSMiKZ1ozE5n71CY4DM+YmI+G3gT/ZHZ46WBId7f3VTF/D8pGwMygcQbrQA==
   dependencies:
     "@babel/parser" "^7.15.0"
-    "@vue/compiler-core" "3.2.13"
-    "@vue/compiler-dom" "3.2.13"
-    "@vue/compiler-ssr" "3.2.13"
-    "@vue/ref-transform" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/compiler-core" "3.2.19"
+    "@vue/compiler-dom" "3.2.19"
+    "@vue/compiler-ssr" "3.2.19"
+    "@vue/ref-transform" "3.2.19"
+    "@vue/shared" "3.2.19"
     estree-walker "^2.0.2"
     magic-string "^0.25.7"
     postcss "^8.1.10"
     source-map "^0.6.1"
 
-"@vue/compiler-ssr@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.13.tgz#98434672e0b488c2affa4b0570731d6be5cda187"
-  integrity sha512-ZbO6uDhUWTdKBRguYNEZXj2FU3nh1cudoHBiidbxj9q5J0tVT+j1PSVFAXPq6SquUBdJpa4HvGkQ5kQzv6upXg==
+"@vue/compiler-ssr@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.19.tgz#3e91ecf70f8f961c5f63eacd2139bcdab9a7a07c"
+  integrity sha512-oLon0Cn3O7WEYzzmzZavGoqXH+199LT+smdjBT3Uf3UX4HwDNuBFCmvL0TsqV9SQnIgKvBRbQ7lhbpnd4lqM3w==
   dependencies:
-    "@vue/compiler-dom" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/compiler-dom" "3.2.19"
+    "@vue/shared" "3.2.19"
 
-"@vue/reactivity@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.13.tgz#d269b09aaafef06a91bf3eb98defd41a2c3daf54"
-  integrity sha512-j3ByCiRgrr4uEZpXJM8XowrbYKeNHMHlbmMZE/2QpVzVPIfrQWS2fpLmbchJeMrnwIrzEl+dub3hgwkV4KRn4w==
+"@vue/reactivity@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.19.tgz#fc6e0f0106f295226835cfed5ff5f84d927bea65"
+  integrity sha512-FtachoYs2SnyrWup5UikP54xDX6ZJ1s5VgHcJp4rkGoutU3Ry61jhs+nCX7J64zjX992Mh9gGUC0LqTs8q9vCA==
   dependencies:
-    "@vue/shared" "3.2.13"
+    "@vue/shared" "3.2.19"
 
-"@vue/ref-transform@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.13.tgz#6adfce50d388cc03683d9d2ba58f3a3bde5166f4"
-  integrity sha512-q6GXHZFzXjpx1K3UFRF8fa+xSmD9xV/FjhGzTNnfrryBr8tBUNYgP2f0s5K5N+21Ay7+MlQ1XXMUp8McGvsryQ==
+"@vue/ref-transform@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.19.tgz#cf0f986486bb26838fbd09749e927bab19745600"
+  integrity sha512-03wwUnoIAeKti5IGGx6Vk/HEBJ+zUcm5wrUM3+PQsGf7IYnXTbeIfHHpx4HeSeWhnLAjqZjADQwW8uA4rBmVbg==
   dependencies:
     "@babel/parser" "^7.15.0"
-    "@vue/compiler-core" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/compiler-core" "3.2.19"
+    "@vue/shared" "3.2.19"
     estree-walker "^2.0.2"
     magic-string "^0.25.7"
 
-"@vue/runtime-core@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.13.tgz#8b62f92642e56af71d0d35a9f0065daf6f9eb3fb"
-  integrity sha512-VQedL9Wa7yWMPVDrIkxzLCm6cWCDBoXcXc+jrsOJkqpWhEeA7+zGOsDsHzhLH8aaJD6vdnUR5Cy0EKvoJDqEWQ==
+"@vue/runtime-core@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.19.tgz#807715b7f4728abb84fa4a8efdbe37d8ddb4c6d3"
+  integrity sha512-qArZSWKxWsgKfxk9BelZ32nY0MZ31CAW2kUUyVJyxh4cTfHaXGbjiQB5JgsvKc49ROMNffv9t3/qjasQqAH+RQ==
   dependencies:
-    "@vue/reactivity" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/reactivity" "3.2.19"
+    "@vue/shared" "3.2.19"
 
-"@vue/runtime-dom@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.13.tgz#238f517a75765719f8373409cee853775c636f92"
-  integrity sha512-DVG+ItkrnCOEa9HSrmGBTLwv/gBVYCO8wkm/yv+d5ChoTnyIILxP0oCiZEPJsgWZfUSRPNi5rXozwo7F99MiwQ==
+"@vue/runtime-dom@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.19.tgz#7e8bf645754703e360fa132e4be9113edf2377bb"
+  integrity sha512-hIRboxXwafeHhbZEkZYNV0MiJXPNf4fP0X6hM2TJb0vssz8BKhD9cF92BkRgZztTQevecbhk0gu4uAPJ3dxL9A==
   dependencies:
-    "@vue/runtime-core" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/runtime-core" "3.2.19"
+    "@vue/shared" "3.2.19"
     csstype "^2.6.8"
 
-"@vue/server-renderer@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.13.tgz#b10a564be67eec6721f90b36c3c817c19e6064b4"
-  integrity sha512-KI+JFV+vRb95+Jb6IwRRm4Vhvj8wrJTNs+OlATfqwwIRpBGAyxn/4knDJYzlnUf/mrKAkrbw751mHhi+pEwILQ==
+"@vue/server-renderer@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.19.tgz#870bcec9f7cdaee0c2187a169b6e636ab4362fb1"
+  integrity sha512-A9FNT7fgQJXItwdzWREntAgWKVtKYuXHBKGev/H4+ByTu8vB7gQXGcim01QxaJshdNg4dYuH2tEBZXCNCNx+/w==
   dependencies:
-    "@vue/compiler-ssr" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/compiler-ssr" "3.2.19"
+    "@vue/shared" "3.2.19"
 
-"@vue/shared@3.2.13":
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.13.tgz#c830ef966d7af12598e0ea862a55695ea589cd47"
-  integrity sha512-F/gs3kHQ8Xeo24F6EImOvBiIoYQsBjF9qoLzvk+LHxYN6ZhIDEL1NWrBFYzdFQ7NphjEYd4EvPZ+Qee+WX8P6w==
+"@vue/shared@3.2.19":
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.19.tgz#111ec3da18337d86274446984c49925b1b2b2dd7"
+  integrity sha512-Knqhx7WieLdVgwCAZgTVrDCXZ50uItuecLh9JdLC8O+a5ayaSyIQYveUK3hCRNC7ws5zalHmZwfdLMGaS8r4Ew==
 
 "@webassemblyjs/ast@1.11.0":
   version "1.11.0"
@@ -4091,7 +4091,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
   dependencies:
     once "^1.4.0"
 
-enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.0:
+enhanced-resolve@^5.0.0:
   version "5.8.0"
   resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz#d9deae58f9d3773b6a111a5a46831da5be5c9ac0"
   integrity sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==
@@ -4107,6 +4107,14 @@ enhanced-resolve@^5.7.0:
     graceful-fs "^4.2.4"
     tapable "^2.2.0"
 
+enhanced-resolve@^5.8.3:
+  version "5.8.3"
+  resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0"
+  integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==
+  dependencies:
+    graceful-fs "^4.2.4"
+    tapable "^2.2.0"
+
 enquirer@^2.3.5, enquirer@^2.3.6:
   version "2.3.6"
   resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
@@ -4173,10 +4181,10 @@ es-module-lexer@^0.4.0:
   resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.0.tgz#21f4181cc8b7eee06855f1c59e6087c7bc4f77b0"
   integrity sha512-iuEGihqqhKWFgh72Q/Jtch7V2t/ft8w8IPP2aEN8ArYKO+IWyo6hsi96hCdgyeEDQIV3InhYQ9BlwUFPGXrbEQ==
 
-es-module-lexer@^0.7.1:
-  version "0.7.1"
-  resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.7.1.tgz#c2c8e0f46f2df06274cdaf0dd3f3b33e0a0b267d"
-  integrity sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==
+es-module-lexer@^0.9.0:
+  version "0.9.0"
+  resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.0.tgz#fe4c4621977bc668e285c5f1f70ca3b451095fda"
+  integrity sha512-qU2eN/XHsrl3E4y7mK1wdWnyy5c8gXtCbfP6Xcsemm7fPUR1PIV1JhZfP7ojcN0Fzp69CfrS3u76h2tusvfKiQ==
 
 es-to-primitive@^1.2.1:
   version "1.2.1"
@@ -11521,16 +11529,16 @@ vue-svg-loader@0.17.0-beta.2:
     semver "^7.3.2"
     svgo "^1.3.2"
 
-vue@3.2.13:
-  version "3.2.13"
-  resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.13.tgz#9d1a94fc62dc29ae21a3dd0d8ee24198e421671e"
-  integrity sha512-raTGvLXXTdMxrhQKY1r1YFXZMmjbjTe7QHBW9EU4CgCBhq8DbgyLqgILcSUZmeFyazk5WY7a7xu0VYmHElf4lA==
+vue@3.2.19:
+  version "3.2.19"
+  resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.19.tgz#da2c80a6a0271c7097fee9e31692adfd9d569c8f"
+  integrity sha512-6KAMdIfAtlK+qohTIUE4urwAv4A3YRuo8uAbByApUmiB0CziGAAPs6qVugN6oHPia8YIafHB/37K0O6KZ7sGmA==
   dependencies:
-    "@vue/compiler-dom" "3.2.13"
-    "@vue/compiler-sfc" "3.2.13"
-    "@vue/runtime-dom" "3.2.13"
-    "@vue/server-renderer" "3.2.13"
-    "@vue/shared" "3.2.13"
+    "@vue/compiler-dom" "3.2.19"
+    "@vue/compiler-sfc" "3.2.19"
+    "@vue/runtime-dom" "3.2.19"
+    "@vue/server-renderer" "3.2.19"
+    "@vue/shared" "3.2.19"
 
 vuedraggable@4.0.1:
   version "4.0.1"
@@ -11642,10 +11650,10 @@ webpack-sources@^3.2.0:
   resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d"
   integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw==
 
-webpack@5.53.0:
-  version "5.53.0"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.53.0.tgz#f463cd9c6fc1356ae4b9b7ac911fd1f5b2df86af"
-  integrity sha512-RZ1Z3z3ni44snoWjfWeHFyzvd9HMVYDYC5VXmlYUT6NWgEOWdCNpad5Fve2CzzHoRED7WtsKe+FCyP5Vk4pWiQ==
+webpack@5.54.0:
+  version "5.54.0"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.54.0.tgz#629f0cd14c7a4340af758a3c7cef25c50670ae4d"
+  integrity sha512-MAVKJMsIUotOQKzFOmN8ZkmMlj7BOyjDU6t1lomW9dWOme5WTStzGa3HMLdV1KYD1AiFETGsznL4LMSvj4tukw==
   dependencies:
     "@types/eslint-scope" "^3.7.0"
     "@types/estree" "^0.0.50"
@@ -11656,8 +11664,8 @@ webpack@5.53.0:
     acorn-import-assertions "^1.7.6"
     browserslist "^4.14.5"
     chrome-trace-event "^1.0.2"
-    enhanced-resolve "^5.8.0"
-    es-module-lexer "^0.7.1"
+    enhanced-resolve "^5.8.3"
+    es-module-lexer "^0.9.0"
     eslint-scope "5.1.1"
     events "^3.2.0"
     glob-to-regexp "^0.4.1"