diff --git a/packages/frontend/assets/reversi/put.mp3 b/packages/frontend/assets/reversi/put.mp3
new file mode 100644
index 000000000..baa1b8319
Binary files /dev/null and b/packages/frontend/assets/reversi/put.mp3 differ
diff --git a/packages/frontend/assets/reversi/stone_b.png b/packages/frontend/assets/reversi/stone_b.png
new file mode 100644
index 000000000..9e98455a3
Binary files /dev/null and b/packages/frontend/assets/reversi/stone_b.png differ
diff --git a/packages/frontend/assets/reversi/stone_w.png b/packages/frontend/assets/reversi/stone_w.png
new file mode 100644
index 000000000..f2bee593d
Binary files /dev/null and b/packages/frontend/assets/reversi/stone_w.png differ
diff --git a/packages/frontend/src/pages/reversi/game.board.vue b/packages/frontend/src/pages/reversi/game.board.vue
index bf45fc411..fbe44d016 100644
--- a/packages/frontend/src/pages/reversi/game.board.vue
+++ b/packages/frontend/src/pages/reversi/game.board.vue
@@ -6,7 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 <template>
 <MkSpacer :contentMax="600">
 	<div :class="$style.root" class="_gaps">
-		<header><b><MkA :to="userPage(blackUser)"><MkUserName :user="blackUser"/></MkA></b>({{ i18n.ts._reversi.black }}) vs <b><MkA :to="userPage(whiteUser)"><MkUserName :user="whiteUser"/></MkA></b>({{ i18n.ts._reversi.white }})</header>
+		<div style="display: flex; align-items: center; justify-content: center; gap: 10px;">
+			<span>({{ i18n.ts._reversi.black }})</span>
+			<MkAvatar style="width: 32px; height: 32px;" :user="blackUser" :showIndicator="true"/>
+			<span> vs </span>
+			<MkAvatar style="width: 32px; height: 32px;" :user="whiteUser" :showIndicator="true"/>
+			<span>({{ i18n.ts._reversi.white }})</span>
+		</div>
 
 		<div style="overflow: clip; line-height: 28px;">
 			<div v-if="!iAmPlayer && !game.isEnded && turnUser" class="turn">
@@ -49,8 +55,14 @@ SPDX-License-Identifier: AGPL-3.0-only
 						}]"
 						@click="putStone(i)"
 					>
-						<img v-if="stone === true" style="pointer-events: none; user-select: none; display: block; width: 100%; height: 100%;" :src="blackUser.avatarUrl">
-						<img v-if="stone === false" style="pointer-events: none; user-select: none; display: block; width: 100%; height: 100%;" :src="whiteUser.avatarUrl">
+						<template v-if="useAvatarAsStone">
+							<img v-if="stone === true" :class="$style.boardCellStone" :src="blackUser.avatarUrl"/>
+							<img v-if="stone === false" :class="$style.boardCellStone" :src="whiteUser.avatarUrl"/>
+						</template>
+						<template v-else>
+							<img v-if="stone === true" :class="$style.boardCellStone" src="/client-assets/reversi/stone_b.png"/>
+							<img v-if="stone === false" :class="$style.boardCellStone" src="/client-assets/reversi/stone_w.png"/>
+						</template>
 					</div>
 				</div>
 				<div v-if="showBoardLabels" :class="$style.labelsY">
@@ -62,10 +74,41 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 		</div>
 
-		<div class="status"><b>{{ i18n.tsx._reversi.turnCount({ count: logPos }) }}</b> {{ i18n.ts._reversi.black }}:{{ engine.blackCount }} {{ i18n.ts._reversi.white }}:{{ engine.whiteCount }} {{ i18n.ts._reversi.total }}:{{ engine.blackCount + engine.whiteCount }}</div>
+		<div class="_panel" style="padding: 16px;">
+			<div>
+				<b>{{ i18n.tsx._reversi.turnCount({ count: logPos }) }}</b> {{ i18n.ts._reversi.black }}:{{ engine.blackCount }} {{ i18n.ts._reversi.white }}:{{ engine.whiteCount }} {{ i18n.ts._reversi.total }}:{{ engine.blackCount + engine.whiteCount }}
+			</div>
+			<div>
+				<div style="display: flex; align-items: center;">
+					<span style="margin-right: 8px;">({{ i18n.ts._reversi.black }})</span>
+					<MkAvatar style="width: 32px; height: 32px; margin-right: 8px;" :user="blackUser" :showIndicator="true"/>
+					<MkA :to="userPage(blackUser)"><MkUserName :user="blackUser"/></MkA>
+				</div>
+				<div> vs </div>
+				<div style="display: flex; align-items: center;">
+					<span style="margin-right: 8px;">({{ i18n.ts._reversi.white }})</span>
+					<MkAvatar style="width: 32px; height: 32px; margin-right: 8px;" :user="whiteUser" :showIndicator="true"/>
+					<MkA :to="userPage(whiteUser)"><MkUserName :user="whiteUser"/></MkA>
+				</div>
+			</div>
+			<div>
+				<p v-if="game.isLlotheo">{{ i18n.ts._reversi.isLlotheo }}</p>
+				<p v-if="game.loopedBoard">{{ i18n.ts._reversi.loopedMap }}</p>
+				<p v-if="game.canPutEverywhere">{{ i18n.ts._reversi.canPutEverywhere }}</p>
+			</div>
+		</div>
 
-		<div v-if="!game.isEnded && iAmPlayer" class="_buttonsCenter">
-			<MkButton danger @click="surrender">{{ i18n.ts._reversi.surrender }}</MkButton>
+		<MkFolder>
+			<template #label>{{ i18n.ts.options }}</template>
+			<div class="_gaps_s" style="text-align: left;">
+				<MkSwitch v-model="showBoardLabels">Show labels</MkSwitch>
+				<MkSwitch v-model="useAvatarAsStone">useAvatarAsStone</MkSwitch>
+			</div>
+		</MkFolder>
+
+		<div class="_buttonsCenter">
+			<MkButton v-if="!game.isEnded && iAmPlayer" danger @click="surrender">{{ i18n.ts._reversi.surrender }}</MkButton>
+			<MkButton @click="share">{{ i18n.ts.share }}</MkButton>
 		</div>
 
 		<div v-if="game.isEnded" class="_panel _gaps_s" style="padding: 16px;">
@@ -79,12 +122,6 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<MkButton style="margin: auto;" :disabled="autoplaying" @click="autoplay()"><i class="ti ti-player-play"></i></MkButton>
 		</div>
 
-		<div>
-			<p v-if="game.isLlotheo">{{ i18n.ts._reversi.isLlotheo }}</p>
-			<p v-if="game.loopedBoard">{{ i18n.ts._reversi.loopedMap }}</p>
-			<p v-if="game.canPutEverywhere">{{ i18n.ts._reversi.canPutEverywhere }}</p>
-		</div>
-
 		<MkA v-if="game.isEnded" :to="`/reversi`">
 			<img src="/client-assets/reversi/logo.png" style="display: block; max-width: 100%; width: 200px; margin: auto;"/>
 		</MkA>
@@ -98,12 +135,16 @@ import * as CRC32 from 'crc-32';
 import * as Misskey from 'misskey-js';
 import * as Reversi from 'misskey-reversi';
 import MkButton from '@/components/MkButton.vue';
+import MkFolder from '@/components/MkFolder.vue';
+import MkSwitch from '@/components/MkSwitch.vue';
 import { deepClone } from '@/scripts/clone.js';
 import { useInterval } from '@/scripts/use-interval.js';
 import { signinRequired } from '@/account.js';
 import { i18n } from '@/i18n.js';
 import { misskeyApi } from '@/scripts/misskey-api.js';
 import { userPage } from '@/filters/user.js';
+import * as sound from '@/scripts/sound.js';
+import * as os from '@/os.js';
 
 const $i = signinRequired();
 
@@ -112,7 +153,8 @@ const props = defineProps<{
 	connection: Misskey.ChannelConnection;
 }>();
 
-const showBoardLabels = true;
+const showBoardLabels = ref<boolean>(false);
+const useAvatarAsStone = ref<boolean>(true);
 const autoplaying = ref<boolean>(false);
 const game = ref<Misskey.entities.ReversiGameDetailed>(deepClone(props.game));
 const logPos = ref<number>(game.value.logs.length);
@@ -206,8 +248,10 @@ function putStone(pos) {
 
 	triggerRef(engine);
 
-	// サウンドを再生する
-	//sound.play(myColor.value ? 'reversiPutBlack' : 'reversiPutWhite');
+	sound.playUrl('/client-assets/reversi/put.mp3', {
+		volume: 1,
+		playbackRate: 1,
+	});
 
 	const id = Math.random().toString(36).slice(2);
 	props.connection.send('putStone', {
@@ -232,8 +276,13 @@ function onStreamLog(log: Reversi.Serializer.Log & { id: string | null }) {
 			case 'put': {
 				engine.value.putStone(log.pos);
 				triggerRef(engine);
+
+				sound.playUrl('/client-assets/reversi/put.mp3', {
+					volume: 1,
+					playbackRate: 1,
+				});
+
 				checkEnd();
-				//sound.play(x.color ? 'reversiPutBlack' : 'reversiPutWhite');
 				break;
 			}
 
@@ -281,7 +330,13 @@ function onStreamRescue(_game) {
 	checkEnd();
 }
 
-function surrender() {
+async function surrender() {
+	const { canceled } = await os.confirm({
+		type: 'warning',
+		text: i18n.ts.areYouSure,
+	});
+	if (canceled) return;
+
 	misskeyApi('reversi/surrender', {
 		gameId: game.value.id,
 	});
@@ -317,6 +372,13 @@ function autoplay() {
 	}, 1000);
 }
 
+function share() {
+	os.post({
+		initialText: `#MisskeyReversi ${location.href}`,
+		instant: true,
+	});
+}
+
 onMounted(() => {
 	props.connection.on('log', onStreamLog);
 	props.connection.on('rescue', onStreamRescue);
@@ -341,7 +403,7 @@ $gap: 4px;
 }
 
 .board {
-	width: calc(100% - 16px);
+	width: 100%;
 	max-width: 500px;
 	margin: 0 auto;
 }
@@ -437,4 +499,12 @@ $gap: 4px;
 		border-color: transparent !important;
 	}
 }
+
+.boardCellStone {
+	pointer-events: none;
+	user-select: none;
+	display: block;
+	width: 100%;
+	height: 100%;
+}
 </style>
diff --git a/packages/frontend/src/pages/reversi/index.vue b/packages/frontend/src/pages/reversi/index.vue
index c483e36c2..d33acc95a 100644
--- a/packages/frontend/src/pages/reversi/index.vue
+++ b/packages/frontend/src/pages/reversi/index.vue
@@ -10,9 +10,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<img src="/client-assets/reversi/logo.png" style="display: block; max-width: 100%; max-height: 200px; margin: auto;"/>
 		</div>
 
-		<div class="_buttonsCenter">
-			<MkButton primary gradate rounded @click="matchAny">{{ i18n.ts._reversi.freeMatch }}</MkButton>
-			<MkButton primary gradate rounded @click="matchUser">{{ i18n.ts.invite }}</MkButton>
+		<div class="_panel" style="padding: 16px;">
+			<div class="_buttonsCenter">
+				<MkButton primary gradate rounded @click="matchAny">{{ i18n.ts._reversi.freeMatch }}</MkButton>
+				<MkButton primary gradate rounded @click="matchUser">{{ i18n.ts.invite }}</MkButton>
+			</div>
 		</div>
 
 		<MkFolder v-if="invitations.length > 0" :defaultOpen="true">
@@ -28,12 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 		<MkFolder v-if="$i" :defaultOpen="true">
 			<template #label>{{ i18n.ts._reversi.myGames }}</template>
-			<MkPagination :pagination="myGamesPagination">
+			<MkPagination :pagination="myGamesPagination" :disableAutoLoad="true">
 				<template #default="{ items }">
 					<div :class="$style.gamePreviews">
 						<MkA v-for="g in items" :key="g.id" v-panel :class="$style.gamePreview" tabindex="-1" :to="`/reversi/g/${g.id}`">
 							<div :class="$style.gamePreviewPlayers">
-								<MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user1"/><b><MkUserName :user="g.user1"/></b> vs <b><MkUserName :user="g.user2"/></b><MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user2"/>
+								<MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user1"/> vs <MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user2"/>
 							</div>
 							<div :class="$style.gamePreviewFooter">
 								<span :style="!g.isEnded ? 'color: var(--accent);' : ''">{{ g.isEnded ? i18n.ts._reversi.ended : i18n.ts._reversi.playing }}</span>
@@ -47,12 +49,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 		<MkFolder :defaultOpen="true">
 			<template #label>{{ i18n.ts._reversi.allGames }}</template>
-			<MkPagination :pagination="gamesPagination">
+			<MkPagination :pagination="gamesPagination" :disableAutoLoad="true">
 				<template #default="{ items }">
 					<div :class="$style.gamePreviews">
 						<MkA v-for="g in items" :key="g.id" v-panel :class="$style.gamePreview" tabindex="-1" :to="`/reversi/g/${g.id}`">
 							<div :class="$style.gamePreviewPlayers">
-								<MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user1"/><b><MkUserName :user="g.user1"/></b> vs <b><MkUserName :user="g.user2"/></b><MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user2"/>
+								<MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user1"/> vs <MkAvatar :class="$style.gamePreviewPlayersAvatar" :user="g.user2"/>
 							</div>
 							<div :class="$style.gamePreviewFooter">
 								<span :style="!g.isEnded ? 'color: var(--accent);' : ''">{{ g.isEnded ? i18n.ts._reversi.ended : i18n.ts._reversi.playing }}</span>