|
@@ -0,0 +1,563 @@
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted } from 'vue';
|
|
|
+import { service } from './util/http';
|
|
|
+import { message, getLang } from './util/locale';
|
|
|
+import { store } from './util/store';
|
|
|
+
|
|
|
+const model = ref({
|
|
|
+ type: '',
|
|
|
+ forward: '',
|
|
|
+ index: 0,
|
|
|
+ speak: 0,
|
|
|
+ welcome: [],
|
|
|
+ inputs: [],
|
|
|
+ focus: {
|
|
|
+ index: 0,
|
|
|
+ auto: true,
|
|
|
+ },
|
|
|
+ submit: false,
|
|
|
+ invalid: '',
|
|
|
+ forget: false,
|
|
|
+ interval: 0,
|
|
|
+});
|
|
|
+const inputs = { 'in': ['username', 'password'], 'up': ['username', 'nick', 'password', 'repeat'], 'forget': ['username', 'email', 'code', 'newpass', 'repeat'] };
|
|
|
+
|
|
|
+const language = (lang) => {
|
|
|
+ store.language = lang;
|
|
|
+ localStorage.setItem('language', lang);
|
|
|
+ window.location.reload();
|
|
|
+};
|
|
|
+
|
|
|
+const type = (i, j) => {
|
|
|
+ if (model.value.interval)
|
|
|
+ clearInterval(model.value.interval);
|
|
|
+ if ((i === 0 && j === 2) || (i === 1 && j === 1)) {
|
|
|
+ model.value = {
|
|
|
+ type: i === 1 && j === 1 ? 'forget' : (model.value.type === 'up' || model.value.type === 'forget' ? 'in' : 'up'),
|
|
|
+ forward: model.value.forward,
|
|
|
+ index: 0,
|
|
|
+ speak: 0,
|
|
|
+ welcome: [],
|
|
|
+ inputs: [],
|
|
|
+ focus: {
|
|
|
+ index: 0,
|
|
|
+ auto: true,
|
|
|
+ },
|
|
|
+ submit: false,
|
|
|
+ invalid: '',
|
|
|
+ forget: false,
|
|
|
+ };
|
|
|
+ model.value.interval = setInterval(next, model.value.type === 'in' ? 50 : 100);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const next = () => {
|
|
|
+ if (model.value.submit || speak())
|
|
|
+ return;
|
|
|
+
|
|
|
+ model.value.index++;
|
|
|
+ model.value.speak = 0;
|
|
|
+};
|
|
|
+
|
|
|
+const speak = () => {
|
|
|
+ if (model.value.index === 0) {
|
|
|
+ let welcome = message('welcome.' + model.value.type);
|
|
|
+ if (model.value.speak > welcome.length)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ model.value.welcome = welcome.substring(0, model.value.speak++).split('\n');
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ let index = model.value.index - 1;
|
|
|
+ if (model.value.focus.auto)
|
|
|
+ model.value.focus.index = index;
|
|
|
+ if (index < inputs[model.value.type].length) {
|
|
|
+ let label = message(inputs[model.value.type][index]);
|
|
|
+ if (index === 0) {
|
|
|
+ label = message('username.' + model.value.type);
|
|
|
+ } else if (index === 1 && model.value.type === 'in')
|
|
|
+ label += '\n' + message('forget');
|
|
|
+ if (model.value.speak > label.length) {
|
|
|
+ if (model.value.inputs[index].step === 0)
|
|
|
+ model.value.inputs[index].step = 1;
|
|
|
+
|
|
|
+ return model.value.inputs[index].step < 3;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (model.value.inputs.length < model.value.index) {
|
|
|
+ let input = {
|
|
|
+ label: [],
|
|
|
+ value: '',
|
|
|
+ placeholder: '',
|
|
|
+ invalid: '',
|
|
|
+ step: 0,
|
|
|
+ password: index >= (model.value.type === 'up' ? 2 : (model.value.type === 'in' ? 1 : 3)),
|
|
|
+ };
|
|
|
+ if (index === 0) {
|
|
|
+ if (model.value.type === 'in')
|
|
|
+ input.placeholder = message('username-email');
|
|
|
+ else if (model.value.type === 'up')
|
|
|
+ input.placeholder = message('username.placeholder');
|
|
|
+ }
|
|
|
+ model.value.inputs.push(input);
|
|
|
+ }
|
|
|
+ model.value.inputs[index].label = label.substring(0, model.value.speak++).split('\n');
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+const input = (index) => {
|
|
|
+ let value = model.value.inputs[index].value;
|
|
|
+ length = value.length;
|
|
|
+ if (index === 0) {
|
|
|
+ if (model.value.type === 'up') {
|
|
|
+ model.value.inputs[index].invalid = length < 4 || length > 15 ? message('username.invalid.up') : '';
|
|
|
+ if (!model.value.inputs[index].invalid) {
|
|
|
+ service('/user/auth/exists', { uid: value }, data => {
|
|
|
+ model.value.inputs[index].step = data ? 2 : 1;
|
|
|
+ model.value.inputs[index].invalid = data ? '' : message('username.invalid.up');
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ model.value.inputs[index].invalid = '';
|
|
|
+ model.value.inputs[index].step = 2;
|
|
|
+ }
|
|
|
+ } else if (index === 1) {
|
|
|
+ if (model.value.type === 'up') {
|
|
|
+ model.value.inputs[index].invalid = length < 2 || length > 14 ? message('nick.invalid') : '';
|
|
|
+ model.value.inputs[index].step = length < 2 || length > 14 ? 1 : 2;
|
|
|
+ } else if (model.value.type === 'in') {
|
|
|
+ model.value.inputs[index].invalid = length < 7 || length > 20 ? message('password.invalid') : '';
|
|
|
+ model.value.inputs[index].step = length < 7 || length > 20 ? 1 : 2;
|
|
|
+ } else if (model.value.type === 'forget') {
|
|
|
+ let valid = /^(?:\w+\.?-?)*\w+@(?:\w+\.?-?)*\w+$/.test(value);
|
|
|
+ model.value.inputs[index].invalid = !valid ? message('email.invalid') : '';
|
|
|
+ model.value.inputs[index].step = !valid ? 1 : 2;
|
|
|
+ }
|
|
|
+ } else if (index === 2) {
|
|
|
+ if (model.value.type === 'up') {
|
|
|
+ model.value.inputs[index].invalid = length < 7 || length > 20 ? message('password.invalid') : '';
|
|
|
+ model.value.inputs[index].step = length < 7 || length > 20 ? 1 : 2;
|
|
|
+ } else if (model.value.type === 'forget') {
|
|
|
+ model.value.inputs[index].invalid = length === 8 ? '' : message('code.invalid');
|
|
|
+ model.value.inputs[index].step = length === 8 ? 2 : 1;
|
|
|
+ }
|
|
|
+ } else if (index === 3) {
|
|
|
+ if (model.value.type === 'up') {
|
|
|
+ model.value.inputs[index].invalid = value === model.value.inputs[index - 1].value ? '' : message('repeat.invalid');
|
|
|
+ model.value.inputs[index].step = value === model.value.inputs[index - 1].value ? 2 : 1;
|
|
|
+ } else if (model.value.type === 'forget') {
|
|
|
+ model.value.inputs[index].invalid = length < 7 || length > 20 ? message('password.invalid') : '';
|
|
|
+ model.value.inputs[index].step = length < 7 || length > 20 ? 1 : 2;
|
|
|
+ }
|
|
|
+ } else if (index === 4) {
|
|
|
+ model.value.inputs[index].invalid = value === model.value.inputs[index - 1].value ? '' : message('repeat.invalid');
|
|
|
+ model.value.inputs[index].step = value === model.value.inputs[index - 1].value ? 2 : 1;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const confirm = (index, event, callback) => {
|
|
|
+ if (event)
|
|
|
+ event.target.blur();
|
|
|
+ if (model.value.submit) {
|
|
|
+ model.value.focus = { index: model.value.inputs.length + 1, auto: false };
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (model.value.type === 'forget' && !callback) {
|
|
|
+ if (index === 1) {
|
|
|
+ service('/home/forget-email', { uid: model.value.inputs[0].value, email: model.value.inputs[1].value, subject: message('forget.title'), lang: getLang() }, data => {
|
|
|
+ model.value.invalid = message(data ? 'code.send' : 'email.failure');
|
|
|
+ if (data)
|
|
|
+ confirm(index, null, 1);
|
|
|
+ });
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (index === 2) {
|
|
|
+ service('/home/forget-code', { code: model.value.inputs[2].value }, data => {
|
|
|
+ if (data)
|
|
|
+ confirm(index, null, 1);
|
|
|
+ model.value.invalid = data ? '' : message('code.invalid');
|
|
|
+ });
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ model.value.focus.auto = true;
|
|
|
+ if (model.value.inputs[index].step === 2)
|
|
|
+ model.value.inputs[index].step = 3;
|
|
|
+ if (model.value.inputs[index].step === 3) {
|
|
|
+ model.value.submit = (index === 1 && model.value.type === 'in') || (index === 3 && model.value.type === 'up') || (index === 4 && model.value.type === 'forget');
|
|
|
+ if (model.value.submit)
|
|
|
+ model.value.focus = { index: index + 1, auto: false };
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const focus = (index) => {
|
|
|
+ model.value.focus = { index, auto: false };
|
|
|
+};
|
|
|
+
|
|
|
+const submit = () => {
|
|
|
+ if (model.value.type === 'up') {
|
|
|
+ service('/user/sign-up', {
|
|
|
+ type: '',
|
|
|
+ uid: model.value.inputs[0].value,
|
|
|
+ nick: model.value.inputs[1].value,
|
|
|
+ password: model.value.inputs[2].value,
|
|
|
+ }, data => {
|
|
|
+ if (data.id) {
|
|
|
+ forward();
|
|
|
+ } else {
|
|
|
+ model.value.invalid = message('sign-up.invalid');
|
|
|
+ }
|
|
|
+ }, () => model.value.invalid = message('sign-up.invalid'));
|
|
|
+ } else if (model.value.type === 'in') {
|
|
|
+ service('/user/sign-in', {
|
|
|
+ type: '',
|
|
|
+ uid: model.value.inputs[0].value,
|
|
|
+ password: model.value.inputs[1].value,
|
|
|
+ }, data => {
|
|
|
+ if (data.id) {
|
|
|
+ forward();
|
|
|
+ } else {
|
|
|
+ model.value.invalid = message('sign-in.invalid');
|
|
|
+ }
|
|
|
+ }, () => model.value.invalid = message('sign-in.invalid'));
|
|
|
+ } else if (model.value.type === 'forget') {
|
|
|
+ service('/home/password', { code: model.value.inputs[2].value, password: model.value.inputs[3].value }, data => {
|
|
|
+ model.value.forget = data;
|
|
|
+ model.value.invalid = message('forget.' + (data ? 'success' : 'failure'));
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const forward = () => {
|
|
|
+ if (model.value.forward === 'parent') {
|
|
|
+ window.parent.postMessage({ type: 'sign', value: '' }, '*');
|
|
|
+ window.parent.postMessage({ type: 'session', value: localStorage.getItem('photon-session-id')}, '*')
|
|
|
+ } else {
|
|
|
+ location.href = model.value.forward;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ document.title = message('title');
|
|
|
+ if (location.search && location.search.indexOf('?') > -1) {
|
|
|
+ for (let param of location.search.substring(1).split('&')) {
|
|
|
+ if (param.indexOf('type=') === 0) {
|
|
|
+ model.value.type = param.substring(5);
|
|
|
+ } else if (param.indexOf('forward=') === 0) {
|
|
|
+ model.value.forward = decodeURIComponent(param.substring(8));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!model.value.type)
|
|
|
+ model.value.type = 'in';
|
|
|
+ if (!model.value.forward)
|
|
|
+ model.value.forward = '/';
|
|
|
+ model.value.interval = setInterval(next, model.value.type === 'in' ? 50 : 100);
|
|
|
+ service('/user/sign', {}, data => {
|
|
|
+ if (data.id){
|
|
|
+ if(model.value.forward === 'parent'){
|
|
|
+ window.parent.postMessage({ type: 'sign', value: data.id }, '*');
|
|
|
+ window.parent.postMessage({ type: 'session', value: localStorage.getItem('photon-session-id')}, '*')
|
|
|
+ }else{
|
|
|
+ location.href = model.value.forward;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="stars">
|
|
|
+ <div v-for="i in 6" class="star"></div>
|
|
|
+ </div>
|
|
|
+ <div class="sign-in-up">
|
|
|
+ <div class="nav">
|
|
|
+ <img src="./assets/logo.png" />
|
|
|
+ <div class="langs">
|
|
|
+ <div @click="language('zh')"><span>中</span></div>
|
|
|
+ <div @click="language('en')"><span>En</span></div>
|
|
|
+ <div @click="language('jp')"><span>あ</span></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="dialog">
|
|
|
+ <div v-for="welcome in model.welcome" class="welcome">{{ welcome }}</div>
|
|
|
+ <template v-for="(ip, index) in model.inputs">
|
|
|
+ <div class="label">
|
|
|
+ <span v-for="(label, li) in ip.label" :class="'label-' + (li === 0 ? '0' : (index + '' + li))"
|
|
|
+ @click="type(index, li)">{{ label }}</span>
|
|
|
+ </div>
|
|
|
+ <div v-if="ip.step > 0" class="input">
|
|
|
+ <div v-if="model.focus.index === index" class="arrow">→</div>
|
|
|
+ <div v-else-if="model.type === 'up'" class="correct">√</div>
|
|
|
+ <input :type="ip.password ? 'password' : 'text'" v-model="model.inputs[index].value"
|
|
|
+ :placeholder="model.inputs[index].placeholder" @focus="focus(index)" @input="input(index)"
|
|
|
+ @keypress.enter="confirm(index, $event)" />
|
|
|
+ <div v-if="model.focus.index === index"
|
|
|
+ :class="model.inputs[index].step === 2 ? 'button-valid' : 'button-invalid'" @click="confirm(index)">{{
|
|
|
+ message('continue') }}</div>
|
|
|
+ <div v-else class="button-empty">{{ message('continue') }}</div>
|
|
|
+ </div>
|
|
|
+ <div v-else-if="ip.step === 3" class="input">
|
|
|
+ <div v-if="model.type === 'up'" class="correct">√</div>
|
|
|
+ <div class="value">{{ model.inputs[index].password ? '********' : model.inputs[index].value }}</div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div v-if="model.forget" class="submit" @click="type(0, 2)">{{ message('to-in') }}</div>
|
|
|
+ <div v-else-if="model.submit" class="submit" @click="submit">{{ message('sign-' + model.type) }}</div>
|
|
|
+ </div>
|
|
|
+ <div v-if="model.inputs.length > 0 && model.inputs.length >= model.index" class="invalid">{{
|
|
|
+ model.inputs[model.index - 1].invalid }}</div>
|
|
|
+ <div v-if="model.invalid" class="invalid">{{ model.invalid }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.stars,
|
|
|
+.star {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.stars {
|
|
|
+ background-color: #040d21;
|
|
|
+ background-image: url(./assets/hero-glow.svg);
|
|
|
+ background-size: cover;
|
|
|
+ background-position: center center;
|
|
|
+}
|
|
|
+
|
|
|
+.star {
|
|
|
+ background-image: radial-gradient(2px 2px at 50px 200px, #eee, rgba(0, 0, 0, 0)), radial-gradient(2px 2px at 40px 70px, #fff, rgba(0, 0, 0, 0)), radial-gradient(3px 4px at 120px 40px, #ddd, rgba(0, 0, 0, 0));
|
|
|
+ background-repeat: repeat;
|
|
|
+ background-size: 250px 250px;
|
|
|
+ opacity: 0;
|
|
|
+ animation: zoom 10s infinite;
|
|
|
+}
|
|
|
+
|
|
|
+.star:nth-child(1) {
|
|
|
+ background-position: 10% 90%;
|
|
|
+ animation-delay: 0s
|
|
|
+}
|
|
|
+
|
|
|
+.star:nth-child(2) {
|
|
|
+ background-position: 20% 50%;
|
|
|
+ background-size: 270px 500px;
|
|
|
+ animation-delay: .3s
|
|
|
+}
|
|
|
+
|
|
|
+.star:nth-child(3) {
|
|
|
+ background-position: 40% -80%;
|
|
|
+ animation-delay: 1.2s
|
|
|
+}
|
|
|
+
|
|
|
+.star:nth-child(4) {
|
|
|
+ background-position: -20% -30%;
|
|
|
+ transform: rotate(60deg);
|
|
|
+ animation-delay: 2.5s
|
|
|
+}
|
|
|
+
|
|
|
+.star:nth-child(5) {
|
|
|
+ background-image: radial-gradient(2px 2px at 10px 100px, #eee, rgba(0, 0, 0, 0)), radial-gradient(2px 2px at 20px 10px, #fff, rgba(0, 0, 0, 0)), radial-gradient(3px 4px at 150px 40px, #ddd, rgba(0, 0, 0, 0));
|
|
|
+ background-position: 80% 30%;
|
|
|
+ animation-delay: 4s
|
|
|
+}
|
|
|
+
|
|
|
+.star:nth-child(6) {
|
|
|
+ background-position: 50% 20%;
|
|
|
+ animation-delay: 6s
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes zoom {
|
|
|
+ 0% {
|
|
|
+ opacity: 0;
|
|
|
+ transform: scale(0.5);
|
|
|
+ transform: rotate(5deg);
|
|
|
+ animation-timing-function: ease-in
|
|
|
+ }
|
|
|
+
|
|
|
+ 85% {
|
|
|
+ opacity: 1
|
|
|
+ }
|
|
|
+
|
|
|
+ 100% {
|
|
|
+ opacity: .2;
|
|
|
+ transform: scale(2.2)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media(prefers-reduced-motion) {
|
|
|
+ .star {
|
|
|
+ animation: none
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.sign-in-up {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+@media screen and (max-width: 1080px) {
|
|
|
+ .sign-in-up {
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media screen and (min-width: 1080px) {
|
|
|
+ .sign-in-up {
|
|
|
+ left: 20vw;
|
|
|
+ right: 20vw;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.nav {
|
|
|
+ width: calc(100% - 32px);
|
|
|
+ padding: 16px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.nav img {
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+}
|
|
|
+
|
|
|
+.nav .langs{
|
|
|
+ color:#8193b2;
|
|
|
+ display: flex;
|
|
|
+ column-gap: 8px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.dialog {
|
|
|
+ margin: 24px;
|
|
|
+ padding: 24px;
|
|
|
+ background-color: #0c162d;
|
|
|
+ border: 1px solid #202637;
|
|
|
+ border-radius: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.welcome {
|
|
|
+ width: 33vw;
|
|
|
+ min-width: 280px;
|
|
|
+ color: #8193b2;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.label {
|
|
|
+ margin-top: 24px;
|
|
|
+ font-weight: 600;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.label-0 {
|
|
|
+ color: #00cfc8;
|
|
|
+}
|
|
|
+
|
|
|
+.label-01 {
|
|
|
+ padding-left: 16px;
|
|
|
+ color: #8193b2;
|
|
|
+}
|
|
|
+
|
|
|
+.label-02,
|
|
|
+.label-11 {
|
|
|
+ color: #FF8DC0;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.label-11 {
|
|
|
+ padding-left: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.input {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding-top: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.arrow {
|
|
|
+ color: #ea4aaa;
|
|
|
+}
|
|
|
+
|
|
|
+.correct {
|
|
|
+ color: #20bb3d;
|
|
|
+ padding-right: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.input input {
|
|
|
+ flex-grow: 1;
|
|
|
+ outline: none;
|
|
|
+ border: 1px solid #0c162d;
|
|
|
+ background: none;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.input input:focus {
|
|
|
+ border: 1px solid rgb(9, 105, 218);
|
|
|
+}
|
|
|
+
|
|
|
+.value {
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.button-invalid,
|
|
|
+.button-valid,
|
|
|
+.button-empty {
|
|
|
+ padding: 4px 8px;
|
|
|
+ border-radius: 6px;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+.button-invalid {
|
|
|
+ color: #627597;
|
|
|
+ border: 1px solid #627597;
|
|
|
+ cursor: default;
|
|
|
+}
|
|
|
+
|
|
|
+.button-valid,
|
|
|
+.submit {
|
|
|
+ color: #FF8DC0;
|
|
|
+ border: 1px solid #FF8DC0;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.button-empty {
|
|
|
+ color: #0c162d;
|
|
|
+ border: 1px solid #0c162d;
|
|
|
+ cursor: default;
|
|
|
+}
|
|
|
+
|
|
|
+.submit {
|
|
|
+ text-align: center;
|
|
|
+ padding: 8px 0;
|
|
|
+ border-radius: 6px;
|
|
|
+ margin-top: 24px;
|
|
|
+}
|
|
|
+
|
|
|
+.invalid {
|
|
|
+ padding: 0 48px;
|
|
|
+ color: #8193b2;
|
|
|
+}
|
|
|
+</style>
|