012053a783
Audit A7: the «Оферта» / «Политика» links in the AuthLayout footer were raw <a href> pointing at unrouted paths -> 404 via the SPA catch-all. Adds a single DRY LegalDocView served by /legal/:doc(offer|privacy), rendering an honest «document being finalized» stub (real legal text needs юр. редактура — реестр K3 / blocker Б-1). Footer links upgraded to <RouterLink> for SPA navigation. Also refreshes two stale auth-layout doc-comments left by the /recovery removal (review M1). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
149 lines
4.6 KiB
Vue
149 lines
4.6 KiB
Vue
<script setup lang="ts">
|
||
/**
|
||
* Двухпанельный layout для экранов аутентификации (login/register/2fa/forgot/recovery-use).
|
||
*
|
||
* Источник дизайна: 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>
|
||
<RouterLink to="/legal/offer">Оферта</RouterLink>
|
||
<RouterLink to="/legal/privacy">Политика</RouterLink>
|
||
</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>
|