diff --git a/packages/frontend/src/components/MkModalWindow.vue b/packages/frontend/src/components/MkModalWindow.vue
index ad7dc4da11..63c55b904a 100644
--- a/packages/frontend/src/components/MkModalWindow.vue
+++ b/packages/frontend/src/components/MkModalWindow.vue
@@ -1,15 +1,15 @@
 <template>
 <MkModal ref="modal" :prefer-type="'dialog'" @click="onBgClick" @closed="$emit('closed')">
-	<div ref="rootEl" class="ebkgoccj" :style="{ width: `${width}px`, height: `min(${height}px, 100%)` }" @keydown="onKeydown">
-		<div ref="headerEl" class="header">
-			<button v-if="withOkButton" class="_button" @click="$emit('close')"><i class="ti ti-x"></i></button>
-			<span class="title">
+	<div ref="rootEl" :class="$style.root" :style="{ width: `${width}px`, height: `min(${height}px, 100%)` }" @keydown="onKeydown">
+		<div ref="headerEl" :class="$style.header">
+			<button v-if="withOkButton" :class="$style.headerButton" class="_button" @click="$emit('close')"><i class="ti ti-x"></i></button>
+			<span :class="$style.title">
 				<slot name="header"></slot>
 			</span>
-			<button v-if="!withOkButton" class="_button" data-cy-modal-window-close @click="$emit('close')"><i class="ti ti-x"></i></button>
-			<button v-if="withOkButton" class="_button" :disabled="okButtonDisabled" @click="$emit('ok')"><i class="ti ti-check"></i></button>
+			<button v-if="!withOkButton" :class="$style.headerButton" class="_button" data-cy-modal-window-close @click="$emit('close')"><i class="ti ti-x"></i></button>
+			<button v-if="withOkButton" :class="$style.headerButton" class="_button" :disabled="okButtonDisabled" @click="$emit('ok')"><i class="ti ti-check"></i></button>
 		</div>
-		<div class="body">
+		<div :class="$style.body">
 			<slot :width="bodyWidth" :height="bodyHeight"></slot>
 		</div>
 	</div>
@@ -81,8 +81,8 @@ defineExpose({
 });
 </script>
 
-<style lang="scss" scoped>
-.ebkgoccj {
+<style lang="scss" module>
+.root {
 	margin: auto;
 	overflow: hidden;
 	display: flex;
@@ -96,51 +96,52 @@ defineExpose({
 		--root-margin: 16px;
 	}
 
-	> .header {
-		$height: 46px;
-		$height-narrow: 42px;
-		display: flex;
-		flex-shrink: 0;
-		background: var(--windowHeader);
-		-webkit-backdrop-filter: var(--blur, blur(15px));
-		backdrop-filter: var(--blur, blur(15px));
+	--headerHeight: 46px;
+	--headerHeightNarrow: 42px;
+}
 
-		> button {
-			height: $height;
-			width: $height;
+.header {
+	display: flex;
+	flex-shrink: 0;
+	background: var(--windowHeader);
+	-webkit-backdrop-filter: var(--blur, blur(15px));
+	backdrop-filter: var(--blur, blur(15px));
+}
 
-			@media (max-width: 500px) {
-				height: $height-narrow;
-				width: $height-narrow;
-			}
-		}
+.headerButton {
+	height: var(--headerHeight);
+	width: var(--headerHeight);
 
-		> .title {
-			flex: 1;
-			line-height: $height;
-			padding-left: 32px;
-			font-weight: bold;
-			white-space: nowrap;
-			overflow: hidden;
-			text-overflow: ellipsis;
-			pointer-events: none;
-
-			@media (max-width: 500px) {
-				line-height: $height-narrow;
-				padding-left: 16px;
-			}
-		}
-
-		> button + .title {
-			padding-left: 0;
-		}
-	}
-
-	> .body {
-		flex: 1;
-		overflow: auto;
-		background: var(--panel);
-		container-type: size;
+	@media (max-width: 500px) {
+		height: var(--headerHeightNarrow);
+		width: var(--headerHeightNarrow);
 	}
 }
+
+.title {
+	flex: 1;
+	line-height: var(--headerHeight);
+	padding-left: 32px;
+	font-weight: bold;
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	pointer-events: none;
+
+	@media (max-width: 500px) {
+		line-height: var(--headerHeightNarrow);
+		padding-left: 16px;
+	}
+}
+
+.headerButton + .title {
+	padding-left: 0;
+}
+
+.body {
+	flex: 1;
+	overflow: auto;
+	background: var(--panel);
+	container-type: size;
+}
 </style>
diff --git a/packages/frontend/src/components/MkSelect.vue b/packages/frontend/src/components/MkSelect.vue
index 2de890186a..4efb65c287 100644
--- a/packages/frontend/src/components/MkSelect.vue
+++ b/packages/frontend/src/components/MkSelect.vue
@@ -1,13 +1,13 @@
 <template>
-<div class="vblkjoeq">
-	<div class="label" @click="focus"><slot name="label"></slot></div>
-	<div ref="container" class="input" :class="{ inline, disabled, focused }" @mousedown.prevent="show">
-		<div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div>
+<div>
+	<div :class="$style.label" @click="focus"><slot name="label"></slot></div>
+	<div ref="container" :class="[$style.input, { [$style.inline]: inline, [$style.disabled]: disabled, [$style.focused]: focused }]" @mousedown.prevent="show">
+		<div ref="prefixEl" :class="$style.prefix"><slot name="prefix"></slot></div>
 		<select
 			ref="inputEl"
 			v-model="v"
 			v-adaptive-border
-			class="select"
+			:class="$style.inputCore"
 			:disabled="disabled"
 			:required="required"
 			:readonly="readonly"
@@ -18,9 +18,9 @@
 		>
 			<slot></slot>
 		</select>
-		<div ref="suffixEl" class="suffix"><i class="ti ti-chevron-down" :class="[$style.chevron, { [$style.chevronOpening]: opening }]"></i></div>
+		<div ref="suffixEl" :class="$style.suffix"><i class="ti ti-chevron-down" :class="[$style.chevron, { [$style.chevronOpening]: opening }]"></i></div>
 	</div>
-	<div class="caption"><slot name="caption"></slot></div>
+	<div :class="$style.caption"><slot name="caption"></slot></div>
 
 	<MkButton v-if="manualSave && changed" primary @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 </div>
@@ -169,121 +169,116 @@ function show(ev: MouseEvent) {
 }
 </script>
 
-<style lang="scss" scoped>
-.vblkjoeq {
-	> .label {
-		font-size: 0.85em;
-		padding: 0 0 8px 0;
-		user-select: none;
+<style lang="scss" module>
+.label {
+	font-size: 0.85em;
+	padding: 0 0 8px 0;
+	user-select: none;
 
-		&:empty {
-			display: none;
+	&:empty {
+		display: none;
+	}
+}
+
+.caption {
+	font-size: 0.85em;
+	padding: 8px 0 0 0;
+	color: var(--fgTransparentWeak);
+
+	&:empty {
+		display: none;
+	}
+}
+
+.input {
+	position: relative;
+	cursor: pointer;
+
+	&.inline {
+		display: inline-block;
+		margin: 0;
+	}
+
+	&.focused {
+		> .inputCore {
+			border-color: var(--accent) !important;
+			//box-shadow: 0 0 0 4px var(--focus);
 		}
 	}
 
-	> .caption {
-		font-size: 0.85em;
-		padding: 8px 0 0 0;
-		color: var(--fgTransparentWeak);
+	&.disabled {
+		opacity: 0.7;
 
-		&:empty {
-			display: none;
+		&,
+		> .inputCore {
+			cursor: not-allowed !important;
 		}
 	}
 
-	> .input {
-		position: relative;
-		cursor: pointer;
-
-		&:hover {
-			> .select {
-				border-color: var(--inputBorderHover) !important;
-			}
-		}
-
-		> .select {
-			appearance: none;
-			-webkit-appearance: none;
-			display: block;
-			height: v-bind("height + 'px'");
-			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(--panel);
-			border-radius: 6px;
-			outline: none;
-			box-shadow: none;
-			box-sizing: border-box;
-			cursor: pointer;
-			transition: border-color 0.1s ease-out;
-			pointer-events: none;
-			user-select: none;
-		}
-
-		> .prefix,
-		> .suffix {
-			display: flex;
-			align-items: center;
-			position: absolute;
-			z-index: 1;
-			top: 0;
-			padding: 0 12px;
-			font-size: 1em;
-			height: v-bind("height + 'px'");
-			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) !important;
-			}
-		}
-
-		&.disabled {
-			opacity: 0.7;
-
-			&, * {
-				cursor: not-allowed !important;
-			}
+	&:hover {
+		> .inputCore {
+			border-color: var(--inputBorderHover) !important;
 		}
 	}
 }
-</style>
 
-<style lang="scss" module>
+.inputCore {
+	appearance: none;
+	-webkit-appearance: none;
+	display: block;
+	height: v-bind("height + 'px'");
+	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(--panel);
+	border-radius: 6px;
+	outline: none;
+	box-shadow: none;
+	box-sizing: border-box;
+	transition: border-color 0.1s ease-out;
+	cursor: pointer;
+	pointer-events: none;
+	user-select: none;
+}
+
+.prefix,
+.suffix {
+	display: flex;
+	align-items: center;
+	position: absolute;
+	z-index: 1;
+	top: 0;
+	padding: 0 12px;
+	font-size: 1em;
+	height: v-bind("height + 'px'");
+	min-width: 16px;
+	max-width: 150px;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	box-sizing: border-box;
+	pointer-events: none;
+
+	&:empty {
+		display: none;
+	}
+}
+
+.prefix {
+	left: 0;
+	padding-right: 6px;
+}
+
+.suffix {
+	right: 0;
+	padding-left: 6px;
+}
+
 .chevron {
 	transition: transform 0.1s ease-out;
 }