Files
portal/app/resources/js/layouts/AuthLayout.vue
T

149 lines
4.5 KiB
Vue
Raw Normal View History

<script setup lang="ts">
/**
* Двухпанельный layout для экранов аутентификации (login/register/2fa/forgot/recovery).
*
* Источник дизайна: liderra_v8_handoff/concepts/v8_login.html (CSS .layout grid 1fr 1fr,
* .brand-pane слева тёмный теало-нуар + radial-gradient'ы, .form-pane справа warm ivory).
*
* Структура:
* - <v-row no-gutters> с двумя колонками 50/50 на desktop, на mobile — brand-pane скрыт.
* - Слева: brand mark "Лидерра.", цитата с акцентом, footer с ссылками на оферту/политику.
* - Справа: <RouterView /> рендерит конкретный auth-экран (LoginView и т.п.).
*/
import { RouterView, useRoute } from 'vue-router';
import DevIndexBadge from '../components/DevIndexBadge.vue';
const route = useRoute();
</script>
<template>
<v-app>
<v-main>
<v-row no-gutters class="auth-layout">
<v-col cols="12" md="6" class="brand-pane d-none d-md-flex">
<div class="brand-pane-inner">
<div class="bp-brand">
<span class="mark" aria-hidden="true">
<svg viewBox="0 0 48 48" width="24" height="24">
<path
d="M16 14 L16 34 L32 34"
stroke="#012019"
stroke-width="4.5"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"
/>
<circle cx="32" cy="34" r="3.5" fill="#0F6E56" />
</svg>
</span>
<span>Лидерра<span class="dot">.</span></span>
</div>
<p class="bp-quote">
Поток лидов <em>под контролем</em>.<br />
Pay-per-lead, прозрачно каждый рубль <em>в дело</em>.
</p>
<div class="bp-foot">
<span>v8 · Forest</span>
<a href="/legal/offer">Оферта</a>
<a href="/legal/privacy">Политика</a>
</div>
</div>
</v-col>
<v-col cols="12" md="6" class="form-pane d-flex align-center justify-center">
<RouterView />
</v-col>
</v-row>
</v-main>
<DevIndexBadge :index="route.meta.devIndex" :label="route.meta.devLabel" />
</v-app>
</template>
<style scoped>
.auth-layout {
min-height: 100vh;
}
.brand-pane {
background: #012019;
color: #fff;
padding: 56px 60px;
position: relative;
overflow: hidden;
}
.brand-pane::before {
content: '';
position: absolute;
inset: 0;
background-image:
radial-gradient(circle at 80% 20%, rgba(50, 200, 169, 0.08) 0%, transparent 40%),
radial-gradient(circle at 20% 80%, rgba(15, 110, 86, 0.1) 0%, transparent 40%);
pointer-events: none;
}
.brand-pane-inner {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
}
.bp-brand {
display: flex;
align-items: center;
gap: 10px;
font-weight: 600;
font-size: 16px;
letter-spacing: -0.01em;
font-variation-settings: 'opsz' 18;
}
.bp-brand .mark {
width: 24px;
height: 24px;
border-radius: 5px;
background: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
overflow: hidden;
}
.bp-brand .dot {
color: #32c8a9;
}
.bp-quote {
font-size: 30px;
font-weight: 500;
font-variation-settings: 'opsz' 28;
letter-spacing: -0.02em;
line-height: 1.18;
max-width: 440px;
margin: 0;
}
.bp-quote em {
color: #32c8a9;
font-style: normal;
}
.bp-foot {
font-size: 12px;
color: #7a8c87;
font-family: 'JetBrains Mono', ui-monospace, monospace;
display: flex;
gap: 14px;
}
.bp-foot a {
color: inherit;
text-decoration: none;
}
.bp-foot a:hover {
color: #fff;
}
.form-pane {
background: #f6f3ec;
padding: 40px 32px 56px;
}
</style>