diff --git a/html/src/app.scss b/html/src/app.scss
index e03db206..e101f386 100644
--- a/html/src/app.scss
+++ b/html/src/app.scss
@@ -172,11 +172,64 @@ a {
// modal 시작이 2000이라서
z-index: 1999;
display: flex;
+ align-items: center;
+ justify-content: center;
width: 100%;
height: 100%;
background: #fff;
}
+.x-login {
+ display: grid;
+ grid-template-rows: repeat(2, auto);
+ align-items: center;
+ max-width: clamp(600px, 60svw, 800px);
+}
+
+.x-login-form-container {
+ display: grid;
+ gap: 8px;
+ justify-items: center;
+ height: fit-content;
+}
+
+.x-login-form-container:has(> div:nth-child(3)) {
+ grid-template-columns: 1fr 1px 1fr;
+}
+
+.x-login-form-container > div {
+ position: relative;
+ height: fit-content;
+ max-width: 280px;
+ padding: 16px;
+}
+
+.x-scroll-wrapper {
+ width: 100%;
+ height: 100%;
+ overflow-y: auto;
+}
+
+hr.x-vertical-divider {
+ height: 100%;
+ width: 100%;
+ margin: 0;
+ border: 0;
+ background: rgb(255 255 255 / 16%);
+}
+
+.x-saved-account-list {
+ display: grid;
+
+ > .x-friend-item {
+ width: 100%;
+ }
+}
+
+.x-legal-notice-container {
+ margin-top: 8px;
+}
+
.x-menu-container {
flex: none;
overflow: hidden auto;
diff --git a/html/src/mixins/loginPage.pug b/html/src/mixins/loginPage.pug
index f056b60e..ab883fbe 100644
--- a/html/src/mixins/loginPage.pug
+++ b/html/src/mixins/loginPage.pug
@@ -1,36 +1,43 @@
mixin loginPage()
.x-login-container(v-if="!API.isLoggedIn" v-loading="loginForm.loading")
- div(style="position:absolute;margin:5px")
- el-button(type="default" @click="showVRCXUpdateDialog" size="mini" icon="el-icon-download" circle)
- div(style="width:300px;margin:auto")
- div(style="margin:15px" v-if="Object.keys(loginForm.savedCredentials).length !== 0")
- h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.savedAccounts") }}
- .x-friend-list(style="margin-top:10px")
- .x-friend-item(v-for="user in loginForm.savedCredentials" :key="user.user.id")
- .x-friend-item(@click="relogin(user)" style="width:202px;padding:0")
- .avatar
- img(v-lazy="userImage(user.user)")
- .detail
- span.name(v-text="user.user.displayName")
- span.extra(v-text="user.user.username")
- span.extra(v-text="user.loginParmas.endpoint")
- el-button(type="default" @click="deleteSavedLogin(user.user.id)" size="mini" icon="el-icon-delete" circle)
- div(style="margin:15px")
- h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.login") }}
- el-form(ref="loginForm" :model="loginForm" :rules="loginForm.rules" @submit.native.prevent="login()")
- el-form-item(:label="$t('view.login.field.username')" prop="username" required)
- el-input(v-model="loginForm.username" name="username" :placeholder="$t('view.login.field.username')" clearable)
- el-form-item(:label="$t('view.login.field.password')" prop="password" required style="margin-top:10px")
- el-input(type="password" v-model="loginForm.password" name="password" :placeholder="$t('view.login.field.password')" clearable show-password)
- el-checkbox(v-model="loginForm.saveCredentials" style="margin-top:15px") {{ $t("view.login.field.saveCredentials") }}
- el-checkbox(v-model="enableCustomEndpoint" @change="toggleCustomEndpoint" style="margin-top:10px") {{ $t("view.login.field.devEndpoint") }}
- el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.endpoint')" prop="endpoint" style="margin-top:10px")
- el-input(v-model="loginForm.endpoint" name="endpoint" :placeholder="API.endpointDomainVrchat" clearable)
- el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.websocket')" prop="endpoint" style="margin-top:10px")
- el-input(v-model="loginForm.websocket" name="websocket" :placeholder="API.websocketDomainVrchat" clearable)
- el-form-item(style="margin-top:15px")
- el-button(native-type="submit" type="primary" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.login") }}
- el-button(type="primary" @click="openExternalLink('https://vrchat.com/register')" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.register") }}
+ .x-login
+ div(style="position:fixed; top: 0; left: 0; margin:5px")
+ el-button(type="default" @click="showVRCXUpdateDialog" size="mini" icon="el-icon-download" circle)
+
+ div.x-login-form-container
+ div
+ h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.login") }}
+ el-form(ref="loginForm" :model="loginForm" :rules="loginForm.rules" @submit.native.prevent="login()")
+ el-form-item(:label="$t('view.login.field.username')" prop="username" required)
+ el-input(v-model="loginForm.username" name="username" :placeholder="$t('view.login.field.username')" clearable)
+ el-form-item(:label="$t('view.login.field.password')" prop="password" required style="margin-top:10px")
+ el-input(type="password" v-model="loginForm.password" name="password" :placeholder="$t('view.login.field.password')" clearable show-password)
+ el-checkbox(v-model="loginForm.saveCredentials" style="margin-top:15px") {{ $t("view.login.field.saveCredentials") }}
+ el-checkbox(v-model="enableCustomEndpoint" @change="toggleCustomEndpoint" style="margin-top:10px") {{ $t("view.login.field.devEndpoint") }}
+ el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.endpoint')" prop="endpoint" style="margin-top:10px")
+ el-input(v-model="loginForm.endpoint" name="endpoint" :placeholder="API.endpointDomainVrchat" clearable)
+ el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.websocket')" prop="endpoint" style="margin-top:10px")
+ el-input(v-model="loginForm.websocket" name="websocket" :placeholder="API.websocketDomainVrchat" clearable)
+ el-form-item(style="margin-top:15px")
+ el-button(native-type="submit" type="primary" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.login") }}
+ el-button(type="primary" @click="openExternalLink('https://vrchat.com/register')" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.register") }}
+
+ hr.x-vertical-divider(v-if="Object.keys(loginForm.savedCredentials).length !== 0")/
+
+ div(v-if="Object.keys(loginForm.savedCredentials).length !== 0")
+ h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.savedAccounts") }}
+ .x-scroll-wrapper(style="margin-top:10px")
+ .x-saved-account-list
+ .x-friend-item(v-for="user in loginForm.savedCredentials" :key="user.user.id" @click="relogin(user)")
+ .avatar
+ img(v-lazy="userImage(user.user)")
+ .detail
+ span.name(v-text="user.user.displayName")
+ span.extra(v-text="user.user.username")
+ span.extra(v-text="user.loginParmas.endpoint")
+ el-button(type="default" @click="deleteSavedLogin(user.user.id)" size="mini" icon="el-icon-delete" circle)
+
+ div.x-legal-notice-container
div(style="text-align:center;font-size:12px")
p #[a.x-link(@click="openExternalLink('https://vrchat.com/home/password')") {{ $t("view.login.forgotPassword") }}]
p © 2019-2022 #[a.x-link(@click="openExternalLink('https://github.com/pypy-vrc')") pypy] (mina#5656) & #[a.x-link(@click="openExternalLink('https://github.com/Natsumi-sama')") Natsumi]