chore: refresh preview pages + add tradein landing #283
7 changed files with 5429 additions and 258 deletions
586
frontend/public/analytics.html
Normal file
586
frontend/public/analytics.html
Normal file
|
|
@ -0,0 +1,586 @@
|
|||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>/analytics — Свердл рынок · gendsgn</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
:root {
|
||||
--bg-app:#F6F7F9; --bg-card:#FFFFFF; --bg-card-alt:#FAFBFC; --bg-headline:#0F172A;
|
||||
--border-soft:#EEF0F3; --border-card:#E6E8EC; --border-strong:#D1D5DB;
|
||||
--fg-primary:#111111; --fg-secondary:#5B6066; --fg-tertiary:#73767E;
|
||||
--fg-on-dark:#E2E8F0; --fg-on-dark-muted:#94A3B8;
|
||||
--accent:#1D4ED8; --accent-hover:#1E40AF; --accent-soft:#DBEAFE; --accent-2:#F2994A;
|
||||
--success:#0A7A3A; --success-soft:#DCFCE7;
|
||||
--warn:#9A6700; --warn-soft:#FEF3C7;
|
||||
--danger:#B3261E; --danger-soft:#FEE2E2;
|
||||
--viz-1:#1D4ED8; --viz-2:#0EA5E9; --viz-3:#14B8A6; --viz-4:#F59E0B; --viz-5:#8B5CF6;
|
||||
--prediction-band: rgba(14,165,233,0.18);
|
||||
--font-body:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
|
||||
}
|
||||
* { box-sizing:border-box; margin:0; padding:0; }
|
||||
html { background:var(--bg-app); }
|
||||
body { font-family:var(--font-body); font-size:14px; line-height:1.5; color:var(--fg-primary); font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; }
|
||||
a { color:inherit; text-decoration:none; }
|
||||
button { font:inherit; cursor:pointer; }
|
||||
.mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
|
||||
.wrap { max-width:1440px; margin:0 auto; padding:0 24px; }
|
||||
|
||||
/* ============ DEV NAV ============ */
|
||||
.dev-nav { position:sticky; top:0; z-index:100; display:flex; align-items:center; gap:18px; height:38px; padding:0 18px; background:#0b0f1a; color:rgba(255,255,255,0.92); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; letter-spacing:0.04em; border-bottom:1px solid rgba(255,255,255,0.08); }
|
||||
.dev-nav .dev-label { display:inline-flex; align-items:center; gap:8px; color:#fbbf24; font-weight:600; letter-spacing:0.18em; text-transform:uppercase; white-space:nowrap; }
|
||||
.dev-nav .dev-label::before { content:''; width:6px; height:6px; border-radius:50%; background:#fbbf24; box-shadow:0 0 0 3px rgba(251,191,36,0.22); }
|
||||
.dev-nav .dev-tabs { display:inline-flex; gap:2px; align-items:center; }
|
||||
.dev-nav .dev-sep { width:1px; height:16px; background:rgba(255,255,255,0.16); margin:0 6px; }
|
||||
.dev-nav .dev-tabs a { padding:5px 11px; border-radius:5px; color:rgba(255,255,255,0.62); transition:background .12s,color .12s; }
|
||||
.dev-nav .dev-tabs a:hover { color:#fff; background:rgba(255,255,255,0.08); }
|
||||
.dev-nav .dev-tabs a[aria-current="page"] { color:#0b0f1a; background:#fbbf24; font-weight:600; }
|
||||
.dev-nav .dev-hint { margin-left:auto; color:rgba(255,255,255,0.36); white-space:nowrap; }
|
||||
@media print { .dev-nav { display:none !important; } }
|
||||
|
||||
.topbar { background:var(--bg-card); border-bottom:1px solid var(--border-card); }
|
||||
.topbar-inner { display:flex; align-items:center; justify-content:space-between; height:56px; }
|
||||
.brand { display:inline-flex; align-items:center; gap:8px; font-weight:700; font-size:15px; color:var(--fg-primary); letter-spacing:-0.01em; }
|
||||
.brand-mark { width:22px; height:22px; border-radius:6px; background:var(--accent); display:grid; place-items:center; color:#fff; font-size:11px; font-weight:700; }
|
||||
.brand-mark::before { content:'gd'; }
|
||||
.topbar-user { display:flex; align-items:center; gap:12px; font-size:13px; color:var(--fg-secondary); }
|
||||
.topbar-user .who { display:flex; align-items:center; gap:8px; padding:6px 12px; border-radius:6px; background:var(--bg-card-alt); border:1px solid var(--border-card); }
|
||||
.topbar-user .avatar { width:22px; height:22px; border-radius:50%; background:var(--accent-soft); color:var(--accent); display:grid; place-items:center; font-weight:600; font-size:10px; }
|
||||
|
||||
.crumbs { display:flex; gap:8px; align-items:center; padding-top:16px; font-size:12.5px; color:var(--fg-secondary); }
|
||||
.crumbs a { color:var(--fg-secondary); }
|
||||
.crumbs a:hover { color:var(--accent); text-decoration:underline; text-underline-offset:3px; }
|
||||
.crumbs .sep { color:var(--fg-tertiary); }
|
||||
.crumbs .last { color:var(--fg-primary); }
|
||||
|
||||
.page-head { padding:8px 0 16px; display:flex; justify-content:space-between; align-items:flex-end; gap:24px; }
|
||||
.page-head h1 { font-size:22px; line-height:1.25; font-weight:600; letter-spacing:-0.01em; }
|
||||
.page-head .sub { font-size:13px; color:var(--fg-secondary); margin-top:4px; }
|
||||
.page-head .right { display:flex; gap:8px; align-items:center; }
|
||||
|
||||
.a-tabs { display:flex; gap:2px; border-bottom:1px solid var(--border-card); margin-bottom:16px; overflow-x:auto; }
|
||||
.a-tabs a { padding:10px 14px; font-size:13px; font-weight:500; color:var(--fg-secondary); border-bottom:2px solid transparent; margin-bottom:-1px; white-space:nowrap; }
|
||||
.a-tabs a:hover { color:var(--fg-primary); }
|
||||
.a-tabs a[aria-current="page"] { color:var(--accent); border-bottom-color:var(--accent); font-weight:600; }
|
||||
|
||||
.headline-bar { background:var(--bg-headline); color:var(--fg-on-dark); border-radius:12px; padding:16px 20px; display:flex; align-items:center; gap:16px; margin-bottom:16px; }
|
||||
.headline-bar .tag { font-size:10.5px; letter-spacing:0.08em; text-transform:uppercase; font-weight:600; color:var(--accent-2); white-space:nowrap; }
|
||||
.headline-bar .verdict { font-size:15px; font-weight:500; line-height:1.4; color:var(--fg-on-dark); }
|
||||
.headline-bar .verdict b { color:#fff; font-weight:600; }
|
||||
.headline-bar .caveat { margin-left:auto; font-size:11.5px; color:var(--fg-on-dark-muted); white-space:nowrap; }
|
||||
|
||||
.kpi-row { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:24px; }
|
||||
.kpi { background:var(--bg-card); border:1px solid var(--border-card); border-radius:12px; padding:16px 18px; }
|
||||
.kpi .label { font-size:11px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; }
|
||||
.kpi .value { font-size:28px; line-height:1.15; font-weight:600; color:var(--fg-primary); letter-spacing:-0.015em; margin-top:8px; }
|
||||
.kpi .value small { font-size:14px; color:var(--fg-secondary); font-weight:500; margin-left:4px; }
|
||||
.kpi .hint { font-size:12.5px; color:var(--fg-secondary); margin-top:6px; }
|
||||
.kpi .delta { display:inline-flex; align-items:center; gap:4px; font-size:12px; font-weight:600; margin-top:8px; padding:2px 8px; border-radius:4px; font-variant-numeric:tabular-nums; }
|
||||
.kpi .delta.pos { color:var(--success); background:var(--success-soft); }
|
||||
.kpi .delta.neg { color:var(--danger); background:var(--danger-soft); }
|
||||
|
||||
.section { background:var(--bg-card); border:1px solid var(--border-card); border-radius:12px; padding:20px; margin-bottom:24px; }
|
||||
.section-head { display:flex; align-items:flex-end; justify-content:space-between; gap:16px; margin-bottom:16px; }
|
||||
.section-head h2 { font-size:18px; line-height:1.25; font-weight:600; letter-spacing:-0.01em; }
|
||||
.section-head .sub { font-size:12.5px; color:var(--fg-secondary); margin-top:4px; }
|
||||
.section-head .right { display:flex; gap:8px; align-items:center; }
|
||||
|
||||
.btn { display:inline-flex; align-items:center; gap:6px; height:36px; padding:0 16px; border-radius:8px; font-weight:500; font-size:13.5px; border:1px solid transparent; transition:all .12s; }
|
||||
.btn-primary { background:var(--accent); color:#fff; border-color:var(--accent); }
|
||||
.btn-primary:hover { background:var(--accent-hover); border-color:var(--accent-hover); }
|
||||
.btn-secondary { background:var(--accent-2); color:#fff; border-color:var(--accent-2); }
|
||||
.btn-secondary:hover { filter:brightness(0.94); }
|
||||
.btn-tertiary { background:transparent; color:var(--fg-primary); border-color:var(--border-card); }
|
||||
.btn-tertiary:hover { border-color:var(--fg-primary); }
|
||||
.btn-compact { height:32px; padding:0 12px; font-size:12.5px; border-radius:6px; }
|
||||
|
||||
.chip { display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 12px; border-radius:14px; font-size:12px; font-weight:500; color:var(--fg-secondary); background:transparent; border:1px solid var(--border-card); transition:all .12s; cursor:pointer; }
|
||||
.chip:hover { color:var(--fg-primary); border-color:var(--fg-secondary); }
|
||||
.chip[aria-pressed="true"] { color:var(--accent); background:var(--accent-soft); border-color:var(--accent-soft); }
|
||||
|
||||
.badge { display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:600; padding:2px 8px; border-radius:4px; }
|
||||
.badge.live { color:var(--success); background:var(--success-soft); }
|
||||
.badge.live::before { content:''; width:6px; height:6px; border-radius:50%; background:var(--success); box-shadow:0 0 0 3px rgba(10,122,58,0.18); }
|
||||
|
||||
.map-wrap { position:relative; height:480px; border-radius:8px; overflow:hidden; border:1px solid var(--border-soft); background:#EEF2F7; }
|
||||
.map-wrap svg { width:100%; height:100%; display:block; }
|
||||
.map-legend { position:absolute; bottom:12px; left:12px; background:rgba(255,255,255,0.96); backdrop-filter:blur(8px); border:1px solid var(--border-card); border-radius:8px; padding:10px 12px; font-size:11.5px; display:flex; flex-direction:column; gap:6px; }
|
||||
.map-legend h4 { font-size:10px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; }
|
||||
.map-legend .row { display:flex; align-items:center; gap:8px; }
|
||||
.map-legend .row .pip { width:10px; height:10px; border-radius:50%; border:1.5px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,0.06); }
|
||||
.map-controls { position:absolute; top:12px; right:12px; display:flex; flex-direction:column; gap:4px; }
|
||||
.map-controls button { width:32px; height:32px; border-radius:6px; background:rgba(255,255,255,0.96); border:1px solid var(--border-card); font-size:14px; color:var(--fg-primary); display:grid; place-items:center; }
|
||||
.map-tooltip { position:absolute; top:14%; left:36%; background:#fff; border:1px solid var(--border-card); border-radius:8px; padding:10px 12px; font-size:11.5px; box-shadow:0 8px 24px -8px rgba(0,0,0,0.18); min-width:200px; }
|
||||
.map-tooltip .name { font-weight:600; color:var(--fg-primary); font-size:12.5px; margin-bottom:2px; }
|
||||
.map-tooltip .meta { color:var(--fg-secondary); font-size:11px; line-height:1.45; }
|
||||
.map-tooltip .stat { display:flex; justify-content:space-between; padding-top:6px; margin-top:6px; border-top:1px solid var(--border-soft); }
|
||||
|
||||
.pulse-wrap { display:grid; grid-template-columns:1fr 240px; gap:24px; align-items:start; }
|
||||
.pulse-chart { position:relative; height:280px; border-left:1px solid var(--border-soft); border-bottom:1px solid var(--border-soft); }
|
||||
.pulse-chart svg { width:100%; height:100%; display:block; }
|
||||
.pulse-legend { display:flex; flex-direction:column; gap:10px; padding-top:8px; }
|
||||
.pulse-legend .leg-row { display:flex; align-items:center; gap:8px; font-size:12.5px; }
|
||||
.pulse-legend .leg-row .sw { width:14px; height:8px; border-radius:2px; }
|
||||
.pulse-legend .leg-row .name { color:var(--fg-primary); font-weight:500; }
|
||||
.pulse-legend .leg-row .meta { margin-left:auto; color:var(--fg-secondary); font-size:11.5px; }
|
||||
.pulse-axis { position:absolute; font-size:10px; color:var(--fg-tertiary); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
|
||||
|
||||
.qg-table { display:grid; grid-template-columns:160px 1fr 70px; gap:12px; }
|
||||
.qg-row { display:contents; }
|
||||
.qg-cell { padding:8px 0; border-top:1px solid var(--border-soft); display:flex; align-items:center; }
|
||||
.qg-row:first-child .qg-cell { border-top:0; }
|
||||
.qg-name { color:var(--fg-primary); font-weight:500; font-size:13px; }
|
||||
.qg-bars { display:flex; flex-direction:column; gap:4px; padding:6px 0; flex:1; }
|
||||
.qg-bar { height:14px; border-radius:4px; position:relative; min-width:1%; transition:all .15s; }
|
||||
.qg-bar .v { position:absolute; right:8px; top:50%; transform:translateY(-50%); font-size:10.5px; font-weight:600; color:#fff; font-variant-numeric:tabular-nums; }
|
||||
.qg-bar.supply { background:var(--fg-tertiary); }
|
||||
.qg-bar.demand { background:var(--accent); }
|
||||
.qg-delta { font-size:12px; font-weight:600; padding:3px 8px; border-radius:4px; text-align:center; font-variant-numeric:tabular-nums; }
|
||||
.qg-delta.pos { color:var(--success); background:var(--success-soft); }
|
||||
.qg-delta.neg { color:var(--danger); background:var(--danger-soft); }
|
||||
.qg-delta.flat { color:var(--fg-secondary); background:var(--bg-card-alt); }
|
||||
|
||||
.two-col { display:grid; grid-template-columns:1fr 1fr; gap:24px; margin-bottom:24px; }
|
||||
|
||||
.pipeline { display:flex; flex-direction:column; gap:10px; padding-top:8px; }
|
||||
.pipe-row { display:grid; grid-template-columns:60px 1fr 80px; gap:12px; align-items:center; }
|
||||
.pipe-row .year { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; color:var(--fg-secondary); }
|
||||
.pipe-row .stack { height:18px; border-radius:4px; overflow:hidden; display:flex; background:var(--bg-card-alt); }
|
||||
.pipe-row .stack .seg { height:100%; }
|
||||
.pipe-row .total { font-size:12.5px; font-weight:600; color:var(--fg-primary); text-align:right; font-variant-numeric:tabular-nums; }
|
||||
|
||||
.ann-table { width:100%; border-collapse:collapse; }
|
||||
.ann-table th { font-size:10px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; text-align:left; padding:8px 8px 8px 0; border-bottom:1px solid var(--border-card); }
|
||||
.ann-table th:last-child, .ann-table td:last-child { text-align:right; padding-right:0; }
|
||||
.ann-table td { font-size:13px; padding:10px 8px 10px 0; border-bottom:1px solid var(--border-soft); color:var(--fg-primary); }
|
||||
.ann-table tr:last-child td { border-bottom:0; }
|
||||
.ann-table .num { font-variant-numeric:tabular-nums; font-weight:500; }
|
||||
.ann-table a { color:var(--accent); }
|
||||
.ann-table a:hover { text-decoration:underline; text-underline-offset:2px; }
|
||||
|
||||
.treemap { display:grid; grid-template-columns:repeat(12,1fr); grid-auto-rows:54px; gap:4px; }
|
||||
.tile { background:var(--accent); color:#fff; padding:10px 12px; border-radius:6px; display:flex; flex-direction:column; justify-content:space-between; cursor:pointer; transition:transform .1s; overflow:hidden; }
|
||||
.tile:hover { transform:translateY(-1px); }
|
||||
.tile .t-name { font-size:13px; font-weight:600; line-height:1.2; }
|
||||
.tile .t-meta { font-size:11px; opacity:0.85; font-variant-numeric:tabular-nums; }
|
||||
.tile.lvl-5 { background:#1E3A8A; }
|
||||
.tile.lvl-4 { background:#1D4ED8; }
|
||||
.tile.lvl-3 { background:#3B82F6; }
|
||||
.tile.lvl-2 { background:#60A5FA; }
|
||||
.tile.lvl-1 { background:#93C5FD; color:#1E3A8A; }
|
||||
.tile.lvl-1 .t-meta { opacity:0.75; }
|
||||
|
||||
details.acc { background:var(--bg-card); border:1px solid var(--border-card); border-radius:12px; margin-bottom:12px; }
|
||||
details.acc summary { padding:14px 20px; font-size:14px; font-weight:600; color:var(--fg-primary); cursor:pointer; list-style:none; display:flex; justify-content:space-between; align-items:center; }
|
||||
details.acc summary::-webkit-details-marker { display:none; }
|
||||
details.acc summary::after { content:'+'; color:var(--fg-secondary); font-size:18px; font-weight:400; }
|
||||
details.acc[open] summary::after { content:'–'; }
|
||||
details.acc .acc-body { padding:0 20px 20px; font-size:13px; color:var(--fg-secondary); line-height:1.55; }
|
||||
|
||||
.caveat-bar { background:var(--warn-soft); border:1px solid var(--warn); border-radius:8px; padding:12px 16px; display:flex; gap:12px; align-items:flex-start; font-size:13px; color:var(--fg-primary); margin-bottom:24px; }
|
||||
.caveat-bar .icon { width:18px; height:18px; flex-shrink:0; color:var(--warn); display:grid; place-items:center; font-weight:700; border:1.5px solid var(--warn); border-radius:50%; font-size:12px; }
|
||||
.caveat-bar b { color:var(--warn); }
|
||||
|
||||
@media (max-width:1200px) {
|
||||
.kpi-row { grid-template-columns:repeat(2,1fr); }
|
||||
.two-col { grid-template-columns:1fr; }
|
||||
.pulse-wrap { grid-template-columns:1fr; }
|
||||
.treemap { grid-template-columns:repeat(6,1fr); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<aside class="dev-nav" aria-label="Dev navigation">
|
||||
<span class="dev-label">Превью · gendsgn</span>
|
||||
<nav class="dev-tabs" aria-label="Превью страницы">
|
||||
<a href="index.html">обзор</a>
|
||||
<a href="landing.html">лендинг</a>
|
||||
<a href="analytics.html" aria-current="page">/analytics</a>
|
||||
<a href="site-finder.html">/site-finder</a>
|
||||
<a href="site-finder-analysis.html">/site-finder/анализ</a>
|
||||
<a href="developers.html">/developers</a>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="wrap topbar-inner">
|
||||
<div style="display:flex;align-items:center;gap:24px;">
|
||||
<a href="landing.html" class="brand"><span class="brand-mark"></span><span>gendsgn</span></a>
|
||||
<span class="badge live">live · обновлено 4 ч назад</span>
|
||||
</div>
|
||||
<div class="topbar-user">
|
||||
<span style="font-size:12px;color:var(--fg-tertiary);">Свердловская обл. · 2025-Q1</span>
|
||||
<div class="who"><div class="avatar">AD</div>Алексей · PRINZIP (demo)</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
|
||||
<nav class="crumbs" aria-label="Breadcrumb">
|
||||
<a href="landing.html">gendsgn</a>
|
||||
<span class="sep">/</span>
|
||||
<span class="last">analytics — Свердл рынок</span>
|
||||
</nav>
|
||||
|
||||
<div class="page-head">
|
||||
<div>
|
||||
<h1>Свердл рынок — обзор спроса и предложения</h1>
|
||||
<div class="sub">6 832 411 ДДУ Росреестра · 1 482 объекта ДОМ.РФ в активной фазе · обновление еженедельно</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="btn btn-tertiary btn-compact">Снимок PDF</button>
|
||||
<button class="btn btn-secondary btn-compact">Export CSV ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="a-tabs" aria-label="Разделы аналитики">
|
||||
<a href="analytics.html" aria-current="page">Свердл рынок</a>
|
||||
<a href="site-finder.html">Рекомендатор</a>
|
||||
<a href="developers.html">Девелоперы</a>
|
||||
<a href="#">PRINZIP · профиль</a>
|
||||
<a href="#">Объекты</a>
|
||||
</nav>
|
||||
|
||||
<div class="headline-bar" role="status">
|
||||
<span class="tag">вердикт квартала</span>
|
||||
<p class="verdict">Дефицит средне-большого жилья <b>80+ м²</b>: <b>37%</b> сделок Росреестра, но <b>11%</b> портфеля ДОМ.РФ. Окно сужается к <b>Q3 2026</b>.</p>
|
||||
<span class="caveat">источник: ДОМ.РФ · Росреестр · март 2026</span>
|
||||
</div>
|
||||
|
||||
<div class="kpi-row">
|
||||
<div class="kpi">
|
||||
<div class="label">Объём строительства</div>
|
||||
<div class="value">5,82<small>млн м²</small></div>
|
||||
<div class="hint">в активной фазе по области</div>
|
||||
<span class="delta pos">↑ 4,1% YoY</span>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="label">Sold % (медиана)</div>
|
||||
<div class="value">61,4 %</div>
|
||||
<div class="hint">объекты в продаже > 6 мес</div>
|
||||
<span class="delta neg">↓ 3,2 пп QoQ</span>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="label">Средняя цена</div>
|
||||
<div class="value">186<small>тыс ₽/м²</small></div>
|
||||
<div class="hint">первичка, март 2026</div>
|
||||
<span class="delta pos">↑ 1,8% MoM</span>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="label">Активных новостроек</div>
|
||||
<div class="value">347</div>
|
||||
<div class="hint">в открытой продаже Я.Недв</div>
|
||||
<span class="delta pos">+12 за месяц</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Карта рынка — новостройки Свердловской области</h2>
|
||||
<div class="sub">347 объектов в активной продаже · цвет точки — sold % за 6 месяцев · клик → drill-in</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="chip" aria-pressed="true">все классы</button>
|
||||
<button class="chip">комфорт</button>
|
||||
<button class="chip">бизнес</button>
|
||||
<button class="chip">премиум</button>
|
||||
<button class="btn btn-secondary btn-compact">Export GeoJSON ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="map-wrap">
|
||||
<svg viewBox="0 0 1200 480" preserveAspectRatio="xMidYMid slice" role="img" aria-label="Карта новостроек Екатеринбурга и окрестностей">
|
||||
<defs>
|
||||
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
||||
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#DDE3EB" stroke-width="0.5"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="1200" height="480" fill="url(#grid)"/>
|
||||
<path d="M 100 80 Q 280 180 380 220 T 700 280 Q 880 320 1100 380" stroke="#0EA5E9" stroke-width="3.5" fill="none" opacity="0.45" stroke-linecap="round"/>
|
||||
<path d="M 0 240 L 1200 240" stroke="#C5CCD6" stroke-width="2" opacity="0.6"/>
|
||||
<path d="M 600 0 L 600 480" stroke="#C5CCD6" stroke-width="2" opacity="0.6"/>
|
||||
<path d="M 180 0 Q 380 240 580 480" stroke="#C5CCD6" stroke-width="1.5" opacity="0.5"/>
|
||||
<path d="M 850 0 Q 700 240 850 480" stroke="#C5CCD6" stroke-width="1.5" opacity="0.5"/>
|
||||
<text x="280" y="110" font-family="Inter,sans-serif" font-size="11" fill="#5B6066" font-weight="500">Академический</text>
|
||||
<text x="540" y="160" font-family="Inter,sans-serif" font-size="11" fill="#5B6066" font-weight="500">ВИЗ</text>
|
||||
<text x="730" y="200" font-family="Inter,sans-serif" font-size="11" fill="#5B6066" font-weight="500">Центр</text>
|
||||
<text x="920" y="270" font-family="Inter,sans-serif" font-size="11" fill="#5B6066" font-weight="500">Пионерский</text>
|
||||
<text x="380" y="330" font-family="Inter,sans-serif" font-size="11" fill="#5B6066" font-weight="500">Юго-Запад</text>
|
||||
<text x="680" y="380" font-family="Inter,sans-serif" font-size="11" fill="#5B6066" font-weight="500">Уралмаш</text>
|
||||
<text x="980" y="420" font-family="Inter,sans-serif" font-size="11" fill="#5B6066" font-weight="500">Эльмаш</text>
|
||||
<g id="markers">
|
||||
<circle cx="220" cy="140" r="6" fill="#B3261E" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="250" cy="160" r="6" fill="#B3261E" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="310" cy="155" r="5" fill="#B3261E" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="940" cy="290" r="5" fill="#B3261E" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="290" cy="130" r="5" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="340" cy="170" r="6" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="520" cy="180" r="5" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="570" cy="200" r="6" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="650" cy="170" r="5" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="720" cy="220" r="6" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="790" cy="190" r="5" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="900" cy="260" r="6" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="380" cy="360" r="5" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="420" cy="340" r="6" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="700" cy="400" r="5" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="240" cy="180" r="6" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="610" cy="140" r="5" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="670" cy="190" r="6" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="800" cy="230" r="5" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="450" cy="280" r="6" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="500" cy="320" r="5" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="970" cy="380" r="6" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="1020" cy="410" r="5" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="320" cy="220" r="7" fill="#0A7A3A" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="560" cy="240" r="6" fill="#0A7A3A" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="640" cy="280" r="7" fill="#0A7A3A" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="730" cy="320" r="6" fill="#0A7A3A" stroke="#fff" stroke-width="2"/>
|
||||
<circle cx="850" cy="350" r="7" fill="#0A7A3A" stroke="#fff" stroke-width="2"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="map-controls">
|
||||
<button aria-label="Zoom in">+</button>
|
||||
<button aria-label="Zoom out">–</button>
|
||||
<button aria-label="Сбросить вид">⤢</button>
|
||||
</div>
|
||||
<div class="map-legend">
|
||||
<h4>Sold % за 6 мес</h4>
|
||||
<div class="row"><span class="pip" style="background:#B3261E"></span>< 40 % · риск затоваривания</div>
|
||||
<div class="row"><span class="pip" style="background:#F59E0B"></span>40–65 % · средний темп</div>
|
||||
<div class="row"><span class="pip" style="background:#14B8A6"></span>65–80 % · хороший темп</div>
|
||||
<div class="row"><span class="pip" style="background:#0A7A3A"></span>80+ % · близко к закрытию</div>
|
||||
</div>
|
||||
<div class="map-tooltip" role="tooltip">
|
||||
<div class="name">ЖК «Каменные палатки» · PRINZIP</div>
|
||||
<div class="meta">Академический · комфорт · 1 824 кв</div>
|
||||
<div class="stat"><span>Sold %</span><b style="color:var(--success);">78 %</b></div>
|
||||
<div class="stat"><span>Срок продаж</span><b>22 мес</b></div>
|
||||
<div class="stat"><span>Ср. цена</span><b>173 тыс ₽/м²</b></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:12px;font-size:12px;color:var(--fg-tertiary);">Карта стилизована для превью. В продукте — Leaflet с базой 2GIS, клик → /analytics/objects/[id]</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Динамика рынка — 14 месяцев</h2>
|
||||
<div class="sub">Объём ДДУ (Росреестр) и две линии: sold % портфеля и средняя цена м²</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="chip" aria-pressed="true">14 мес</button>
|
||||
<button class="chip">12 мес</button>
|
||||
<button class="chip">6 мес</button>
|
||||
<button class="btn btn-secondary btn-compact">Export CSV ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pulse-wrap">
|
||||
<div class="pulse-chart">
|
||||
<svg viewBox="0 0 800 280" preserveAspectRatio="none">
|
||||
<g stroke="#EEF0F3" stroke-width="1">
|
||||
<line x1="0" y1="56" x2="800" y2="56"/>
|
||||
<line x1="0" y1="112" x2="800" y2="112"/>
|
||||
<line x1="0" y1="168" x2="800" y2="168"/>
|
||||
<line x1="0" y1="224" x2="800" y2="224"/>
|
||||
</g>
|
||||
<g fill="#DBEAFE">
|
||||
<rect x="20" y="180" width="36" height="100"/>
|
||||
<rect x="76" y="190" width="36" height="90"/>
|
||||
<rect x="132" y="170" width="36" height="110"/>
|
||||
<rect x="188" y="160" width="36" height="120"/>
|
||||
<rect x="244" y="150" width="36" height="130"/>
|
||||
<rect x="300" y="140" width="36" height="140"/>
|
||||
<rect x="356" y="155" width="36" height="125"/>
|
||||
<rect x="412" y="130" width="36" height="150"/>
|
||||
<rect x="468" y="120" width="36" height="160"/>
|
||||
<rect x="524" y="135" width="36" height="145"/>
|
||||
<rect x="580" y="115" width="36" height="165"/>
|
||||
<rect x="636" y="105" width="36" height="175"/>
|
||||
<rect x="692" y="125" width="36" height="155"/>
|
||||
<rect x="748" y="110" width="36" height="170"/>
|
||||
</g>
|
||||
<polyline fill="none" stroke="#1D4ED8" stroke-width="2.5" points="38,90 94,82 150,98 206,76 262,68 318,72 374,84 430,60 486,52 542,66 598,48 654,42 710,58 766,46"/>
|
||||
<g fill="#1D4ED8">
|
||||
<circle cx="38" cy="90" r="3"/><circle cx="94" cy="82" r="3"/><circle cx="150" cy="98" r="3"/><circle cx="206" cy="76" r="3"/>
|
||||
<circle cx="262" cy="68" r="3"/><circle cx="318" cy="72" r="3"/><circle cx="374" cy="84" r="3"/><circle cx="430" cy="60" r="3"/>
|
||||
<circle cx="486" cy="52" r="3"/><circle cx="542" cy="66" r="3"/><circle cx="598" cy="48" r="3"/><circle cx="654" cy="42" r="3"/>
|
||||
<circle cx="710" cy="58" r="3"/><circle cx="766" cy="46" r="3"/>
|
||||
</g>
|
||||
<polyline fill="none" stroke="#F59E0B" stroke-width="2" points="38,140 94,138 150,134 206,128 262,126 318,120 374,116 430,112 486,108 542,102 598,98 654,92 710,88 766,84"/>
|
||||
<g font-family="ui-monospace,Menlo" font-size="9" fill="#73767E">
|
||||
<text x="34" y="276">фев</text><text x="90" y="276">мар</text><text x="146" y="276">апр</text><text x="202" y="276">май</text>
|
||||
<text x="258" y="276">июн</text><text x="316" y="276">июл</text><text x="372" y="276">авг</text><text x="428" y="276">сен</text>
|
||||
<text x="484" y="276">окт</text><text x="540" y="276">ноя</text><text x="596" y="276">дек</text><text x="654" y="276">янв</text>
|
||||
<text x="710" y="276">фев</text><text x="764" y="276">мар</text>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<aside class="pulse-legend">
|
||||
<div class="leg-row"><span class="sw" style="background:#DBEAFE"></span><span class="name">Объём ДДУ</span><span class="meta">62 415</span></div>
|
||||
<div class="leg-row"><span class="sw" style="background:#1D4ED8"></span><span class="name">Sold %</span><span class="meta">61,4 % · ↓ 3,2 пп</span></div>
|
||||
<div class="leg-row"><span class="sw" style="background:#F59E0B"></span><span class="name">Цена ₽/м²</span><span class="meta">186 тыс · ↑ 12 %</span></div>
|
||||
<div style="margin-top:16px;padding-top:16px;border-top:1px solid var(--border-soft);font-size:11.5px;color:var(--fg-secondary);line-height:1.5;">
|
||||
Левая ось — sold % (синяя), правая ось — цена ₽/м² (оранжевая). Бары — объём ДДУ помесячно. Hover на точку — раскладка по классу жилья.
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Парадокс портфеля по комнатности</h2>
|
||||
<div class="sub">Доля сегмента в портфеле ДОМ.РФ против доли в сделках Росреестра за 14 мес</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="chip" aria-pressed="true">вся область</button>
|
||||
<button class="chip">Екатеринбург</button>
|
||||
<button class="chip">область без ЕКБ</button>
|
||||
<button class="btn btn-secondary btn-compact">Export CSV ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="qg-table" role="table">
|
||||
<div class="qg-row">
|
||||
<div class="qg-cell qg-name">Сегмент</div>
|
||||
<div class="qg-cell"><span style="font-size:10.5px;letter-spacing:0.04em;text-transform:uppercase;color:var(--fg-secondary);font-weight:500;">портфель ДОМ.РФ vs сделки Росреестра</span></div>
|
||||
<div class="qg-cell" style="justify-content:flex-end;"><span style="font-size:10.5px;letter-spacing:0.04em;text-transform:uppercase;color:var(--fg-secondary);font-weight:500;">Δ пп</span></div>
|
||||
</div>
|
||||
<div class="qg-row">
|
||||
<div class="qg-cell qg-name">Студии до 30 м²</div>
|
||||
<div class="qg-cell qg-bars"><div class="qg-bar supply" style="width:78%"><span class="v">24%</span></div><div class="qg-bar demand" style="width:30%"><span class="v">9%</span></div></div>
|
||||
<div class="qg-cell" style="justify-content:flex-end;"><span class="qg-delta neg">−15</span></div>
|
||||
</div>
|
||||
<div class="qg-row">
|
||||
<div class="qg-cell qg-name">1-комн. 30–45 м²</div>
|
||||
<div class="qg-cell qg-bars"><div class="qg-bar supply" style="width:88%"><span class="v">31%</span></div><div class="qg-bar demand" style="width:72%"><span class="v">24%</span></div></div>
|
||||
<div class="qg-cell" style="justify-content:flex-end;"><span class="qg-delta neg">−7</span></div>
|
||||
</div>
|
||||
<div class="qg-row">
|
||||
<div class="qg-cell qg-name">2-комн. 45–65 м²</div>
|
||||
<div class="qg-cell qg-bars"><div class="qg-bar supply" style="width:62%"><span class="v">22%</span></div><div class="qg-bar demand" style="width:66%"><span class="v">23%</span></div></div>
|
||||
<div class="qg-cell" style="justify-content:flex-end;"><span class="qg-delta flat">+1</span></div>
|
||||
</div>
|
||||
<div class="qg-row">
|
||||
<div class="qg-cell qg-name">3-комн. 65–85 м²</div>
|
||||
<div class="qg-cell qg-bars"><div class="qg-bar supply" style="width:38%"><span class="v">13%</span></div><div class="qg-bar demand" style="width:72%"><span class="v">24%</span></div></div>
|
||||
<div class="qg-cell" style="justify-content:flex-end;"><span class="qg-delta pos">+11</span></div>
|
||||
</div>
|
||||
<div class="qg-row">
|
||||
<div class="qg-cell qg-name">4+ комн. / 85+ м²</div>
|
||||
<div class="qg-cell qg-bars"><div class="qg-bar supply" style="width:32%"><span class="v">11%</span></div><div class="qg-bar demand" style="width:58%"><span class="v">20%</span></div></div>
|
||||
<div class="qg-cell" style="justify-content:flex-end;"><span class="qg-delta pos">+9</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="two-col">
|
||||
<section class="section" style="margin-bottom:0;">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Pipeline по году ввода</h2>
|
||||
<div class="sub">Объём (тыс. м²) в разрезе классов</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="btn btn-secondary btn-compact">Export CSV ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pipeline">
|
||||
<div class="pipe-row"><span class="year">2024</span><div class="stack"><div class="seg" style="width:42%;background:#93C5FD"></div><div class="seg" style="width:34%;background:#3B82F6"></div><div class="seg" style="width:18%;background:#1D4ED8"></div><div class="seg" style="width:6%;background:#1E3A8A"></div></div><span class="total">1 240</span></div>
|
||||
<div class="pipe-row"><span class="year">2025</span><div class="stack"><div class="seg" style="width:48%;background:#93C5FD"></div><div class="seg" style="width:30%;background:#3B82F6"></div><div class="seg" style="width:16%;background:#1D4ED8"></div><div class="seg" style="width:6%;background:#1E3A8A"></div></div><span class="total">1 820</span></div>
|
||||
<div class="pipe-row"><span class="year">2026</span><div class="stack"><div class="seg" style="width:52%;background:#93C5FD"></div><div class="seg" style="width:28%;background:#3B82F6"></div><div class="seg" style="width:14%;background:#1D4ED8"></div><div class="seg" style="width:6%;background:#1E3A8A"></div></div><span class="total">2 110</span></div>
|
||||
<div class="pipe-row"><span class="year">2027</span><div class="stack"><div class="seg" style="width:56%;background:#93C5FD"></div><div class="seg" style="width:26%;background:#3B82F6"></div><div class="seg" style="width:12%;background:#1D4ED8"></div><div class="seg" style="width:6%;background:#1E3A8A"></div></div><span class="total">2 580</span></div>
|
||||
<div class="pipe-row"><span class="year">2028</span><div class="stack"><div class="seg" style="width:60%;background:#93C5FD"></div><div class="seg" style="width:24%;background:#3B82F6"></div><div class="seg" style="width:11%;background:#1D4ED8"></div><div class="seg" style="width:5%;background:#1E3A8A"></div></div><span class="total">1 970</span></div>
|
||||
</div>
|
||||
<div style="margin-top:16px;display:flex;gap:16px;font-size:11.5px;color:var(--fg-secondary);flex-wrap:wrap;">
|
||||
<span style="display:inline-flex;align-items:center;gap:6px;"><span style="width:10px;height:10px;background:#93C5FD;border-radius:2px;"></span>комфорт</span>
|
||||
<span style="display:inline-flex;align-items:center;gap:6px;"><span style="width:10px;height:10px;background:#3B82F6;border-radius:2px;"></span>бизнес</span>
|
||||
<span style="display:inline-flex;align-items:center;gap:6px;"><span style="width:10px;height:10px;background:#1D4ED8;border-radius:2px;"></span>премиум</span>
|
||||
<span style="display:inline-flex;align-items:center;gap:6px;"><span style="width:10px;height:10px;background:#1E3A8A;border-radius:2px;"></span>элит</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" style="margin-bottom:0;">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Активные новостройки</h2>
|
||||
<div class="sub">Топ-7 по объёму · Я.Недвижимость · обновлено 4 ч назад</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="btn btn-secondary btn-compact">Export CSV ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<table class="ann-table">
|
||||
<thead>
|
||||
<tr><th>ЖК</th><th>Девелопер</th><th>Sold %</th><th>Ср. цена</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><a href="#">Каменные палатки</a></td><td>PRINZIP</td><td class="num">78 %</td><td class="num">173 ₽</td></tr>
|
||||
<tr><td><a href="#">Северная корона</a></td><td>Брусника</td><td class="num">71 %</td><td class="num">198 ₽</td></tr>
|
||||
<tr><td><a href="#">Чкалов</a></td><td>Атомстройком.</td><td class="num">64 %</td><td class="num">156 ₽</td></tr>
|
||||
<tr><td><a href="#">Малевич</a></td><td>Форум-групп</td><td class="num">58 %</td><td class="num">182 ₽</td></tr>
|
||||
<tr><td><a href="#">Уют</a></td><td>Атлас Девел.</td><td class="num">52 %</td><td class="num">141 ₽</td></tr>
|
||||
<tr><td><a href="#">Гольф-парк</a></td><td>КОРТРОС</td><td class="num">41 %</td><td class="num">224 ₽</td></tr>
|
||||
<tr><td><a href="#">Эталон City</a></td><td>Эталон</td><td class="num">38 %</td><td class="num">167 ₽</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Концентрация ЖК по районам</h2>
|
||||
<div class="sub">Площадь плитки — объём строительства · цвет — sold % · клик → топ девелоперов района</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="chip" aria-pressed="true">по объёму</button>
|
||||
<button class="chip">по числу ЖК</button>
|
||||
<button class="chip">по выручке</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="treemap">
|
||||
<a href="developers.html" class="tile lvl-4" style="grid-column:span 4;grid-row:span 2;"><span class="t-name">Академический</span><span class="t-meta">42 ЖК · 824 тыс м² · sold 71 %</span></a>
|
||||
<a href="developers.html" class="tile lvl-3" style="grid-column:span 3;grid-row:span 2;"><span class="t-name">Центр</span><span class="t-meta">28 ЖК · 612 тыс м² · sold 64 %</span></a>
|
||||
<a href="developers.html" class="tile lvl-5" style="grid-column:span 3;grid-row:span 2;"><span class="t-name">ВИЗ</span><span class="t-meta">31 ЖК · 588 тыс м² · sold 48 %</span></a>
|
||||
<a href="developers.html" class="tile lvl-2" style="grid-column:span 2;grid-row:span 2;"><span class="t-name">Пионерский</span><span class="t-meta">19 ЖК · 411 тыс м²</span></a>
|
||||
<a href="developers.html" class="tile lvl-4" style="grid-column:span 3;"><span class="t-name">Юго-Запад</span><span class="t-meta">14 · 386 тыс м²</span></a>
|
||||
<a href="developers.html" class="tile lvl-2" style="grid-column:span 3;"><span class="t-name">Уралмаш</span><span class="t-meta">11 · 254 тыс м²</span></a>
|
||||
<a href="developers.html" class="tile lvl-3" style="grid-column:span 2;"><span class="t-name">Эльмаш</span><span class="t-meta">8 · 198</span></a>
|
||||
<a href="developers.html" class="tile lvl-1" style="grid-column:span 2;"><span class="t-name">Сортировка</span><span class="t-meta">6 · 142</span></a>
|
||||
<a href="developers.html" class="tile lvl-3" style="grid-column:span 2;"><span class="t-name">Уктус</span><span class="t-meta">7 · 168</span></a>
|
||||
<a href="developers.html" class="tile lvl-1" style="grid-column:span 2;"><span class="t-name">Химмаш</span><span class="t-meta">4 · 96</span></a>
|
||||
<a href="developers.html" class="tile lvl-2" style="grid-column:span 3;"><span class="t-name">Широкая речка</span><span class="t-meta">5 · 124 тыс м²</span></a>
|
||||
<a href="developers.html" class="tile lvl-1" style="grid-column:span 3;"><span class="t-name">Верхняя Пышма</span><span class="t-meta">12 · 218 тыс м²</span></a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="caveat-bar">
|
||||
<span class="icon">!</span>
|
||||
<div>
|
||||
<b>Caveat по данным.</b> Sold % считается по объектам в продаже более 6 месяцев; новые ЖК со стартом < 6 мес не входят в медиану, но видны на карте. Росреестр может задерживать ДДУ до 14 дней — берём 7-дневный backfill при еженедельном пересчёте.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<details class="acc">
|
||||
<summary>Развёрнутый разрез по 17 районам области</summary>
|
||||
<div class="acc-body">Sold %, средний срок, цена м², объём в работе — по каждому из 17 районов с фильтром по классу. Открывается отдельной таблицей в /analytics/districts.</div>
|
||||
</details>
|
||||
<details class="acc">
|
||||
<summary>Методология подсчёта sold %</summary>
|
||||
<div class="acc-body">Sold % = (общее число проданных лотов по объекту) / (общее число лотов в продаже). Источник: ДДУ Росреестра матчатся с лотами портфеля ДОМ.РФ по cadastral_id + comm_name fuzzy match (порог 0.85, pg_trgm).</div>
|
||||
</details>
|
||||
<details class="acc">
|
||||
<summary>Сравнение с январём 2025 (год к году)</summary>
|
||||
<div class="acc-body">Sold % медиана: 64,6 % → 61,4 % (−3,2 пп). Объём строительства: 5,59 → 5,82 млн м² (+4,1 %). Средняя цена: 166 → 186 тыс ₽/м² (+12 %). Разрыв спрос-предложение в 3к/4+ сегменте увеличился: с +14 пп до +20 пп суммарно.</div>
|
||||
</details>
|
||||
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
515
frontend/public/developers.html
Normal file
515
frontend/public/developers.html
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>/analytics/developers — Топ-15 девелоперов · gendsgn</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
:root {
|
||||
--bg-app:#F6F7F9; --bg-card:#FFFFFF; --bg-card-alt:#FAFBFC; --bg-headline:#0F172A;
|
||||
--border-soft:#EEF0F3; --border-card:#E6E8EC; --border-strong:#D1D5DB;
|
||||
--fg-primary:#111111; --fg-secondary:#5B6066; --fg-tertiary:#73767E;
|
||||
--fg-on-dark:#E2E8F0; --fg-on-dark-muted:#94A3B8;
|
||||
--accent:#1D4ED8; --accent-hover:#1E40AF; --accent-soft:#DBEAFE; --accent-2:#F2994A;
|
||||
--success:#0A7A3A; --success-soft:#DCFCE7;
|
||||
--warn:#9A6700; --warn-soft:#FEF3C7;
|
||||
--danger:#B3261E; --danger-soft:#FEE2E2;
|
||||
--viz-1:#1D4ED8; --viz-2:#0EA5E9; --viz-3:#14B8A6; --viz-4:#F59E0B; --viz-5:#8B5CF6;
|
||||
--font-body:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
|
||||
}
|
||||
* { box-sizing:border-box; margin:0; padding:0; }
|
||||
html { background:var(--bg-app); }
|
||||
body { font-family:var(--font-body); font-size:14px; line-height:1.5; color:var(--fg-primary); font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; }
|
||||
a { color:inherit; text-decoration:none; }
|
||||
button { font:inherit; cursor:pointer; }
|
||||
.mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
|
||||
.wrap { max-width:1440px; margin:0 auto; padding:0 24px; }
|
||||
|
||||
.dev-nav { position:sticky; top:0; z-index:100; display:flex; align-items:center; gap:18px; height:38px; padding:0 18px; background:#0b0f1a; color:rgba(255,255,255,0.92); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; letter-spacing:0.04em; border-bottom:1px solid rgba(255,255,255,0.08); }
|
||||
.dev-nav .dev-label { display:inline-flex; align-items:center; gap:8px; color:#fbbf24; font-weight:600; letter-spacing:0.18em; text-transform:uppercase; white-space:nowrap; }
|
||||
.dev-nav .dev-label::before { content:''; width:6px; height:6px; border-radius:50%; background:#fbbf24; box-shadow:0 0 0 3px rgba(251,191,36,0.22); }
|
||||
.dev-nav .dev-tabs { display:inline-flex; gap:2px; align-items:center; }
|
||||
.dev-nav .dev-sep { width:1px; height:16px; background:rgba(255,255,255,0.16); margin:0 6px; }
|
||||
.dev-nav .dev-tabs a { padding:5px 11px; border-radius:5px; color:rgba(255,255,255,0.62); transition:background .12s,color .12s; }
|
||||
.dev-nav .dev-tabs a:hover { color:#fff; background:rgba(255,255,255,0.08); }
|
||||
.dev-nav .dev-tabs a[aria-current="page"] { color:#0b0f1a; background:#fbbf24; font-weight:600; }
|
||||
.dev-nav .dev-hint { margin-left:auto; color:rgba(255,255,255,0.36); white-space:nowrap; }
|
||||
@media print { .dev-nav { display:none !important; } }
|
||||
|
||||
.topbar { background:var(--bg-card); border-bottom:1px solid var(--border-card); }
|
||||
.topbar-inner { display:flex; align-items:center; justify-content:space-between; height:56px; }
|
||||
.brand { display:inline-flex; align-items:center; gap:8px; font-weight:700; font-size:15px; color:var(--fg-primary); letter-spacing:-0.01em; }
|
||||
.brand-mark { width:22px; height:22px; border-radius:6px; background:var(--accent); display:grid; place-items:center; color:#fff; font-size:11px; font-weight:700; }
|
||||
.brand-mark::before { content:'gd'; }
|
||||
.topbar-user { display:flex; align-items:center; gap:12px; font-size:13px; color:var(--fg-secondary); }
|
||||
.topbar-user .who { display:flex; align-items:center; gap:8px; padding:6px 12px; border-radius:6px; background:var(--bg-card-alt); border:1px solid var(--border-card); }
|
||||
.topbar-user .avatar { width:22px; height:22px; border-radius:50%; background:var(--accent-soft); color:var(--accent); display:grid; place-items:center; font-weight:600; font-size:10px; }
|
||||
|
||||
.crumbs { display:flex; gap:8px; align-items:center; padding-top:16px; font-size:12.5px; color:var(--fg-secondary); }
|
||||
.crumbs a { color:var(--fg-secondary); }
|
||||
.crumbs a:hover { color:var(--accent); text-decoration:underline; text-underline-offset:3px; }
|
||||
.crumbs .sep { color:var(--fg-tertiary); }
|
||||
.crumbs .last { color:var(--fg-primary); }
|
||||
|
||||
.page-head { padding:8px 0 16px; display:flex; justify-content:space-between; align-items:flex-end; gap:24px; }
|
||||
.page-head h1 { font-size:22px; line-height:1.25; font-weight:600; letter-spacing:-0.01em; }
|
||||
.page-head .sub { font-size:13px; color:var(--fg-secondary); margin-top:4px; }
|
||||
.page-head .right { display:flex; gap:8px; align-items:center; }
|
||||
|
||||
.a-tabs { display:flex; gap:2px; border-bottom:1px solid var(--border-card); margin-bottom:16px; overflow-x:auto; }
|
||||
.a-tabs a { padding:10px 14px; font-size:13px; font-weight:500; color:var(--fg-secondary); border-bottom:2px solid transparent; margin-bottom:-1px; white-space:nowrap; }
|
||||
.a-tabs a:hover { color:var(--fg-primary); }
|
||||
.a-tabs a[aria-current="page"] { color:var(--accent); border-bottom-color:var(--accent); font-weight:600; }
|
||||
|
||||
.kpi-row { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:24px; }
|
||||
.kpi { background:var(--bg-card); border:1px solid var(--border-card); border-radius:12px; padding:16px 18px; }
|
||||
.kpi .label { font-size:11px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; }
|
||||
.kpi .value { font-size:28px; line-height:1.15; font-weight:600; color:var(--fg-primary); letter-spacing:-0.015em; margin-top:8px; }
|
||||
.kpi .value small { font-size:14px; color:var(--fg-secondary); font-weight:500; margin-left:4px; }
|
||||
.kpi .hint { font-size:12.5px; color:var(--fg-secondary); margin-top:6px; }
|
||||
.kpi .delta { display:inline-flex; align-items:center; gap:4px; font-size:12px; font-weight:600; margin-top:8px; padding:2px 8px; border-radius:4px; font-variant-numeric:tabular-nums; }
|
||||
.kpi .delta.pos { color:var(--success); background:var(--success-soft); }
|
||||
.kpi .delta.neg { color:var(--danger); background:var(--danger-soft); }
|
||||
.kpi.who-kpi .value { font-size:20px; line-height:1.2; }
|
||||
.kpi.who-kpi .badge-row { display:flex; gap:4px; margin-top:8px; }
|
||||
|
||||
.section { background:var(--bg-card); border:1px solid var(--border-card); border-radius:12px; padding:20px; margin-bottom:24px; }
|
||||
.section-head { display:flex; align-items:flex-end; justify-content:space-between; gap:16px; margin-bottom:16px; }
|
||||
.section-head h2 { font-size:18px; line-height:1.25; font-weight:600; letter-spacing:-0.01em; }
|
||||
.section-head .sub { font-size:12.5px; color:var(--fg-secondary); margin-top:4px; }
|
||||
.section-head .right { display:flex; gap:8px; align-items:center; }
|
||||
|
||||
.btn { display:inline-flex; align-items:center; gap:6px; height:36px; padding:0 16px; border-radius:8px; font-weight:500; font-size:13.5px; border:1px solid transparent; transition:all .12s; }
|
||||
.btn-primary { background:var(--accent); color:#fff; border-color:var(--accent); }
|
||||
.btn-primary:hover { background:var(--accent-hover); border-color:var(--accent-hover); }
|
||||
.btn-secondary { background:var(--accent-2); color:#fff; border-color:var(--accent-2); }
|
||||
.btn-secondary:hover { filter:brightness(0.94); }
|
||||
.btn-tertiary { background:transparent; color:var(--fg-primary); border-color:var(--border-card); }
|
||||
.btn-tertiary:hover { border-color:var(--fg-primary); }
|
||||
.btn-compact { height:32px; padding:0 12px; font-size:12.5px; border-radius:6px; }
|
||||
|
||||
.chip { display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 12px; border-radius:14px; font-size:12px; font-weight:500; color:var(--fg-secondary); background:transparent; border:1px solid var(--border-card); transition:all .12s; cursor:pointer; }
|
||||
.chip:hover { color:var(--fg-primary); border-color:var(--fg-secondary); }
|
||||
.chip[aria-pressed="true"] { color:var(--accent); background:var(--accent-soft); border-color:var(--accent-soft); }
|
||||
|
||||
.badge { display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:600; padding:2px 8px; border-radius:4px; }
|
||||
.badge.success { color:var(--success); background:var(--success-soft); }
|
||||
.badge.warn { color:var(--warn); background:var(--warn-soft); }
|
||||
.badge.danger { color:var(--danger); background:var(--danger-soft); }
|
||||
|
||||
/* ============ SEARCH ============ */
|
||||
.search { position:relative; }
|
||||
.search input { height:32px; padding:0 12px 0 32px; border:1px solid var(--border-strong); border-radius:6px; background:var(--bg-card); font:inherit; font-size:13px; color:var(--fg-primary); width:240px; }
|
||||
.search input:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
|
||||
.search::before { content:''; position:absolute; left:10px; top:50%; transform:translateY(-50%); width:14px; height:14px; border:1.5px solid var(--fg-tertiary); border-radius:50%; box-shadow:5px 5px 0 -3px var(--fg-tertiary); pointer-events:none; }
|
||||
|
||||
/* ============ LEADERBOARD TABLE ============ */
|
||||
.lb-wrap { overflow-x:auto; }
|
||||
.lb { width:100%; border-collapse:collapse; min-width:920px; }
|
||||
.lb th { font-size:10px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; text-align:left; padding:10px 8px; border-bottom:1px solid var(--border-card); background:var(--bg-card-alt); white-space:nowrap; }
|
||||
.lb th:not(:nth-child(-n+2)) { text-align:right; }
|
||||
.lb td { font-size:13px; padding:12px 8px; border-bottom:1px solid var(--border-soft); color:var(--fg-primary); }
|
||||
.lb td:not(:nth-child(-n+2)) { text-align:right; font-variant-numeric:tabular-nums; }
|
||||
.lb tr:last-child td { border-bottom:0; }
|
||||
.lb tr:hover { background:var(--bg-card-alt); cursor:pointer; }
|
||||
.lb tr.selected { background:var(--accent-soft); }
|
||||
.lb tr.selected td { color:var(--fg-primary); }
|
||||
.lb tr.selected td:first-child { color:var(--accent); font-weight:600; }
|
||||
.lb .rank { color:var(--fg-tertiary); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11px; width:32px; }
|
||||
.lb .name { color:var(--fg-primary); font-weight:500; }
|
||||
.lb .name .sub { font-size:11px; color:var(--fg-secondary); font-weight:400; margin-top:2px; }
|
||||
.lb .pill { display:inline-flex; align-items:center; padding:2px 8px; border-radius:4px; font-size:11px; font-weight:600; font-variant-numeric:tabular-nums; }
|
||||
.lb .pill.pos { color:var(--success); background:var(--success-soft); }
|
||||
.lb .pill.neg { color:var(--danger); background:var(--danger-soft); }
|
||||
.lb .pill.flat { color:var(--fg-secondary); background:var(--bg-card-alt); }
|
||||
.lb-foot { padding-top:12px; display:flex; justify-content:space-between; align-items:center; font-size:12.5px; color:var(--fg-secondary); }
|
||||
|
||||
/* ============ VELOCITY SCATTER ============ */
|
||||
.scatter-wrap { position:relative; height:380px; padding:16px 0 32px 48px; }
|
||||
.scatter-wrap svg { width:100%; height:100%; display:block; }
|
||||
.axis-x-label { position:absolute; bottom:4px; left:50%; transform:translateX(-50%); font-size:11px; color:var(--fg-secondary); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
|
||||
.axis-y-label { position:absolute; top:50%; left:-8px; transform:translateY(-50%) rotate(-90deg); transform-origin:center; font-size:11px; color:var(--fg-secondary); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; white-space:nowrap; }
|
||||
|
||||
/* ============ COMPARE CHART ============ */
|
||||
.compare-wrap { position:relative; height:280px; padding:8px 0 24px 48px; }
|
||||
.compare-wrap svg { width:100%; height:100%; display:block; }
|
||||
.legend-row { display:flex; gap:24px; padding-top:8px; }
|
||||
.legend-row .leg { display:inline-flex; align-items:center; gap:8px; font-size:12.5px; color:var(--fg-primary); }
|
||||
.legend-row .leg .sw { width:14px; height:8px; border-radius:2px; }
|
||||
.legend-row .leg .meta { color:var(--fg-secondary); margin-left:4px; }
|
||||
|
||||
@media (max-width:1100px) {
|
||||
.kpi-row { grid-template-columns:repeat(2,1fr); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<aside class="dev-nav" aria-label="Dev navigation">
|
||||
<span class="dev-label">Превью · gendsgn</span>
|
||||
<nav class="dev-tabs" aria-label="Превью страницы">
|
||||
<a href="index.html">обзор</a>
|
||||
<a href="landing.html">лендинг</a>
|
||||
<a href="analytics.html">/analytics</a>
|
||||
<a href="site-finder.html">/site-finder</a>
|
||||
<a href="site-finder-analysis.html">/site-finder/анализ</a>
|
||||
<a href="developers.html" aria-current="page">/developers</a>
|
||||
</aside>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="wrap topbar-inner">
|
||||
<div style="display:flex;align-items:center;gap:24px;">
|
||||
<a href="landing.html" class="brand"><span class="brand-mark"></span><span>gendsgn</span></a>
|
||||
</div>
|
||||
<div class="topbar-user">
|
||||
<span style="font-size:12px;color:var(--fg-tertiary);">Свердловская обл. · 2025-Q1</span>
|
||||
<div class="who"><div class="avatar">AD</div>Алексей · PRINZIP (demo)</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
|
||||
<nav class="crumbs" aria-label="Breadcrumb">
|
||||
<a href="landing.html">gendsgn</a>
|
||||
<span class="sep">/</span>
|
||||
<a href="analytics.html">analytics</a>
|
||||
<span class="sep">/</span>
|
||||
<span class="last">developers — топ-15 девелоперов</span>
|
||||
</nav>
|
||||
|
||||
<div class="page-head">
|
||||
<div>
|
||||
<h1>Топ-15 девелоперов Свердловской области</h1>
|
||||
<div class="sub">Выбран: <b>PRINZIP</b> · кликните на строку leaderboard, чтобы сравнить с другим девелопером</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="btn btn-tertiary btn-compact">Снимок PDF</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="a-tabs" aria-label="Разделы аналитики">
|
||||
<a href="analytics.html">Свердл рынок</a>
|
||||
<a href="site-finder.html">Рекомендатор</a>
|
||||
<a href="developers.html" aria-current="page">Девелоперы</a>
|
||||
<a href="#">PRINZIP · профиль</a>
|
||||
<a href="#">Объекты</a>
|
||||
</nav>
|
||||
|
||||
<!-- 4 KPI for selected dev -->
|
||||
<div class="kpi-row">
|
||||
<div class="kpi who-kpi">
|
||||
<div class="label">Девелопер</div>
|
||||
<div class="value">PRINZIP</div>
|
||||
<div class="hint">Екатеринбург · с 2007 г.</div>
|
||||
<div class="badge-row">
|
||||
<span class="badge success">комфорт</span>
|
||||
<span class="badge warn">бизнес</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="label">Объём в Свердл</div>
|
||||
<div class="value">412<small>тыс м²</small></div>
|
||||
<div class="hint">14 ЖК в активной фазе</div>
|
||||
<span class="delta pos">↑ +28 тыс vs Q4 2025</span>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="label">Sold % (медиана)</div>
|
||||
<div class="value">74<small>%</small></div>
|
||||
<div class="hint">по 14 ЖК в продаже</div>
|
||||
<span class="delta pos">+13 пп vs рынок (61 %)</span>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div class="label">Средний метраж</div>
|
||||
<div class="value">58<small>м²</small></div>
|
||||
<div class="hint">взвешенно по лотности</div>
|
||||
<span class="delta neg">−9 м² vs рынок (67 м²)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LEADERBOARD -->
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Leaderboard — топ-15 по объёму</h2>
|
||||
<div class="sub">Sticky первая колонка при scroll · клик по строке → drawer с профилем девелопера</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="search"><input type="text" placeholder="Поиск девелопера…" /></div>
|
||||
<button class="chip" aria-pressed="true">все классы</button>
|
||||
<button class="chip">комфорт</button>
|
||||
<button class="chip">бизнес</button>
|
||||
<button class="btn btn-secondary btn-compact">Export CSV ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lb-wrap">
|
||||
<table class="lb">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Девелопер</th>
|
||||
<th>Объём, тыс м²</th>
|
||||
<th>ЖК</th>
|
||||
<th>Sold %</th>
|
||||
<th>Δ 14 мес</th>
|
||||
<th>Ср. цена ₽/м²</th>
|
||||
<th>Ср. метраж</th>
|
||||
<th>Топ-район</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="selected"><td class="rank">01</td><td class="name">PRINZIP<div class="sub">14 ЖК · комфорт+бизнес</div></td><td>412</td><td>14</td><td>74 %</td><td><span class="pill pos">+8,2 пп</span></td><td>173</td><td>58</td><td>Академический</td></tr>
|
||||
<tr><td class="rank">02</td><td class="name">Брусника<div class="sub">11 ЖК · комфорт+бизнес</div></td><td>368</td><td>11</td><td>71 %</td><td><span class="pill pos">+5,1 пп</span></td><td>198</td><td>61</td><td>Центр</td></tr>
|
||||
<tr><td class="rank">03</td><td class="name">Атомстройкомплекс<div class="sub">9 ЖК · комфорт</div></td><td>342</td><td>9</td><td>64 %</td><td><span class="pill pos">+2,8 пп</span></td><td>156</td><td>54</td><td>ВИЗ</td></tr>
|
||||
<tr><td class="rank">04</td><td class="name">Форум-групп<div class="sub">8 ЖК · комфорт+бизнес</div></td><td>298</td><td>8</td><td>62 %</td><td><span class="pill flat">+0,4 пп</span></td><td>182</td><td>63</td><td>Юго-Запад</td></tr>
|
||||
<tr><td class="rank">05</td><td class="name">КОРТРОС<div class="sub">6 ЖК · бизнес+премиум</div></td><td>284</td><td>6</td><td>54 %</td><td><span class="pill neg">−3,2 пп</span></td><td>224</td><td>72</td><td>Пионерский</td></tr>
|
||||
<tr><td class="rank">06</td><td class="name">Атлас Девелопмент<div class="sub">7 ЖК · комфорт</div></td><td>241</td><td>7</td><td>52 %</td><td><span class="pill neg">−4,8 пп</span></td><td>141</td><td>52</td><td>Уралмаш</td></tr>
|
||||
<tr><td class="rank">07</td><td class="name">Эталон<div class="sub">5 ЖК · бизнес</div></td><td>198</td><td>5</td><td>48 %</td><td><span class="pill neg">−6,1 пп</span></td><td>167</td><td>59</td><td>Центр</td></tr>
|
||||
<tr><td class="rank">08</td><td class="name">Унистрой<div class="sub">5 ЖК · комфорт</div></td><td>182</td><td>5</td><td>67 %</td><td><span class="pill pos">+3,4 пп</span></td><td>148</td><td>55</td><td>Уктус</td></tr>
|
||||
<tr><td class="rank">09</td><td class="name">Атмосфера<div class="sub">4 ЖК · комфорт</div></td><td>156</td><td>4</td><td>69 %</td><td><span class="pill pos">+4,1 пп</span></td><td>152</td><td>57</td><td>Пионерский</td></tr>
|
||||
<tr><td class="rank">10</td><td class="name">Эфес<div class="sub">4 ЖК · бизнес+премиум</div></td><td>142</td><td>4</td><td>58 %</td><td><span class="pill flat">+0,8 пп</span></td><td>211</td><td>76</td><td>Центр</td></tr>
|
||||
<tr><td class="rank">11</td><td class="name">Семь<div class="sub">3 ЖК · комфорт</div></td><td>128</td><td>3</td><td>72 %</td><td><span class="pill pos">+6,7 пп</span></td><td>167</td><td>56</td><td>ВИЗ</td></tr>
|
||||
<tr><td class="rank">12</td><td class="name">Гринстрой<div class="sub">3 ЖК · комфорт</div></td><td>116</td><td>3</td><td>49 %</td><td><span class="pill neg">−5,4 пп</span></td><td>134</td><td>51</td><td>Сортировка</td></tr>
|
||||
<tr><td class="rank">13</td><td class="name">Лидер<div class="sub">3 ЖК · комфорт</div></td><td>104</td><td>3</td><td>61 %</td><td><span class="pill pos">+1,2 пп</span></td><td>158</td><td>54</td><td>Уралмаш</td></tr>
|
||||
<tr><td class="rank">14</td><td class="name">Гранд<div class="sub">3 ЖК · бизнес</div></td><td>96</td><td>3</td><td>44 %</td><td><span class="pill neg">−8,1 пп</span></td><td>189</td><td>68</td><td>Юго-Запад</td></tr>
|
||||
<tr><td class="rank">15</td><td class="name">УГМК-Девел.<div class="sub">2 ЖК · бизнес+премиум</div></td><td>84</td><td>2</td><td>56 %</td><td><span class="pill flat">+0,2 пп</span></td><td>231</td><td>74</td><td>Верх. Пышма</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="lb-foot">
|
||||
<span>Показано 15 из 87 девелоперов в выборке. Порог — > 20 тыс м² в активной фазе.</span>
|
||||
<a href="#" style="color:var(--accent);font-weight:500;">Показать все 87 →</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- VELOCITY SCATTER -->
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Velocity-карта — объём против Δ sold %</h2>
|
||||
<div class="sub">Кто продаёт быстрее в своём масштабе · ось X — тыс. м² в активной фазе · ось Y — Δ sold % за 14 мес</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="chip" aria-pressed="true">все классы</button>
|
||||
<button class="chip">комфорт</button>
|
||||
<button class="chip">бизнес+премиум</button>
|
||||
<button class="btn btn-secondary btn-compact">Export PNG ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scatter-wrap">
|
||||
<svg viewBox="0 0 1000 380" preserveAspectRatio="xMidYMid meet">
|
||||
<!-- grid -->
|
||||
<g stroke="#EEF0F3" stroke-width="1">
|
||||
<line x1="0" y1="60" x2="1000" y2="60"/>
|
||||
<line x1="0" y1="120" x2="1000" y2="120"/>
|
||||
<line x1="0" y1="190" x2="1000" y2="190"/>
|
||||
<line x1="0" y1="260" x2="1000" y2="260"/>
|
||||
<line x1="0" y1="320" x2="1000" y2="320"/>
|
||||
<line x1="200" y1="0" x2="200" y2="380" stroke-dasharray="2,4"/>
|
||||
<line x1="400" y1="0" x2="400" y2="380" stroke-dasharray="2,4"/>
|
||||
<line x1="600" y1="0" x2="600" y2="380" stroke-dasharray="2,4"/>
|
||||
<line x1="800" y1="0" x2="800" y2="380" stroke-dasharray="2,4"/>
|
||||
</g>
|
||||
<!-- zero line -->
|
||||
<line x1="0" y1="190" x2="1000" y2="190" stroke="#5B6066" stroke-width="1.5"/>
|
||||
<text x="6" y="184" font-family="ui-monospace,Menlo" font-size="10" fill="#5B6066">0 пп — рынок</text>
|
||||
|
||||
<!-- quadrant labels -->
|
||||
<text x="990" y="36" text-anchor="end" font-family="ui-monospace,Menlo" font-size="10" fill="#0A7A3A" font-weight="600">быстрее рынка</text>
|
||||
<text x="990" y="360" text-anchor="end" font-family="ui-monospace,Menlo" font-size="10" fill="#B3261E" font-weight="600">медленнее рынка</text>
|
||||
|
||||
<!-- y axis labels -->
|
||||
<g font-family="ui-monospace,Menlo" font-size="10" fill="#73767E">
|
||||
<text x="-4" y="64" text-anchor="end">+10</text>
|
||||
<text x="-4" y="124" text-anchor="end">+5</text>
|
||||
<text x="-4" y="194" text-anchor="end">0</text>
|
||||
<text x="-4" y="264" text-anchor="end">−5</text>
|
||||
<text x="-4" y="324" text-anchor="end">−10</text>
|
||||
</g>
|
||||
<!-- x axis labels -->
|
||||
<g font-family="ui-monospace,Menlo" font-size="10" fill="#73767E">
|
||||
<text x="0" y="376">0</text>
|
||||
<text x="200" y="376" text-anchor="middle">100</text>
|
||||
<text x="400" y="376" text-anchor="middle">200</text>
|
||||
<text x="600" y="376" text-anchor="middle">300</text>
|
||||
<text x="800" y="376" text-anchor="middle">400</text>
|
||||
<text x="998" y="376" text-anchor="end">500</text>
|
||||
</g>
|
||||
|
||||
<!-- dots -->
|
||||
<g>
|
||||
<!-- PRINZIP (focused) -->
|
||||
<circle cx="824" cy="92" r="14" fill="#1D4ED8" opacity="0.18"/>
|
||||
<circle cx="824" cy="92" r="8" fill="#1D4ED8" stroke="#fff" stroke-width="2"/>
|
||||
<text x="838" y="96" font-family="Inter" font-size="12" font-weight="600" fill="#1D4ED8">PRINZIP · +8,2</text>
|
||||
|
||||
<circle cx="736" cy="129" r="7" fill="#0EA5E9" stroke="#fff" stroke-width="2"/>
|
||||
<text x="748" y="133" font-family="Inter" font-size="11" fill="#5B6066">Брусника · +5,1</text>
|
||||
|
||||
<circle cx="684" cy="151" r="7" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<text x="696" y="155" font-family="Inter" font-size="11" fill="#5B6066">Атомстройком. · +2,8</text>
|
||||
|
||||
<circle cx="596" cy="185" r="6" fill="#94A3B8" stroke="#fff" stroke-width="2"/>
|
||||
<text x="608" y="189" font-family="Inter" font-size="11" fill="#73767E">Форум-групп</text>
|
||||
|
||||
<circle cx="568" cy="234" r="6" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<text x="580" y="238" font-family="Inter" font-size="11" fill="#5B6066">КОРТРОС · −3,2</text>
|
||||
|
||||
<circle cx="482" cy="258" r="6" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<text x="494" y="262" font-family="Inter" font-size="11" fill="#5B6066">Атлас Девел.</text>
|
||||
|
||||
<circle cx="396" cy="278" r="6" fill="#B3261E" stroke="#fff" stroke-width="2"/>
|
||||
<text x="408" y="282" font-family="Inter" font-size="11" fill="#5B6066">Эталон · −6,1</text>
|
||||
|
||||
<circle cx="364" cy="142" r="6" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<text x="376" y="146" font-family="Inter" font-size="11" fill="#5B6066">Унистрой</text>
|
||||
|
||||
<circle cx="312" cy="138" r="5" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<text x="324" y="142" font-family="Inter" font-size="11" fill="#5B6066">Атмосфера</text>
|
||||
|
||||
<circle cx="284" cy="186" r="5" fill="#94A3B8" stroke="#fff" stroke-width="2"/>
|
||||
<text x="296" y="190" font-family="Inter" font-size="11" fill="#5B6066">Эфес</text>
|
||||
|
||||
<circle cx="256" cy="108" r="5" fill="#14B8A6" stroke="#fff" stroke-width="2"/>
|
||||
<text x="266" y="112" font-family="Inter" font-size="11" fill="#5B6066">Семь · +6,7</text>
|
||||
|
||||
<circle cx="232" cy="266" r="5" fill="#F59E0B" stroke="#fff" stroke-width="2"/>
|
||||
<text x="244" y="270" font-family="Inter" font-size="11" fill="#5B6066">Гринстрой</text>
|
||||
|
||||
<circle cx="208" cy="178" r="4" fill="#94A3B8" stroke="#fff" stroke-width="2"/>
|
||||
<text x="218" y="182" font-family="Inter" font-size="10.5" fill="#73767E">Лидер</text>
|
||||
|
||||
<circle cx="192" cy="298" r="4" fill="#B3261E" stroke="#fff" stroke-width="2"/>
|
||||
<text x="202" y="302" font-family="Inter" font-size="10.5" fill="#73767E">Гранд</text>
|
||||
|
||||
<circle cx="168" cy="188" r="4" fill="#94A3B8" stroke="#fff" stroke-width="2"/>
|
||||
<text x="178" y="192" font-family="Inter" font-size="10.5" fill="#73767E">УГМК-Девел.</text>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="axis-y-label">Δ sold % за 14 мес</div>
|
||||
<div class="axis-x-label">Объём, тыс. м² в активной фазе</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:24px;padding-top:12px;font-size:12px;color:var(--fg-secondary);flex-wrap:wrap;">
|
||||
<span><b style="color:var(--fg-primary);">Размер точки</b> — число ЖК в портфеле</span>
|
||||
<span><b style="color:var(--fg-primary);">Цвет</b> — статус velocity (зелёный — растёт, красный — падает)</span>
|
||||
<span style="margin-left:auto;color:var(--fg-tertiary);">38 / 40 ЖК в выборке · 2 объекта < 6 мес в продаже исключены</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- COMPARE LINE -->
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Сравнение sold % — PRINZIP vs топ-2</h2>
|
||||
<div class="sub">Кумулятивный sold % помесячно по всему портфелю; PRINZIP жирнее, Брусника и Атомстройком. для контекста</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button class="chip" aria-pressed="true">vs топ-2</button>
|
||||
<button class="chip">vs Брусника</button>
|
||||
<button class="chip">vs Атомстройком.</button>
|
||||
<button class="btn btn-secondary btn-compact">Export CSV ⤓</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="compare-wrap">
|
||||
<svg viewBox="0 0 1000 280" preserveAspectRatio="xMidYMid meet">
|
||||
<g stroke="#EEF0F3" stroke-width="1">
|
||||
<line x1="0" y1="56" x2="1000" y2="56"/>
|
||||
<line x1="0" y1="112" x2="1000" y2="112"/>
|
||||
<line x1="0" y1="168" x2="1000" y2="168"/>
|
||||
<line x1="0" y1="224" x2="1000" y2="224"/>
|
||||
</g>
|
||||
<!-- PRINZIP -->
|
||||
<polyline fill="none" stroke="#1D4ED8" stroke-width="3" points="0,210 70,196 140,180 210,164 280,150 350,134 420,118 490,104 560,92 630,80 700,72 770,66 840,60 910,56 980,52"/>
|
||||
<g fill="#1D4ED8">
|
||||
<circle cx="0" cy="210" r="3.5"/><circle cx="140" cy="180" r="3.5"/><circle cx="280" cy="150" r="3.5"/><circle cx="420" cy="118" r="3.5"/>
|
||||
<circle cx="560" cy="92" r="3.5"/><circle cx="700" cy="72" r="3.5"/><circle cx="840" cy="60" r="3.5"/><circle cx="980" cy="52" r="3.5"/>
|
||||
</g>
|
||||
<!-- Брусника -->
|
||||
<polyline fill="none" stroke="#0EA5E9" stroke-width="2" points="0,218 70,210 140,198 210,184 280,168 350,154 420,138 490,128 560,116 630,108 700,100 770,94 840,88 910,82 980,78"/>
|
||||
<!-- Атомстройком. -->
|
||||
<polyline fill="none" stroke="#14B8A6" stroke-width="2" points="0,226 70,220 140,212 210,202 280,192 350,180 420,170 490,160 560,150 630,140 700,132 770,124 840,118 910,112 980,108"/>
|
||||
<!-- y axis labels -->
|
||||
<g font-family="ui-monospace,Menlo" font-size="10" fill="#73767E">
|
||||
<text x="-4" y="60" text-anchor="end">100 %</text>
|
||||
<text x="-4" y="116" text-anchor="end">75 %</text>
|
||||
<text x="-4" y="172" text-anchor="end">50 %</text>
|
||||
<text x="-4" y="228" text-anchor="end">25 %</text>
|
||||
</g>
|
||||
<!-- x labels -->
|
||||
<g font-family="ui-monospace,Menlo" font-size="9" fill="#73767E">
|
||||
<text x="0" y="276">фев 25</text>
|
||||
<text x="140" y="276" text-anchor="middle">апр</text>
|
||||
<text x="280" y="276" text-anchor="middle">июн</text>
|
||||
<text x="420" y="276" text-anchor="middle">авг</text>
|
||||
<text x="560" y="276" text-anchor="middle">окт</text>
|
||||
<text x="700" y="276" text-anchor="middle">дек</text>
|
||||
<text x="840" y="276" text-anchor="middle">фев 26</text>
|
||||
<text x="996" y="276" text-anchor="end">мар 26</text>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="legend-row">
|
||||
<span class="leg"><span class="sw" style="background:#1D4ED8;height:10px;"></span>PRINZIP <span class="meta">74 % · +8,2 пп</span></span>
|
||||
<span class="leg"><span class="sw" style="background:#0EA5E9"></span>Брусника <span class="meta">71 % · +5,1 пп</span></span>
|
||||
<span class="leg"><span class="sw" style="background:#14B8A6"></span>Атомстройком. <span class="meta">64 % · +2,8 пп</span></span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- DRAWER (right-side) placeholder mock -->
|
||||
<section class="section">
|
||||
<div class="section-head">
|
||||
<div>
|
||||
<h2>Карточка выбранного девелопера — PRINZIP</h2>
|
||||
<div class="sub">Открывается drawer'ом справа при клике на строку leaderboard (не navigate)</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<a href="#" class="btn btn-tertiary btn-compact">Открыть профиль →</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:16px;">
|
||||
<div>
|
||||
<h3 style="font-size:11px;letter-spacing:0.04em;text-transform:uppercase;color:var(--fg-secondary);margin-bottom:8px;">Концентрация по районам</h3>
|
||||
<div style="display:flex;flex-direction:column;gap:6px;">
|
||||
<div style="display:grid;grid-template-columns:120px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>Академический</span><div style="height:6px;background:var(--accent);border-radius:3px;width:62%;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">62 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:120px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>Центр</span><div style="height:6px;background:var(--accent);border-radius:3px;width:18%;opacity:0.7;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">18 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:120px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>Юго-Запад</span><div style="height:6px;background:var(--accent);border-radius:3px;width:11%;opacity:0.55;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">11 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:120px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>Пионерский</span><div style="height:6px;background:var(--accent);border-radius:3px;width:6%;opacity:0.4;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">6 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:120px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>ВИЗ</span><div style="height:6px;background:var(--accent);border-radius:3px;width:3%;opacity:0.4;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">3 %</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="font-size:11px;letter-spacing:0.04em;text-transform:uppercase;color:var(--fg-secondary);margin-bottom:8px;">Распределение по комнатности</h3>
|
||||
<div style="display:flex;flex-direction:column;gap:6px;">
|
||||
<div style="display:grid;grid-template-columns:80px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>Студии</span><div style="height:6px;background:#93C5FD;border-radius:3px;width:18%;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">18 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:80px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>1-к</span><div style="height:6px;background:#60A5FA;border-radius:3px;width:34%;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">34 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:80px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>2-к</span><div style="height:6px;background:#3B82F6;border-radius:3px;width:28%;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">28 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:80px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>3-к</span><div style="height:6px;background:#1D4ED8;border-radius:3px;width:14%;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">14 %</span></div>
|
||||
<div style="display:grid;grid-template-columns:80px 1fr 40px;gap:8px;align-items:center;font-size:12.5px;"><span>4+</span><div style="height:6px;background:#1E3A8A;border-radius:3px;width:6%;"></div><span style="text-align:right;font-variant-numeric:tabular-nums;">6 %</span></div>
|
||||
</div>
|
||||
<div style="margin-top:12px;padding:8px 12px;background:var(--warn-soft);border-radius:6px;font-size:11.5px;color:var(--fg-primary);">
|
||||
<b style="color:var(--warn);">Gap vs рынок:</b> доля 3к/4+ — 20 % vs 44 % рыночного спроса. Недозагрузка в большом сегменте.
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="font-size:11px;letter-spacing:0.04em;text-transform:uppercase;color:var(--fg-secondary);margin-bottom:8px;">Топ-5 ЖК · drill-in</h3>
|
||||
<table class="lb" style="min-width:0;">
|
||||
<thead><tr><th>ЖК</th><th>Sold %</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="name"><a href="#" style="color:var(--accent);">Каменные палатки</a></td><td><span class="pill pos">78 %</span></td></tr>
|
||||
<tr><td class="name"><a href="#" style="color:var(--accent);">Хрустальный</a></td><td><span class="pill pos">81 %</span></td></tr>
|
||||
<tr><td class="name"><a href="#" style="color:var(--accent);">Прогресс</a></td><td><span class="pill pos">72 %</span></td></tr>
|
||||
<tr><td class="name"><a href="#" style="color:var(--accent);">Светлая роща</a></td><td><span class="pill pos">69 %</span></td></tr>
|
||||
<tr><td class="name"><a href="#" style="color:var(--accent);">Парк-холл</a></td><td><span class="pill flat">52 %</span></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
571
frontend/public/index.html
Normal file
571
frontend/public/index.html
Normal file
|
|
@ -0,0 +1,571 @@
|
|||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>gendsgn — превью нового сайта</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
:root {
|
||||
/* surface */
|
||||
--bg-app: #F6F7F9;
|
||||
--bg-card: #FFFFFF;
|
||||
--bg-card-alt: #FAFBFC;
|
||||
--bg-headline: #0F172A;
|
||||
/* borders */
|
||||
--border-soft: #EEF0F3;
|
||||
--border-card: #E6E8EC;
|
||||
--border-strong: #D1D5DB;
|
||||
/* text */
|
||||
--fg-primary: #111111;
|
||||
--fg-secondary: #5B6066;
|
||||
--fg-tertiary: #73767E;
|
||||
--fg-on-dark: #E2E8F0;
|
||||
--fg-on-dark-muted: #94A3B8;
|
||||
/* brand */
|
||||
--accent: #1D4ED8;
|
||||
--accent-hover: #1E40AF;
|
||||
--accent-soft: #DBEAFE;
|
||||
--accent-2: #F2994A;
|
||||
/* semantic */
|
||||
--success: #0A7A3A;
|
||||
--success-soft: #DCFCE7;
|
||||
--warn: #9A6700;
|
||||
--warn-soft: #FEF3C7;
|
||||
--danger: #B3261E;
|
||||
--danger-soft: #FEE2E2;
|
||||
/* viz */
|
||||
--viz-1: #1D4ED8;
|
||||
--viz-2: #0EA5E9;
|
||||
--viz-3: #14B8A6;
|
||||
--viz-4: #F59E0B;
|
||||
--viz-5: #8B5CF6;
|
||||
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-feature-settings: "tnum";
|
||||
}
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body { margin: 0; }
|
||||
body {
|
||||
background: var(--bg-app);
|
||||
color: var(--fg-primary);
|
||||
font: 14px/1.5 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-feature-settings: "tnum";
|
||||
}
|
||||
a { color: var(--accent); text-decoration: none; }
|
||||
a:hover { color: var(--accent-hover); }
|
||||
ul { margin: 0; padding: 0; list-style: none; }
|
||||
h1, h2, h3, h4 { margin: 0; font-weight: 600; text-align: left; }
|
||||
|
||||
/* preview nav (formerly dev-nav) */
|
||||
.dev-nav {
|
||||
position: sticky; top: 0; z-index: 100;
|
||||
display: flex; align-items: center; gap: 18px;
|
||||
padding: 0 20px; height: 38px;
|
||||
background: var(--bg-headline); color: #fff;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
font: 12px/1 'Inter', system-ui, sans-serif;
|
||||
}
|
||||
.dev-nav .dev-label {
|
||||
color: rgba(255,255,255,0.65); letter-spacing: 0.04em; text-transform: uppercase; font-size: 10.5px;
|
||||
display: inline-flex; align-items: center; gap: 8px;
|
||||
}
|
||||
.dev-nav .dev-label::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-2); }
|
||||
.dev-nav .dev-tabs { display: inline-flex; gap: 2px; align-items: center; }
|
||||
.dev-nav .dev-tabs a {
|
||||
padding: 6px 10px; border-radius: 6px;
|
||||
color: rgba(255,255,255,0.72); font-size: 12px; letter-spacing: 0.01em;
|
||||
transition: background .15s, color .15s;
|
||||
}
|
||||
.dev-nav .dev-tabs a:hover { color: #fff; background: rgba(255,255,255,0.08); }
|
||||
.dev-nav .dev-tabs a[aria-current="page"] { color: var(--bg-headline); background: var(--accent-2); font-weight: 600; }
|
||||
@media print { .dev-nav { display: none !important; } }
|
||||
@media (max-width: 720px) {
|
||||
.dev-nav { gap: 12px; padding: 0 12px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
|
||||
.dev-nav .dev-label { display: none; }
|
||||
}
|
||||
|
||||
/* topbar */
|
||||
.topbar {
|
||||
background: var(--bg-card);
|
||||
border-bottom: 1px solid var(--border-card);
|
||||
}
|
||||
.topbar-inner {
|
||||
max-width: 1280px; margin: 0 auto; padding: 16px 24px;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.brand { display: inline-flex; align-items: center; gap: 8px; color: var(--fg-primary); font-weight: 700; letter-spacing: -0.01em; font-size: 16px; }
|
||||
.brand-mark { width: 24px; height: 24px; border-radius: 6px; background: linear-gradient(135deg, var(--accent), #2563EB); display: inline-block; }
|
||||
.topbar-meta { display: inline-flex; gap: 18px; align-items: center; color: var(--fg-secondary); font-size: 12px; }
|
||||
.topbar-meta b { color: var(--fg-primary); font-weight: 600; }
|
||||
.topbar-meta .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--border-strong); display: inline-block; }
|
||||
|
||||
/* main layout */
|
||||
main { max-width: 1280px; margin: 0 auto; padding: 32px 24px 64px; }
|
||||
.lede { margin-bottom: 28px; max-width: 880px; }
|
||||
.eyebrow {
|
||||
display: inline-block;
|
||||
font: 500 11px/1 'Inter', system-ui, sans-serif;
|
||||
letter-spacing: 0.06em; text-transform: uppercase;
|
||||
color: var(--accent); margin-bottom: 12px;
|
||||
}
|
||||
h1 { font-size: 30px; line-height: 1.15; letter-spacing: -0.015em; margin-bottom: 12px; }
|
||||
.deck { font-size: 16px; line-height: 1.55; color: var(--fg-secondary); max-width: 760px; }
|
||||
.meta {
|
||||
margin-top: 20px;
|
||||
display: flex; flex-wrap: wrap; gap: 0;
|
||||
border: 1px solid var(--border-card); border-radius: 12px;
|
||||
background: var(--bg-card); overflow: hidden;
|
||||
}
|
||||
.meta li {
|
||||
flex: 1 1 0; min-width: 140px;
|
||||
padding: 14px 18px;
|
||||
border-right: 1px solid var(--border-card);
|
||||
font-size: 12px; color: var(--fg-secondary);
|
||||
}
|
||||
.meta li:last-child { border-right: 0; }
|
||||
.meta li b { display: block; font-size: 18px; font-weight: 600; color: var(--fg-primary); letter-spacing: -0.01em; margin-bottom: 2px; }
|
||||
|
||||
/* cards grid */
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
.card {
|
||||
display: flex; flex-direction: column;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-card);
|
||||
border-radius: 12px; overflow: hidden;
|
||||
color: inherit; transition: border-color .15s, transform .15s, box-shadow .15s;
|
||||
}
|
||||
.card:hover { border-color: var(--accent); transform: translateY(-1px); box-shadow: 0 8px 20px -8px rgba(15,23,42,0.08); }
|
||||
.card:hover .card-link { color: var(--accent-hover); }
|
||||
.card:hover .card-link::after { transform: translateX(2px); }
|
||||
.card.featured { grid-column: span 2; }
|
||||
.card.featured .thumb { height: 220px; }
|
||||
|
||||
.thumb {
|
||||
height: 160px;
|
||||
border-bottom: 1px solid var(--border-card);
|
||||
background: var(--bg-card-alt);
|
||||
position: relative; overflow: hidden;
|
||||
}
|
||||
.thumb svg { display: block; width: 100%; height: 100%; }
|
||||
|
||||
.card-body { padding: 20px 22px 22px; display: flex; flex-direction: column; flex: 1; }
|
||||
.card-eyebrow {
|
||||
display: inline-block; font: 500 10px/1 'Inter', system-ui, sans-serif;
|
||||
letter-spacing: 0.08em; text-transform: uppercase;
|
||||
color: var(--fg-tertiary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.card h3 { font-size: 18px; line-height: 1.25; letter-spacing: -0.01em; margin-bottom: 8px; }
|
||||
.card .card-lede { color: var(--fg-secondary); font-size: 13.5px; line-height: 1.5; flex: 1; }
|
||||
.card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
|
||||
.card-tag {
|
||||
font: 500 10.5px/1 'Inter', system-ui, sans-serif;
|
||||
letter-spacing: 0.02em; color: var(--fg-secondary);
|
||||
background: var(--bg-card-alt);
|
||||
border: 1px solid var(--border-card);
|
||||
padding: 4px 8px; border-radius: 6px;
|
||||
}
|
||||
.card-link {
|
||||
margin-top: 14px; font-size: 13px; font-weight: 600; color: var(--accent);
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
}
|
||||
.card-link::after { content: '→'; transition: transform .15s; }
|
||||
|
||||
/* note */
|
||||
.note {
|
||||
margin-top: 28px;
|
||||
border: 1px solid var(--warn);
|
||||
background: var(--warn-soft);
|
||||
border-radius: 12px;
|
||||
padding: 16px 20px;
|
||||
display: grid; grid-template-columns: 22px 1fr; gap: 12px; align-items: start;
|
||||
font-size: 13px; color: var(--fg-primary);
|
||||
}
|
||||
.note svg { width: 18px; height: 18px; color: var(--warn); margin-top: 1px; }
|
||||
.note b { font-weight: 600; }
|
||||
.note p { margin: 0; }
|
||||
|
||||
/* footer */
|
||||
footer {
|
||||
max-width: 1280px; margin: 0 auto; padding: 24px;
|
||||
color: var(--fg-tertiary); font-size: 12px;
|
||||
border-top: 1px solid var(--border-card);
|
||||
display: flex; flex-wrap: wrap; gap: 16px; align-items: center; justify-content: space-between;
|
||||
}
|
||||
|
||||
/* thumb illustrations — abstract page hints */
|
||||
.t-landing { background: linear-gradient(180deg, #FFFFFF 0%, #F6F7F9 100%); }
|
||||
.t-analytics { background: #FAFBFC; }
|
||||
.t-developers { background: #FAFBFC; }
|
||||
.t-sf-landing { background: linear-gradient(180deg, #F6F7F9, #EEF0F3); }
|
||||
.t-sf-analysis { background: var(--bg-headline); }
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
.grid { grid-template-columns: repeat(2, 1fr); }
|
||||
.card.featured { grid-column: span 2; }
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
main { padding: 20px 16px 48px; }
|
||||
.grid { grid-template-columns: 1fr; gap: 12px; }
|
||||
.card.featured { grid-column: span 1; }
|
||||
.card.featured .thumb { height: 160px; }
|
||||
h1 { font-size: 24px; }
|
||||
.meta li { flex: 1 1 50%; border-right: 0; border-bottom: 1px solid var(--border-card); }
|
||||
.meta li:nth-last-child(-n+1) { border-bottom: 0; }
|
||||
.topbar-inner { padding: 12px 16px; }
|
||||
.topbar-meta { font-size: 11px; gap: 10px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<aside class="dev-nav" aria-label="Preview navigation">
|
||||
<span class="dev-label">Превью · gendsgn</span>
|
||||
<nav class="dev-tabs" aria-label="Превью страницы">
|
||||
<a href="index.html" aria-current="page">обзор</a>
|
||||
<a href="landing.html">лендинг</a>
|
||||
<a href="analytics.html">/analytics</a>
|
||||
<a href="developers.html">/developers</a>
|
||||
<a href="site-finder.html">/site-finder</a>
|
||||
<a href="site-finder-analysis.html">/site-finder/анализ</a>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="topbar-inner">
|
||||
<a href="index.html" class="brand"><span class="brand-mark" aria-hidden="true"></span> gendsgn</a>
|
||||
<div class="topbar-meta">
|
||||
<span>обзор макетов</span>
|
||||
<span class="dot" aria-hidden="true"></span>
|
||||
<span><b>5</b> экранов</span>
|
||||
<span class="dot" aria-hidden="true"></span>
|
||||
<span>UI brief · v1</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
|
||||
<section class="lede">
|
||||
<span class="eyebrow">Превью нового сайта</span>
|
||||
<h1>Фасад для пилотных девелоперов</h1>
|
||||
<p class="deck">Маркетинговый лендинг и четыре продуктовых экрана: рыночная аналитика по Свердловской области, топ-15 девелоперов с velocity-картой, поиск участка по кадастру и детальный анализ с sidebar-навигацией. Сделано по UI brief — Inter, tabular-nums, density-first как DOM.РФ / Bloomberg.</p>
|
||||
<ul class="meta">
|
||||
<li><b>5</b>экранов</li>
|
||||
<li><b>Inter</b>tabular numerics</li>
|
||||
<li><b>1280 px</b>desktop · до 412 px responsive</li>
|
||||
<li><b>v1</b>UI brief · черновик</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="grid">
|
||||
|
||||
<!-- Card 1 — Landing (featured, спанит на 2 колонки) -->
|
||||
<a class="card featured" href="landing.html">
|
||||
<div class="thumb t-landing">
|
||||
<svg viewBox="0 0 720 220" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- top nav -->
|
||||
<rect x="0" y="0" width="720" height="32" fill="#FFFFFF"/>
|
||||
<rect x="0" y="31" width="720" height="1" fill="#E6E8EC"/>
|
||||
<rect x="24" y="11" width="60" height="10" rx="2" fill="#111111"/>
|
||||
<rect x="540" y="11" width="44" height="10" rx="2" fill="#E6E8EC"/>
|
||||
<rect x="600" y="11" width="44" height="10" rx="2" fill="#E6E8EC"/>
|
||||
<rect x="654" y="9" width="48" height="14" rx="3" fill="#1D4ED8"/>
|
||||
<!-- hero text -->
|
||||
<rect x="40" y="56" width="60" height="9" rx="2" fill="#F2994A"/>
|
||||
<rect x="40" y="76" width="380" height="20" rx="2" fill="#0F172A"/>
|
||||
<rect x="40" y="102" width="320" height="20" rx="2" fill="#0F172A"/>
|
||||
<rect x="40" y="136" width="280" height="9" rx="2" fill="#73767E"/>
|
||||
<rect x="40" y="152" width="240" height="9" rx="2" fill="#73767E"/>
|
||||
<rect x="40" y="180" width="100" height="22" rx="4" fill="#1D4ED8"/>
|
||||
<rect x="148" y="180" width="80" height="22" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<!-- hero illustration -->
|
||||
<rect x="460" y="56" width="232" height="146" rx="10" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<!-- paradox bars -->
|
||||
<rect x="478" y="78" width="36" height="10" rx="2" fill="#5B6066"/>
|
||||
<rect x="478" y="94" width="200" height="12" rx="2" fill="#EEF0F3"/>
|
||||
<rect x="478" y="94" width="84" height="12" rx="2" fill="#5B6066"/>
|
||||
<rect x="478" y="118" width="36" height="10" rx="2" fill="#0A7A3A"/>
|
||||
<rect x="478" y="134" width="200" height="12" rx="2" fill="#DCFCE7"/>
|
||||
<rect x="478" y="134" width="156" height="12" rx="2" fill="#0A7A3A"/>
|
||||
<rect x="478" y="160" width="160" height="9" rx="2" fill="#E6E8EC"/>
|
||||
<rect x="478" y="176" width="120" height="9" rx="2" fill="#E6E8EC"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<span class="card-eyebrow">Маркетинговый лендинг</span>
|
||||
<h3>Лендинг для пилотных девелоперов</h3>
|
||||
<p class="card-lede">Hero «Спрос смещается быстрее, чем ваш портфель», парадокс «что строят / что продают» по 5 сегментам, три продуктовых модуля, прайс 30 тыс ₽/мес с честным дисклеймером pre-revenue, FAQ.</p>
|
||||
<div class="card-tags">
|
||||
<span class="card-tag">Hero + parados</span>
|
||||
<span class="card-tag">3 product cards</span>
|
||||
<span class="card-tag">Pricing</span>
|
||||
<span class="card-tag">FAQ</span>
|
||||
</div>
|
||||
<span class="card-link">Открыть превью</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Card 2 — Analytics -->
|
||||
<a class="card" href="analytics.html">
|
||||
<div class="thumb t-analytics">
|
||||
<svg viewBox="0 0 360 160" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- headline-bar -->
|
||||
<rect x="16" y="16" width="328" height="22" rx="4" fill="#0F172A"/>
|
||||
<rect x="24" y="22" width="36" height="10" rx="2" fill="#F2994A"/>
|
||||
<rect x="68" y="23" width="220" height="8" rx="2" fill="#E2E8F0"/>
|
||||
<!-- kpi row -->
|
||||
<rect x="16" y="46" width="78" height="36" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="98" y="46" width="78" height="36" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="180" y="46" width="78" height="36" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="262" y="46" width="82" height="36" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="20" y="52" width="32" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="102" y="52" width="32" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="184" y="52" width="32" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="266" y="52" width="32" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="20" y="62" width="48" height="12" rx="2" fill="#111111"/>
|
||||
<rect x="102" y="62" width="42" height="12" rx="2" fill="#111111"/>
|
||||
<rect x="184" y="62" width="44" height="12" rx="2" fill="#111111"/>
|
||||
<rect x="266" y="62" width="50" height="12" rx="2" fill="#111111"/>
|
||||
<!-- map -->
|
||||
<rect x="16" y="90" width="328" height="58" rx="6" fill="#FAFBFC" stroke="#E6E8EC"/>
|
||||
<path d="M 60 132 Q 120 100 180 116 T 320 122" stroke="#D1D5DB" stroke-width="1" fill="none"/>
|
||||
<circle cx="80" cy="118" r="5" fill="#B3261E"/>
|
||||
<circle cx="120" cy="106" r="6" fill="#F59E0B"/>
|
||||
<circle cx="156" cy="122" r="4" fill="#0EA5E9"/>
|
||||
<circle cx="190" cy="112" r="7" fill="#1D4ED8"/>
|
||||
<circle cx="226" cy="118" r="5" fill="#14B8A6"/>
|
||||
<circle cx="262" cy="108" r="6" fill="#1D4ED8"/>
|
||||
<circle cx="296" cy="122" r="4" fill="#0EA5E9"/>
|
||||
<circle cx="328" cy="116" r="5" fill="#B3261E"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<span class="card-eyebrow">Продуктовый экран</span>
|
||||
<h3>/analytics — Свердловский рынок</h3>
|
||||
<p class="card-lede">Headline-вердикт о дефиците 80+ м², 4 KPI выше fold, карта новостроек по sold %, парадокс портфеля vs реальные сделки, treemap районов.</p>
|
||||
<div class="card-tags">
|
||||
<span class="card-tag">Headline-bar</span>
|
||||
<span class="card-tag">Карта</span>
|
||||
<span class="card-tag">Treemap</span>
|
||||
</div>
|
||||
<span class="card-link">Открыть превью</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Card 3 — Developers -->
|
||||
<a class="card" href="developers.html">
|
||||
<div class="thumb t-developers">
|
||||
<svg viewBox="0 0 360 160" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- KPI row -->
|
||||
<rect x="16" y="16" width="78" height="34" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="98" y="16" width="78" height="34" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="180" y="16" width="78" height="34" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="262" y="16" width="82" height="34" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="20" y="22" width="30" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="20" y="32" width="44" height="11" rx="2" fill="#111111"/>
|
||||
<rect x="102" y="22" width="32" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="102" y="32" width="42" height="11" rx="2" fill="#111111"/>
|
||||
<rect x="184" y="22" width="28" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="184" y="32" width="40" height="11" rx="2" fill="#0A7A3A"/>
|
||||
<rect x="266" y="22" width="34" height="5" rx="1" fill="#73767E"/>
|
||||
<rect x="266" y="32" width="48" height="11" rx="2" fill="#111111"/>
|
||||
<!-- leaderboard table -->
|
||||
<rect x="16" y="58" width="200" height="90" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="16" y="58" width="200" height="14" rx="6" fill="#FAFBFC"/>
|
||||
<line x1="16" y1="72" x2="216" y2="72" stroke="#E6E8EC" stroke-width="1"/>
|
||||
<line x1="16" y1="90" x2="216" y2="90" stroke="#EEF0F3" stroke-width="1"/>
|
||||
<line x1="16" y1="108" x2="216" y2="108" stroke="#EEF0F3" stroke-width="1"/>
|
||||
<line x1="16" y1="126" x2="216" y2="126" stroke="#EEF0F3" stroke-width="1"/>
|
||||
<rect x="24" y="63" width="42" height="6" rx="1" fill="#73767E"/>
|
||||
<rect x="120" y="63" width="42" height="6" rx="1" fill="#73767E"/>
|
||||
<rect x="172" y="63" width="32" height="6" rx="1" fill="#73767E"/>
|
||||
<rect x="24" y="78" width="64" height="8" rx="1" fill="#111111"/>
|
||||
<rect x="120" y="79" width="36" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="172" y="79" width="28" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="24" y="96" width="58" height="8" rx="1" fill="#111111"/>
|
||||
<rect x="120" y="97" width="36" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="172" y="97" width="28" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="24" y="114" width="68" height="8" rx="1" fill="#111111"/>
|
||||
<rect x="120" y="115" width="36" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="172" y="115" width="28" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="24" y="132" width="54" height="8" rx="1" fill="#111111"/>
|
||||
<rect x="120" y="133" width="36" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="172" y="133" width="28" height="6" rx="1" fill="#5B6066"/>
|
||||
<!-- velocity scatter -->
|
||||
<rect x="222" y="58" width="122" height="90" rx="6" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<line x1="234" y1="138" x2="334" y2="138" stroke="#D1D5DB" stroke-width="1"/>
|
||||
<line x1="234" y1="138" x2="234" y2="68" stroke="#D1D5DB" stroke-width="1"/>
|
||||
<circle cx="248" cy="120" r="3" fill="#5B6066"/>
|
||||
<circle cx="262" cy="108" r="4" fill="#5B6066"/>
|
||||
<circle cx="278" cy="98" r="3" fill="#0EA5E9"/>
|
||||
<circle cx="294" cy="86" r="5" fill="#1D4ED8"/>
|
||||
<circle cx="306" cy="106" r="3" fill="#F59E0B"/>
|
||||
<circle cx="318" cy="116" r="4" fill="#5B6066"/>
|
||||
<circle cx="328" cy="92" r="3" fill="#14B8A6"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<span class="card-eyebrow">Продуктовый экран</span>
|
||||
<h3>/developers — Топ-15 девелоперов</h3>
|
||||
<p class="card-lede">Search + leaderboard на 15 девелоперов, scatter «Velocity vs объём» с осями (X: тыс м², Y: Δ sold % за 14 мес), сравнение PRINZIP с топ-2 за 14 месяцев.</p>
|
||||
<div class="card-tags">
|
||||
<span class="card-tag">Leaderboard</span>
|
||||
<span class="card-tag">Scatter</span>
|
||||
<span class="card-tag">Export CSV</span>
|
||||
</div>
|
||||
<span class="card-link">Открыть превью</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Card 4 — Site Finder Landing -->
|
||||
<a class="card" href="site-finder.html">
|
||||
<div class="thumb t-sf-landing">
|
||||
<svg viewBox="0 0 360 160" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- map background -->
|
||||
<rect x="0" y="0" width="360" height="160" fill="#F6F7F9"/>
|
||||
<!-- river -->
|
||||
<path d="M 0 90 Q 80 60 160 100 T 360 90" stroke="#DBEAFE" stroke-width="14" fill="none"/>
|
||||
<!-- streets grid -->
|
||||
<g stroke="#EEF0F3" stroke-width="1">
|
||||
<line x1="0" y1="40" x2="360" y2="40"/>
|
||||
<line x1="0" y1="120" x2="360" y2="120"/>
|
||||
<line x1="80" y1="0" x2="80" y2="160"/>
|
||||
<line x1="220" y1="0" x2="220" y2="160"/>
|
||||
<line x1="290" y1="0" x2="290" y2="160"/>
|
||||
</g>
|
||||
<!-- input card (floating) -->
|
||||
<rect x="16" y="16" width="160" height="58" rx="8" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="26" y="24" width="42" height="6" rx="1" fill="#73767E"/>
|
||||
<rect x="26" y="36" width="120" height="20" rx="4" fill="#FAFBFC" stroke="#E6E8EC"/>
|
||||
<rect x="32" y="42" width="74" height="6" rx="1" fill="#111111"/>
|
||||
<rect x="26" y="62" width="48" height="8" rx="2" fill="#1D4ED8"/>
|
||||
<!-- selected parcel highlight -->
|
||||
<rect x="218" y="92" width="52" height="44" rx="4" fill="#DBEAFE" stroke="#1D4ED8" stroke-dasharray="3 3" stroke-width="1.5"/>
|
||||
<!-- pins -->
|
||||
<circle cx="120" cy="60" r="5" fill="#5B6066"/>
|
||||
<circle cx="170" cy="30" r="5" fill="#0A7A3A"/>
|
||||
<circle cx="250" cy="50" r="5" fill="#F59E0B"/>
|
||||
<circle cx="310" cy="80" r="5" fill="#5B6066"/>
|
||||
<circle cx="200" cy="140" r="5" fill="#B3261E"/>
|
||||
<circle cx="120" cy="130" r="5" fill="#0EA5E9"/>
|
||||
<!-- selected card (floating right) -->
|
||||
<rect x="200" y="16" width="144" height="62" rx="8" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="210" y="24" width="44" height="6" rx="1" fill="#F2994A"/>
|
||||
<rect x="210" y="34" width="90" height="9" rx="2" fill="#111111"/>
|
||||
<rect x="210" y="50" width="60" height="6" rx="1" fill="#73767E"/>
|
||||
<rect x="210" y="60" width="40" height="6" rx="1" fill="#73767E"/>
|
||||
<rect x="278" y="58" width="56" height="14" rx="3" fill="#1D4ED8"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<span class="card-eyebrow">Site Finder · Screen 1</span>
|
||||
<h3>/site-finder — карта-first entry</h3>
|
||||
<p class="card-lede">Полноэкранная SVG-карта Екатеринбурга, поле кадастра с примером формата, недавние участки, sticky-карточка выбранного парцела с 7 параметрами и кнопками «Карточка ЕГРН» + «Анализ».</p>
|
||||
<div class="card-tags">
|
||||
<span class="card-tag">Карта-first</span>
|
||||
<span class="card-tag">Кадастр</span>
|
||||
</div>
|
||||
<span class="card-link">Открыть превью</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Card 5 — Site Finder Analysis -->
|
||||
<a class="card" href="site-finder-analysis.html">
|
||||
<div class="thumb t-sf-analysis">
|
||||
<svg viewBox="0 0 360 160" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- top bar -->
|
||||
<rect x="0" y="0" width="360" height="22" fill="#0F172A"/>
|
||||
<rect x="12" y="8" width="44" height="7" rx="1" fill="#94A3B8"/>
|
||||
<rect x="68" y="8" width="120" height="7" rx="1" fill="#E2E8F0"/>
|
||||
<!-- sidebar -->
|
||||
<rect x="0" y="22" width="92" height="138" fill="#FFFFFF"/>
|
||||
<line x1="92" y1="22" x2="92" y2="160" stroke="#E6E8EC"/>
|
||||
<rect x="10" y="34" width="20" height="6" rx="1" fill="#5B6066"/>
|
||||
<!-- 5 sidebar items, item 3 active -->
|
||||
<rect x="8" y="48" width="76" height="14" rx="4" fill="#FAFBFC"/>
|
||||
<circle cx="14" cy="55" r="2" fill="#73767E"/>
|
||||
<rect x="22" y="52" width="52" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="8" y="64" width="76" height="14" rx="4" fill="#FAFBFC"/>
|
||||
<circle cx="14" cy="71" r="2" fill="#73767E"/>
|
||||
<rect x="22" y="68" width="46" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="8" y="80" width="76" height="14" rx="4" fill="#DBEAFE"/>
|
||||
<circle cx="14" cy="87" r="2" fill="#1D4ED8"/>
|
||||
<rect x="22" y="84" width="56" height="6" rx="1" fill="#1D4ED8"/>
|
||||
<rect x="8" y="96" width="76" height="14" rx="4" fill="#FAFBFC"/>
|
||||
<circle cx="14" cy="103" r="2" fill="#73767E"/>
|
||||
<rect x="22" y="100" width="48" height="6" rx="1" fill="#5B6066"/>
|
||||
<rect x="8" y="112" width="76" height="14" rx="4" fill="#FAFBFC"/>
|
||||
<circle cx="14" cy="119" r="2" fill="#73767E"/>
|
||||
<rect x="22" y="116" width="50" height="6" rx="1" fill="#5B6066"/>
|
||||
<!-- main pane -->
|
||||
<rect x="92" y="22" width="268" height="138" fill="#F6F7F9"/>
|
||||
<!-- headline -->
|
||||
<rect x="104" y="34" width="244" height="22" rx="4" fill="#0F172A"/>
|
||||
<rect x="112" y="40" width="32" height="10" rx="2" fill="#F2994A"/>
|
||||
<rect x="150" y="41" width="148" height="8" rx="2" fill="#E2E8F0"/>
|
||||
<!-- 4 settings -->
|
||||
<rect x="104" y="62" width="58" height="16" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="166" y="62" width="58" height="16" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="228" y="62" width="58" height="16" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="290" y="62" width="58" height="16" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<!-- planning previews -->
|
||||
<rect x="104" y="86" width="58" height="40" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="110" y="92" width="46" height="20" rx="2" fill="#FAFBFC"/>
|
||||
<rect x="166" y="86" width="58" height="40" rx="4" fill="#FFFFFF" stroke="#1D4ED8"/>
|
||||
<rect x="172" y="92" width="46" height="20" rx="2" fill="#DBEAFE"/>
|
||||
<rect x="228" y="86" width="58" height="40" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="234" y="92" width="46" height="20" rx="2" fill="#FAFBFC"/>
|
||||
<rect x="290" y="86" width="58" height="40" rx="4" fill="#FFFFFF" stroke="#E6E8EC"/>
|
||||
<rect x="296" y="92" width="46" height="20" rx="2" fill="#FAFBFC"/>
|
||||
<!-- recommendation bar -->
|
||||
<rect x="104" y="132" width="244" height="20" rx="4" fill="#0F172A"/>
|
||||
<rect x="112" y="138" width="120" height="8" rx="2" fill="#E2E8F0"/>
|
||||
<rect x="284" y="135" width="58" height="14" rx="3" fill="#F2994A"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<span class="card-eyebrow">Site Finder · Screen 2 + 3</span>
|
||||
<h3>/site-finder/анализ — sidebar на 5 разделов</h3>
|
||||
<p class="card-lede">Sidebar: Инфо / Сети 1–1,5 км / Продажи конкурентов (3.1/3.2/3.3) / Оценка / Атмосфера. Раздел 3 — 8-секционный модуль с 4 настройками и 4 выводами (планировки с превью, остатки, ассортимент vs скорость, рекомендация).</p>
|
||||
<div class="card-tags">
|
||||
<span class="card-tag">Sidebar nav</span>
|
||||
<span class="card-tag">8-секц. модуль</span>
|
||||
<span class="card-tag">JS pane-switch</span>
|
||||
</div>
|
||||
<span class="card-link">Открыть превью</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</section>
|
||||
|
||||
<aside class="note" role="note">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
|
||||
<line x1="12" y1="9" x2="12" y2="13"/>
|
||||
<line x1="12" y1="17" x2="12.01" y2="17"/>
|
||||
</svg>
|
||||
<p><b>Все цифры — иллюстративные.</b> KPI, имена девелоперов, цены м², проценты sold, координаты пинов и кадастровые номера синтезированы под Свердловскую область для презентации макетов. Реальные fixtures из DOM.РФ / Rosreestr / Yandex Realty подключаются на этапе интеграции с продакшн-API.</p>
|
||||
</aside>
|
||||
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<span>gendsgn · превью v1 · собрано из UI brief</span>
|
||||
<span>5 экранов · Inter + tabular-nums · brief HEX-палитра</span>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,69 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="ru"><head><script data-od-sandbox-shim="">(function(){
|
||||
function makeStore(){
|
||||
var data = {};
|
||||
var api = {
|
||||
getItem: function(k){ return Object.prototype.hasOwnProperty.call(data, k) ? data[k] : null; },
|
||||
setItem: function(k, v){ data[k] = String(v); },
|
||||
removeItem: function(k){ delete data[k]; },
|
||||
clear: function(){ data = {}; },
|
||||
key: function(i){ return Object.keys(data)[i] || null; }
|
||||
};
|
||||
Object.defineProperty(api, 'length', { get: function(){ return Object.keys(data).length; } });
|
||||
return api;
|
||||
}
|
||||
function tryShim(name){
|
||||
var works = false;
|
||||
try { works = !!window[name] && typeof window[name].getItem === 'function'; void window[name].length; }
|
||||
catch (_) { works = false; }
|
||||
if (works) return;
|
||||
try { Object.defineProperty(window, name, { configurable: true, value: makeStore() }); }
|
||||
catch (_) { try { window[name] = makeStore(); } catch (__) {} }
|
||||
}
|
||||
tryShim('localStorage');
|
||||
tryShim('sessionStorage');
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!e.target || !(e.target instanceof Element)) return;
|
||||
var link = e.target.closest('a[href]');
|
||||
if (!link) return;
|
||||
var href = link.getAttribute('href');
|
||||
if (href === null) return;
|
||||
var isAnchor = href.startsWith('#') || href === '';
|
||||
if (isAnchor) {
|
||||
e.preventDefault();
|
||||
if (href === '' || href === '#') {
|
||||
window.scrollTo({ top: 0 });
|
||||
history.replaceState(null, '', ' ');
|
||||
} else {
|
||||
var targetId = href.slice(1);
|
||||
var target = targetId ? document.getElementById(targetId) : null;
|
||||
if (target) {
|
||||
target.scrollIntoView();
|
||||
location.hash === href && history.replaceState(null, '', ' ');
|
||||
location.hash = href;
|
||||
}
|
||||
}
|
||||
} else if (link.getAttribute('target') === '_blank') {
|
||||
e.preventDefault();
|
||||
let safe = false;
|
||||
try {
|
||||
var url = new URL(href, location.href);
|
||||
safe =
|
||||
url.protocol === 'http:' ||
|
||||
url.protocol === 'https:' ||
|
||||
url.protocol === 'mailto:';
|
||||
} catch (_) {}
|
||||
safe && window.open(href, '_blank', 'noopener,noreferrer');
|
||||
}
|
||||
});
|
||||
})();</script>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>gendsgn — аналитика спроса для девелоперов</title>
|
||||
<meta name="description" content="Что строят на рынке и что на самом деле продаётся. Региональная аналитика спроса на основе 6,83 млн ДДУ Росреестра, портфеля ДОМ.РФ и Яндекс.Недвижимости.">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<meta name="description" content="Что строят на рынке и что на самом деле продаётся. Региональная аналитика спроса на основе 6,83 млн ДДУ Росреестра, портфеля ДОМ.РФ и Яндекс.Недвижимости." />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
:root {
|
||||
/* Surface */
|
||||
|
|
@ -339,71 +283,68 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<aside class="dev-nav" aria-label="Dev navigation" data-od-id="path-0">
|
||||
<span class="dev-label">DEV · ТОЛЬКО ДЛЯ РАЗРАБОТКИ</span>
|
||||
<nav class="dev-tabs" aria-label="WIP страницы" data-od-id="path-0-1">
|
||||
<a href="landing.html" aria-current="page" data-od-id="path-0-1-0">лендинг</a>
|
||||
<a href="analytics.html" data-od-id="path-0-1-1">/analytics</a>
|
||||
<a href="site-finder.html" data-od-id="path-0-1-2">/site-finder</a>
|
||||
<a href="site-finder-analysis.html" data-od-id="path-0-1-3">/site-finder/анализ</a>
|
||||
<a href="monitoring.html" data-od-id="path-0-1-4">/developers</a>
|
||||
<span class="dev-sep"></span>
|
||||
<a href="audit.html" data-od-id="path-0-1-6">audit (live)</a>
|
||||
<a href="gendsgn-audit.html" data-od-id="path-0-1-7">audit (отчёт)</a>
|
||||
<aside class="dev-nav" aria-label="Dev navigation">
|
||||
<span class="dev-label">Превью · gendsgn</span>
|
||||
<nav class="dev-tabs" aria-label="Превью страницы">
|
||||
<a href="index.html">обзор</a>
|
||||
<a href="landing.html" aria-current="page">лендинг</a>
|
||||
<a href="analytics.html">/analytics</a>
|
||||
<a href="site-finder.html">/site-finder</a>
|
||||
<a href="site-finder-analysis.html">/site-finder/анализ</a>
|
||||
<a href="developers.html">/developers</a>
|
||||
</nav>
|
||||
<span class="dev-hint">временная панель · скроется в print</span>
|
||||
</aside>
|
||||
|
||||
<header class="nav" data-od-id="path-1">
|
||||
<div class="wrap nav-inner" data-od-id="path-1-0">
|
||||
<a href="#" class="brand" data-od-id="path-1-0-0"><span class="brand-mark"></span><span>gendsgn</span></a>
|
||||
<nav class="nav-links" aria-label="Основная навигация" data-od-id="path-1-0-1">
|
||||
<a href="#product" data-od-id="path-1-0-1-0">Продукт</a>
|
||||
<a href="#paradox" data-od-id="path-1-0-1-1">Аналитика спроса</a>
|
||||
<a href="#pricing" data-od-id="path-1-0-1-2">Пилот</a>
|
||||
<a href="#faq" data-od-id="path-1-0-1-3">FAQ</a>
|
||||
<header class="nav">
|
||||
<div class="wrap nav-inner">
|
||||
<a href="#" class="brand"><span class="brand-mark"></span><span>gendsgn</span></a>
|
||||
<nav class="nav-links" aria-label="Основная навигация">
|
||||
<a href="#product">Продукт</a>
|
||||
<a href="#paradox">Аналитика спроса</a>
|
||||
<a href="#pricing">Пилот</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
<a href="analytics.html" class="btn btn-tertiary" data-od-id="path-1-0-2-0">Demo аналитики →</a>
|
||||
<a href="#pricing" class="btn btn-primary" data-od-id="path-1-0-2-1">Запросить пилот</a>
|
||||
<a href="analytics.html" class="btn btn-tertiary">Demo аналитики →</a>
|
||||
<a href="#pricing" class="btn btn-primary">Запросить пилот</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="wrap" data-od-id="path-2">
|
||||
<main class="wrap">
|
||||
|
||||
<!-- ============ HERO ============ -->
|
||||
<section class="hero" data-od-id="path-2-0">
|
||||
<div class="hero-grid" data-od-id="path-2-0-0">
|
||||
<section class="hero">
|
||||
<div class="hero-grid">
|
||||
<div>
|
||||
<h1 data-od-id="path-2-0-0-0-0">Цифры рынка перед тем, как заливать фундамент.</h1>
|
||||
<h1>Цифры рынка перед тем, как заливать фундамент.</h1>
|
||||
<p class="deck">Что строят на рынке и что на самом деле продаётся — по 6,83 млн ДДУ Росреестра, портфелю ДОМ.РФ и активным новостройкам Яндекс.Недвижимости. Свердловская область, обновление еженедельно.</p>
|
||||
<div class="cta">
|
||||
<a href="#pricing" class="btn btn-primary btn-lg" data-od-id="path-2-0-0-0-2-0">Запросить пилот</a>
|
||||
<a href="analytics.html" class="btn btn-link" data-od-id="path-2-0-0-0-2-1">Открыть demo аналитики →</a>
|
||||
<a href="#pricing" class="btn btn-primary btn-lg">Запросить пилот</a>
|
||||
<a href="analytics.html" class="btn btn-link">Открыть demo аналитики →</a>
|
||||
</div>
|
||||
<p class="cta" style="margin-top:16px;color:var(--fg-tertiary);font-size:12.5px;">3 из 3 пилотных мест открыто · старт пилота — 2 недели · фикс-цена 30 000 ₽/мес</p>
|
||||
</div>
|
||||
<aside class="hero-stats" aria-label="Покрытие данных" data-od-id="path-2-0-0-1">
|
||||
<h3 data-od-id="path-2-0-0-1-0">Покрытие данных</h3>
|
||||
<div class="hero-stat" data-od-id="path-2-0-0-1-1"><span class="label">ДДУ в индексе (Росреестр)</span><span class="value">6 832 411</span></div>
|
||||
<div class="hero-stat" data-od-id="path-2-0-0-1-2"><span class="label">Объекты ДОМ.РФ в Свердловской</span><span class="value">1 482</span></div>
|
||||
<div class="hero-stat" data-od-id="path-2-0-0-1-3"><span class="label">Девелоперы в leaderboard</span><span class="value">87</span></div>
|
||||
<div class="hero-stat" data-od-id="path-2-0-0-1-4"><span class="label">Глубина истории</span><span class="value">14 мес</span></div>
|
||||
<div class="hero-stat" data-od-id="path-2-0-0-1-5"><span class="label">Обновление</span><span class="value">7 дней</span></div>
|
||||
<aside class="hero-stats" aria-label="Покрытие данных">
|
||||
<h3>Покрытие данных</h3>
|
||||
<div class="hero-stat"><span class="label">ДДУ в индексе (Росреестр)</span><span class="value">6 832 411</span></div>
|
||||
<div class="hero-stat"><span class="label">Объекты ДОМ.РФ в Свердловской</span><span class="value">1 482</span></div>
|
||||
<div class="hero-stat"><span class="label">Девелоперы в leaderboard</span><span class="value">87</span></div>
|
||||
<div class="hero-stat"><span class="label">Глубина истории</span><span class="value">14 мес</span></div>
|
||||
<div class="hero-stat"><span class="label">Обновление</span><span class="value">7 дней</span></div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ HEADLINE BAR ============ -->
|
||||
<div class="headline-bar" role="status" data-od-id="path-2-1">
|
||||
<div class="headline-bar" role="status">
|
||||
<span class="tag">Вердикт квартала</span>
|
||||
<p class="verdict">Дефицит средне-большого жилья 80+ м²: <b>37%</b> сделок Росреестра, но <b>11%</b> портфеля ДОМ.РФ. Окно сужается к <b>Q3 2026</b>.</p>
|
||||
<span class="caveat">данные: ДОМ.РФ · Росреестр · март 2026</span>
|
||||
</div>
|
||||
|
||||
<!-- ============ KPI ROW ============ -->
|
||||
<div class="kpi-row" data-od-id="path-2-2">
|
||||
<div class="kpi-row">
|
||||
<div class="kpi">
|
||||
<div class="label">Объём строительства</div>
|
||||
<div class="value">5,8 млн м²</div>
|
||||
|
|
@ -431,20 +372,20 @@
|
|||
</div>
|
||||
|
||||
<!-- ============ PARADOX SECTION ============ -->
|
||||
<div class="section-title" id="paradox" data-od-id="path-2-3">
|
||||
<div class="section-title" id="paradox">
|
||||
<div>
|
||||
<h2 data-od-id="path-2-3-0-0">Парадокс портфеля: что строят vs что продаётся</h2>
|
||||
<h2>Парадокс портфеля: что строят vs что продаётся</h2>
|
||||
<div class="sub">Доля каждого сегмента в активном портфеле ДОМ.РФ против доли в сделках Росреестра за 14 месяцев</div>
|
||||
</div>
|
||||
<a href="analytics.html" class="btn btn-link" data-od-id="path-2-3-1">Открыть в /analytics →</a>
|
||||
<a href="analytics.html" class="btn btn-link">Открыть в /analytics →</a>
|
||||
</div>
|
||||
|
||||
<section class="section paradox" data-od-id="path-2-4">
|
||||
<div class="paradox-chart" data-od-id="path-2-4-0">
|
||||
<aside class="paradox-legend" data-od-id="path-2-4-0-0">
|
||||
<h3 data-od-id="path-2-4-0-0-0">Условные обозначения</h3>
|
||||
<div class="legend-row" data-od-id="path-2-4-0-0-1"><span class="sw" style="background:var(--fg-tertiary)"></span><span class="label">Портфель ДОМ.РФ</span><span class="meta">что строят</span></div>
|
||||
<div class="legend-row" data-od-id="path-2-4-0-0-2"><span class="sw" style="background:var(--accent)"></span><span class="label">Сделки Росреестра</span><span class="meta">что покупают</span></div>
|
||||
<section class="section paradox">
|
||||
<div class="paradox-chart">
|
||||
<aside class="paradox-legend">
|
||||
<h3>Условные обозначения</h3>
|
||||
<div class="legend-row"><span class="sw" style="background:var(--fg-tertiary)"></span><span class="label">Портфель ДОМ.РФ</span><span class="meta">что строят</span></div>
|
||||
<div class="legend-row"><span class="sw" style="background:var(--accent)"></span><span class="label">Сделки Росреестра</span><span class="meta">что покупают</span></div>
|
||||
<div style="font-size:11.5px;color:var(--fg-secondary);margin-top:16px;line-height:1.5;">
|
||||
Δ пп — разница между долей в сделках и долей в портфеле. Положительная — дефицит предложения, отрицательная — затоваривание.
|
||||
</div>
|
||||
|
|
@ -498,22 +439,22 @@
|
|||
</section>
|
||||
|
||||
<!-- ============ MODULES ============ -->
|
||||
<div class="section-title" id="product" data-od-id="path-2-5">
|
||||
<div class="section-title" id="product">
|
||||
<div>
|
||||
<h2 data-od-id="path-2-5-0-0">Три рабочих модуля</h2>
|
||||
<h2>Три рабочих модуля</h2>
|
||||
<div class="sub">Не «features», а конкретные вопросы, на которые финдиректор девелопера ищет ответ</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modules" data-od-id="path-2-6">
|
||||
<div class="modules">
|
||||
|
||||
<article class="module" data-od-id="path-2-6-0">
|
||||
<div class="module-head" data-od-id="path-2-6-0-0">
|
||||
<h3 data-od-id="path-2-6-0-0-0">Аналитика спроса</h3>
|
||||
<article class="module">
|
||||
<div class="module-head">
|
||||
<h3>Аналитика спроса</h3>
|
||||
<span class="badge">/analytics</span>
|
||||
</div>
|
||||
<p>«В каких районах и сегментах сделки опережают предложение?» Разбивка sold % по комнатности, классу, году ввода. Бенчмарк против топ-15 девелоперов области.</p>
|
||||
<div class="preview" data-od-id="path-2-6-0-2">
|
||||
<div class="preview">
|
||||
<div class="preview-table" aria-hidden="true">
|
||||
<div class="row"><span>район / сегмент</span><span class="num">Δ пп</span><span class="pill">статус</span></div>
|
||||
<div class="row"><span>Академический · 3к</span><span class="num pos">+14</span><span class="pill hot">дефицит</span></div>
|
||||
|
|
@ -521,49 +462,49 @@
|
|||
<div class="row"><span>Уралмаш · 2к</span><span class="num pos">+3</span><span class="pill warm">баланс</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cta-row" data-od-id="path-2-6-0-3">
|
||||
<a href="analytics.html" class="btn btn-tertiary btn-compact" data-od-id="path-2-6-0-3-0">Открыть demo</a>
|
||||
<a href="#pricing" class="btn btn-link" data-od-id="path-2-6-0-3-1">в пилот →</a>
|
||||
<div class="cta-row">
|
||||
<a href="analytics.html" class="btn btn-tertiary btn-compact">Открыть demo</a>
|
||||
<a href="#pricing" class="btn btn-link">в пилот →</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="module" data-od-id="path-2-6-1">
|
||||
<div class="module-head" data-od-id="path-2-6-1-0">
|
||||
<h3 data-od-id="path-2-6-1-0-0">Рекомендатор площадки</h3>
|
||||
<article class="module">
|
||||
<div class="module-head">
|
||||
<h3>Рекомендатор площадки</h3>
|
||||
<span class="badge">/recommend</span>
|
||||
</div>
|
||||
<p>«Какую квартирографию закладывать на участке в Академическом, чтобы выйти за 22 месяца?» Mix по комнатности, прогноз срока 80 % продаж, расчёт выручки.</p>
|
||||
<div class="preview" data-od-id="path-2-6-1-2">
|
||||
<div class="preview">
|
||||
<div class="preview-map" aria-hidden="true">
|
||||
<svg viewBox="0 0 320 132" preserveAspectRatio="xMidYMid slice">
|
||||
<defs>
|
||||
<linearGradient id="lg1" x1="0" y1="0" x2="1" y2="0" data-od-id="path-2-6-1-2-0-0-0-0"><stop offset="0" stop-color="#cfd6e0"></stop><stop offset="1" stop-color="#dde3eb"></stop></linearGradient>
|
||||
<linearGradient id="lg1" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="#cfd6e0"/><stop offset="1" stop-color="#dde3eb"/></linearGradient>
|
||||
</defs>
|
||||
<rect width="320" height="132" fill="url(#lg1)"></rect>
|
||||
<path d="M0,80 Q80,60 160,90 T320,70" stroke="#0EA5E9" stroke-width="2" fill="none" stroke-dasharray="0"></path>
|
||||
<path d="M0,40 Q120,30 200,50 T320,40" stroke="#1D4ED8" stroke-width="2.5" fill="none"></path>
|
||||
<circle cx="60" cy="50" r="4" fill="#0A7A3A"></circle>
|
||||
<circle cx="120" cy="48" r="4" fill="#0A7A3A"></circle>
|
||||
<circle cx="180" cy="60" r="4" fill="#F2994A"></circle>
|
||||
<circle cx="220" cy="62" r="4" fill="#F2994A"></circle>
|
||||
<circle cx="260" cy="58" r="4" fill="#B3261E"></circle>
|
||||
<rect width="320" height="132" fill="url(#lg1)"/>
|
||||
<path d="M0,80 Q80,60 160,90 T320,70" stroke="#0EA5E9" stroke-width="2" fill="none" stroke-dasharray="0"/>
|
||||
<path d="M0,40 Q120,30 200,50 T320,40" stroke="#1D4ED8" stroke-width="2.5" fill="none"/>
|
||||
<circle cx="60" cy="50" r="4" fill="#0A7A3A"/>
|
||||
<circle cx="120" cy="48" r="4" fill="#0A7A3A"/>
|
||||
<circle cx="180" cy="60" r="4" fill="#F2994A"/>
|
||||
<circle cx="220" cy="62" r="4" fill="#F2994A"/>
|
||||
<circle cx="260" cy="58" r="4" fill="#B3261E"/>
|
||||
<text x="6" y="14" font-family="ui-monospace,Menlo" font-size="8" fill="#5B6066">srok %</text>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cta-row" data-od-id="path-2-6-1-3">
|
||||
<a href="site-finder.html" class="btn btn-tertiary btn-compact" data-od-id="path-2-6-1-3-0">Открыть demo</a>
|
||||
<a href="#pricing" class="btn btn-link" data-od-id="path-2-6-1-3-1">в пилот →</a>
|
||||
<div class="cta-row">
|
||||
<a href="site-finder.html" class="btn btn-tertiary btn-compact">Открыть demo</a>
|
||||
<a href="#pricing" class="btn btn-link">в пилот →</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="module" data-od-id="path-2-6-2">
|
||||
<div class="module-head" data-od-id="path-2-6-2-0">
|
||||
<h3 data-od-id="path-2-6-2-0-0">Топ-15 девелоперов</h3>
|
||||
<article class="module">
|
||||
<div class="module-head">
|
||||
<h3>Топ-15 девелоперов</h3>
|
||||
<span class="badge">/developers</span>
|
||||
</div>
|
||||
<p>«Кто продаёт быстрее в моём районе и за счёт чего?» Velocity-карта по площади и Δ sold %, фильтр по классу. Drill-down до объекта.</p>
|
||||
<div class="preview" data-od-id="path-2-6-2-2">
|
||||
<div class="preview">
|
||||
<div class="preview-feed" aria-hidden="true">
|
||||
<div class="row"><span class="dot s"></span><span class="who">PRINZIP</span><span class="meta">sold 74 %</span></div>
|
||||
<div class="row"><span class="dot b"></span><span class="who">Брусника</span><span class="meta">sold 68 %</span></div>
|
||||
|
|
@ -571,26 +512,26 @@
|
|||
<div class="row"><span class="dot d"></span><span class="who">КОРТРОС</span><span class="meta">sold 41 %</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cta-row" data-od-id="path-2-6-2-3">
|
||||
<a href="monitoring.html" class="btn btn-tertiary btn-compact" data-od-id="path-2-6-2-3-0">Открыть demo</a>
|
||||
<a href="#pricing" class="btn btn-link" data-od-id="path-2-6-2-3-1">в пилот →</a>
|
||||
<div class="cta-row">
|
||||
<a href="developers.html" class="btn btn-tertiary btn-compact">Открыть demo</a>
|
||||
<a href="#pricing" class="btn btn-link">в пилот →</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ============ PRICING ============ -->
|
||||
<div class="section-title" id="pricing" data-od-id="path-2-7">
|
||||
<div class="section-title" id="pricing">
|
||||
<div>
|
||||
<h2 data-od-id="path-2-7-0-0">Пилот — 30 000 ₽ в месяц</h2>
|
||||
<h2>Пилот — 30 000 ₽ в месяц</h2>
|
||||
<div class="sub">Один тариф, без апсейлов. 3 из 3 пилотных мест открыто, ввод данных за 2 недели.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pricing" data-od-id="path-2-8">
|
||||
<div class="pricing">
|
||||
<div class="price-card">
|
||||
<span class="tag">Пилот · 6 месяцев</span>
|
||||
<h3 data-od-id="path-2-8-0-1">gendsgn для одного девелопера</h3>
|
||||
<h3>gendsgn для одного девелопера</h3>
|
||||
<p class="sub">Полный доступ к трём модулям. Свердловская область как первый регион, остальные — по запросу.</p>
|
||||
<div class="num"><b>30 000 ₽</b><span>/ мес · фикс</span></div>
|
||||
<ul>
|
||||
|
|
@ -601,12 +542,12 @@
|
|||
<li>Экспорт в Excel и CSV для финмодели</li>
|
||||
<li>Запрос новых разрезов от пилотного клиента — приоритет</li>
|
||||
</ul>
|
||||
<a href="#" class="btn btn-primary btn-lg" style="width:100%;justify-content:center;" data-od-id="path-2-8-0-5">Запросить пилот</a>
|
||||
<a href="#" class="btn btn-primary btn-lg" style="width:100%;justify-content:center;">Запросить пилот</a>
|
||||
<div class="meta" style="margin-top:16px;">Контакт менеджера — Алексей Демидов · al@gendsgn.ru</div>
|
||||
</div>
|
||||
<div class="price-card alt">
|
||||
<span class="tag">После пилота</span>
|
||||
<h3 data-od-id="path-2-8-1-1">Региональная лицензия</h3>
|
||||
<h3>Региональная лицензия</h3>
|
||||
<p class="sub">Когда пилот закроется и продукт перейдёт к платным клиентам.</p>
|
||||
<div class="num"><b>от 120 000 ₽</b><span>/ мес · region-pack</span></div>
|
||||
<ul>
|
||||
|
|
@ -615,7 +556,7 @@
|
|||
<li>Бенчмарк против выбранных конкурентов</li>
|
||||
<li>Кастомные разрезы и custom alerting</li>
|
||||
</ul>
|
||||
<a href="#" class="btn btn-tertiary btn-lg" style="width:100%;justify-content:center;" data-od-id="path-2-8-1-5">Запросить расчёт</a>
|
||||
<a href="#" class="btn btn-tertiary btn-lg" style="width:100%;justify-content:center;">Запросить расчёт</a>
|
||||
<div class="meta" style="margin-top:16px;">Расчёт индивидуально, после квалификации пилота</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -625,16 +566,16 @@
|
|||
</div>
|
||||
|
||||
<!-- ============ FAQ ============ -->
|
||||
<div class="section-title" id="faq" data-od-id="path-2-10">
|
||||
<div class="section-title" id="faq">
|
||||
<div>
|
||||
<h2 data-od-id="path-2-10-0-0">Частые возражения</h2>
|
||||
<h2>Частые возражения</h2>
|
||||
<div class="sub">Что обычно спрашивают финдиректора прежде, чем согласиться на пилот</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="faq" data-od-id="path-2-11">
|
||||
<div class="faq">
|
||||
<div>
|
||||
<p style="font-size:13px;color:var(--fg-secondary);">Если ваше возражение не разобрано — напишите на <a href="mailto:al@gendsgn.ru" style="color:var(--accent)" data-od-id="path-2-11-0-0-0">al@gendsgn.ru</a>, ответим за 1 рабочий день.</p>
|
||||
<p style="font-size:13px;color:var(--fg-secondary);">Если ваше возражение не разобрано — напишите на <a href="mailto:al@gendsgn.ru" style="color:var(--accent)">al@gendsgn.ru</a>, ответим за 1 рабочий день.</p>
|
||||
</div>
|
||||
<div class="faq-list">
|
||||
<details class="faq-item">
|
||||
|
|
@ -666,30 +607,30 @@
|
|||
|
||||
</main>
|
||||
|
||||
<footer class="site" data-od-id="path-3">
|
||||
<div class="wrap" data-od-id="path-3-0">
|
||||
<footer class="site">
|
||||
<div class="wrap">
|
||||
<div class="row">
|
||||
<div class="col" style="max-width:280px;">
|
||||
<div class="brand" style="margin-bottom:12px;"><span class="brand-mark"></span><span>gendsgn</span></div>
|
||||
<p style="font-size:13px;color:var(--fg-secondary);line-height:1.55;">Рыночная аналитика для застройщиков. Свердловская область, далее — по запросу пилотных клиентов.</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4 data-od-id="path-3-0-0-1-0">Продукт</h4>
|
||||
<a href="analytics.html" data-od-id="path-3-0-0-1-1">Аналитика спроса</a>
|
||||
<a href="site-finder.html" data-od-id="path-3-0-0-1-2">Рекомендатор площадки</a>
|
||||
<a href="monitoring.html" data-od-id="path-3-0-0-1-3">Топ-15 девелоперов</a>
|
||||
<h4>Продукт</h4>
|
||||
<a href="analytics.html">Аналитика спроса</a>
|
||||
<a href="site-finder.html">Рекомендатор площадки</a>
|
||||
<a href="developers.html">Топ-15 девелоперов</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4 data-od-id="path-3-0-0-2-0">Команда</h4>
|
||||
<a href="#" data-od-id="path-3-0-0-2-1">О нас</a>
|
||||
<a href="#" data-od-id="path-3-0-0-2-2">Методология</a>
|
||||
<a href="#" data-od-id="path-3-0-0-2-3">Источники данных</a>
|
||||
<h4>Команда</h4>
|
||||
<a href="#">О нас</a>
|
||||
<a href="#">Методология</a>
|
||||
<a href="#">Источники данных</a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4 data-od-id="path-3-0-0-3-0">Контакты</h4>
|
||||
<a href="mailto:al@gendsgn.ru" data-od-id="path-3-0-0-3-1">al@gendsgn.ru</a>
|
||||
<a href="https://t.me/gendsgn" data-od-id="path-3-0-0-3-2">Telegram</a>
|
||||
<a href="#" data-od-id="path-3-0-0-3-3">+7 343 000 00 00</a>
|
||||
<h4>Контакты</h4>
|
||||
<a href="mailto:al@gendsgn.ru">al@gendsgn.ru</a>
|
||||
<a href="https://t.me/gendsgn">Telegram</a>
|
||||
<a href="#">+7 343 000 00 00</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="legal">
|
||||
|
|
@ -699,93 +640,5 @@
|
|||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
|
||||
<script data-od-snapshot-bridge="">(function(){
|
||||
function copyComputedStyle(source, target){
|
||||
if (!source || !target || source.nodeType !== 1 || target.nodeType !== 1) return;
|
||||
var computed = window.getComputedStyle(source);
|
||||
var style = target.getAttribute('style') || '';
|
||||
for (var i = 0; i < computed.length; i++){
|
||||
var prop = computed[i];
|
||||
style += prop + ':' + computed.getPropertyValue(prop) + ';';
|
||||
}
|
||||
target.setAttribute('style', style);
|
||||
}
|
||||
function syncElementState(source, target){
|
||||
var tag = source.tagName ? source.tagName.toLowerCase() : '';
|
||||
if (tag === 'img' && source.currentSrc) target.setAttribute('src', source.currentSrc);
|
||||
if (tag === 'input' || tag === 'textarea') target.setAttribute('value', source.value || '');
|
||||
if (tag === 'canvas') {
|
||||
try {
|
||||
var img = document.createElement('img');
|
||||
img.setAttribute('src', source.toDataURL('image/png'));
|
||||
img.setAttribute('style', target.getAttribute('style') || '');
|
||||
target.parentNode && target.parentNode.replaceChild(img, target);
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
function inlineSnapshotStyles(originalRoot, cloneRoot){
|
||||
copyComputedStyle(originalRoot, cloneRoot);
|
||||
syncElementState(originalRoot, cloneRoot);
|
||||
var originals = originalRoot.querySelectorAll('*');
|
||||
var clones = cloneRoot.querySelectorAll('*');
|
||||
var count = Math.min(originals.length, clones.length);
|
||||
for (var i = 0; i < count; i++){
|
||||
copyComputedStyle(originals[i], clones[i]);
|
||||
syncElementState(originals[i], clones[i]);
|
||||
}
|
||||
var scripts = cloneRoot.querySelectorAll('script');
|
||||
for (var s = scripts.length - 1; s >= 0; s--) scripts[s].remove();
|
||||
}
|
||||
function waitForImages(){
|
||||
var imgs = Array.prototype.slice.call(document.images || []);
|
||||
return Promise.all(imgs.map(function(img){
|
||||
if (img.complete) return Promise.resolve();
|
||||
return new Promise(function(resolve){
|
||||
img.addEventListener('load', resolve, { once: true });
|
||||
img.addEventListener('error', resolve, { once: true });
|
||||
});
|
||||
}));
|
||||
}
|
||||
function renderSnapshot(id){
|
||||
var w = Math.max(1, window.innerWidth || document.documentElement.clientWidth || 1);
|
||||
var h = Math.max(1, window.innerHeight || document.documentElement.clientHeight || 1);
|
||||
var dpr = window.devicePixelRatio || 1;
|
||||
var docW = Math.max(w, document.documentElement.scrollWidth || 0, document.body ? document.body.scrollWidth : 0);
|
||||
var docH = Math.max(h, document.documentElement.scrollHeight || 0, document.body ? document.body.scrollHeight : 0);
|
||||
var clone = document.documentElement.cloneNode(true);
|
||||
clone.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
|
||||
inlineSnapshotStyles(document.documentElement, clone);
|
||||
var serializer = new XMLSerializer();
|
||||
var html = serializer.serializeToString(clone);
|
||||
var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + w + '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '">' +
|
||||
'<foreignObject x="' + (-window.scrollX || 0) + '" y="' + (-window.scrollY || 0) + '" width="' + docW + '" height="' + docH + '">' +
|
||||
html +
|
||||
'</foreignObject></svg>';
|
||||
var img = new Image();
|
||||
img.onload = function(){
|
||||
try {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = Math.max(1, Math.floor(w * dpr));
|
||||
canvas.height = Math.max(1, Math.floor(h * dpr));
|
||||
var ctx = canvas.getContext('2d');
|
||||
if (!ctx) throw new Error('no 2d context');
|
||||
ctx.scale(dpr, dpr);
|
||||
ctx.drawImage(img, 0, 0, w, h);
|
||||
window.parent.postMessage({ type: 'od:snapshot:result', id: id, dataUrl: canvas.toDataURL('image/png'), w: canvas.width, h: canvas.height }, '*');
|
||||
} catch (err) {
|
||||
window.parent.postMessage({ type: 'od:snapshot:result', id: id, error: String(err && err.message || err) }, '*');
|
||||
}
|
||||
};
|
||||
img.onerror = function(){
|
||||
window.parent.postMessage({ type: 'od:snapshot:result', id: id, error: 'snapshot image failed' }, '*');
|
||||
};
|
||||
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
|
||||
}
|
||||
window.addEventListener('message', function(ev){
|
||||
var data = ev && ev.data;
|
||||
if (!data || data.type !== 'od:snapshot' || !data.id) return;
|
||||
waitForImages().then(function(){ renderSnapshot(String(data.id)); });
|
||||
});
|
||||
})();</script></body></html>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
1112
frontend/public/site-finder-analysis.html
Normal file
1112
frontend/public/site-finder-analysis.html
Normal file
File diff suppressed because it is too large
Load diff
483
frontend/public/site-finder.html
Normal file
483
frontend/public/site-finder.html
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>/site-finder — Поиск участка · gendsgn</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
:root {
|
||||
--bg-app:#F6F7F9; --bg-card:#FFFFFF; --bg-card-alt:#FAFBFC; --bg-headline:#0F172A;
|
||||
--border-soft:#EEF0F3; --border-card:#E6E8EC; --border-strong:#D1D5DB;
|
||||
--fg-primary:#111111; --fg-secondary:#5B6066; --fg-tertiary:#73767E;
|
||||
--fg-on-dark:#E2E8F0; --fg-on-dark-muted:#94A3B8;
|
||||
--accent:#1D4ED8; --accent-hover:#1E40AF; --accent-soft:#DBEAFE; --accent-2:#F2994A;
|
||||
--success:#0A7A3A; --success-soft:#DCFCE7;
|
||||
--warn:#9A6700; --warn-soft:#FEF3C7;
|
||||
--danger:#B3261E; --danger-soft:#FEE2E2;
|
||||
--viz-1:#1D4ED8; --viz-2:#0EA5E9; --viz-3:#14B8A6; --viz-4:#F59E0B; --viz-5:#8B5CF6;
|
||||
--font-body:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
|
||||
}
|
||||
* { box-sizing:border-box; margin:0; padding:0; }
|
||||
html, body { height:100%; }
|
||||
html { background:var(--bg-app); }
|
||||
body { font-family:var(--font-body); font-size:14px; line-height:1.5; color:var(--fg-primary); font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; overflow:hidden; }
|
||||
a { color:inherit; text-decoration:none; }
|
||||
button { font:inherit; cursor:pointer; }
|
||||
.mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
|
||||
|
||||
/* === dev nav === */
|
||||
.dev-nav { position:sticky; top:0; z-index:200; display:flex; align-items:center; gap:18px; height:38px; padding:0 18px; background:#0b0f1a; color:rgba(255,255,255,0.92); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; letter-spacing:0.04em; border-bottom:1px solid rgba(255,255,255,0.08); }
|
||||
.dev-nav .dev-label { display:inline-flex; align-items:center; gap:8px; color:#fbbf24; font-weight:600; letter-spacing:0.18em; text-transform:uppercase; white-space:nowrap; }
|
||||
.dev-nav .dev-label::before { content:''; width:6px; height:6px; border-radius:50%; background:#fbbf24; box-shadow:0 0 0 3px rgba(251,191,36,0.22); }
|
||||
.dev-nav .dev-tabs { display:inline-flex; gap:2px; align-items:center; flex-wrap:nowrap; overflow:auto; }
|
||||
.dev-nav .dev-sep { width:1px; height:16px; background:rgba(255,255,255,0.16); margin:0 6px; flex:none; }
|
||||
.dev-nav .dev-tabs a { padding:5px 10px; border-radius:5px; color:rgba(255,255,255,0.62); transition:background .12s,color .12s; white-space:nowrap; }
|
||||
.dev-nav .dev-tabs a:hover { color:#fff; background:rgba(255,255,255,0.08); }
|
||||
.dev-nav .dev-tabs a[aria-current="page"] { color:#0b0f1a; background:#fbbf24; font-weight:600; }
|
||||
.dev-nav .dev-hint { margin-left:auto; color:rgba(255,255,255,0.36); white-space:nowrap; }
|
||||
@media print { .dev-nav { display:none !important; } }
|
||||
|
||||
/* === topbar === */
|
||||
.topbar { background:var(--bg-card); border-bottom:1px solid var(--border-card); z-index:50; position:relative; }
|
||||
.topbar-inner { display:flex; align-items:center; justify-content:space-between; height:56px; padding:0 24px; }
|
||||
.topbar-left { display:flex; align-items:center; gap:32px; }
|
||||
.brand { display:inline-flex; align-items:center; gap:8px; font-weight:700; font-size:15px; color:var(--fg-primary); letter-spacing:-0.01em; }
|
||||
.brand-mark { width:22px; height:22px; border-radius:6px; background:var(--accent); display:grid; place-items:center; color:#fff; font-size:11px; font-weight:700; }
|
||||
.brand-mark::before { content:'gd'; }
|
||||
.topbar nav.main { display:flex; gap:18px; font-size:13px; color:var(--fg-secondary); }
|
||||
.topbar nav.main a { padding:6px 0; border-bottom:2px solid transparent; }
|
||||
.topbar nav.main a[aria-current="page"] { color:var(--accent); border-bottom-color:var(--accent); font-weight:600; }
|
||||
.topbar nav.main a:hover { color:var(--fg-primary); }
|
||||
.topbar-user { display:flex; align-items:center; gap:12px; font-size:13px; color:var(--fg-secondary); }
|
||||
.topbar-user .who { display:flex; align-items:center; gap:8px; padding:6px 12px; border-radius:6px; background:var(--bg-card-alt); border:1px solid var(--border-card); }
|
||||
.topbar-user .avatar { width:22px; height:22px; border-radius:50%; background:var(--accent-soft); color:var(--accent); display:grid; place-items:center; font-weight:600; font-size:10px; }
|
||||
|
||||
/* === main entry layout: map full + floating panel === */
|
||||
.stage { position:relative; height:calc(100vh - 38px - 56px); background:#eef1f5; overflow:hidden; }
|
||||
|
||||
/* === map === */
|
||||
.map { position:absolute; inset:0; }
|
||||
.map svg { width:100%; height:100%; display:block; }
|
||||
.map .grid line { stroke:#dde2ea; stroke-width:0.5; }
|
||||
.map .water { fill:#cdd9e8; }
|
||||
.map .road { fill:none; stroke:#fff; stroke-width:6; }
|
||||
.map .road-edge { fill:none; stroke:#dde2ea; stroke-width:7.5; }
|
||||
.map .road-minor { fill:none; stroke:#fff; stroke-width:3.5; }
|
||||
.map .road-minor-edge { fill:none; stroke:#dde2ea; stroke-width:4.5; }
|
||||
.map .district { fill:#fff; stroke:#dde2ea; stroke-width:0.6; }
|
||||
.map .district-label { font-family:var(--font-body); font-size:11px; font-weight:600; fill:#5b6066; letter-spacing:0.04em; text-transform:uppercase; pointer-events:none; }
|
||||
.map .parcel { stroke:#fff; stroke-width:1; cursor:pointer; transition:transform .12s, filter .12s; transform-origin:center; transform-box:fill-box; }
|
||||
.map .parcel:hover { filter:brightness(0.92); }
|
||||
.map .parcel.sel { stroke:#0F172A; stroke-width:2.5; filter:drop-shadow(0 4px 10px rgba(15,23,42,0.32)); }
|
||||
.map .pin { cursor:pointer; }
|
||||
.map .pin circle.dot { fill:var(--accent); stroke:#fff; stroke-width:3; }
|
||||
.map .pin.sel circle.dot { fill:var(--accent-2); }
|
||||
.map .pin.sel circle.halo { fill:none; stroke:var(--accent-2); stroke-width:2; opacity:0.5; }
|
||||
|
||||
/* === legend (bottom-left) === */
|
||||
.legend { position:absolute; left:24px; bottom:24px; background:var(--bg-card); border:1px solid var(--border-card); border-radius:10px; padding:14px 16px; box-shadow:0 4px 14px -8px rgba(15,23,42,0.18); min-width:240px; }
|
||||
.legend h4 { font-size:11px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:600; margin-bottom:8px; }
|
||||
.legend ul { list-style:none; display:grid; gap:6px; }
|
||||
.legend li { display:grid; grid-template-columns:14px 1fr auto; gap:8px; align-items:center; font-size:12.5px; color:var(--fg-secondary); }
|
||||
.legend li i { display:inline-block; width:12px; height:12px; border-radius:3px; }
|
||||
.legend li b { color:var(--fg-primary); font-weight:500; font-variant-numeric:tabular-nums; }
|
||||
|
||||
/* === scale/zoom (bottom-right) === */
|
||||
.map-ctrl { position:absolute; right:24px; bottom:24px; display:flex; flex-direction:column; gap:8px; }
|
||||
.map-ctrl button { width:36px; height:36px; border:1px solid var(--border-card); background:var(--bg-card); border-radius:8px; box-shadow:0 4px 14px -8px rgba(15,23,42,0.18); font-size:18px; color:var(--fg-secondary); display:grid; place-items:center; }
|
||||
.map-ctrl button:hover { color:var(--fg-primary); border-color:var(--border-strong); }
|
||||
.map-scale { position:absolute; right:80px; bottom:32px; display:flex; align-items:center; gap:6px; font-size:11px; color:var(--fg-secondary); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; background:rgba(255,255,255,0.85); padding:4px 8px; border-radius:4px; }
|
||||
.map-scale i { width:60px; height:3px; background:var(--fg-primary); position:relative; }
|
||||
.map-scale i::before, .map-scale i::after { content:''; position:absolute; width:1px; height:8px; background:var(--fg-primary); top:-2px; }
|
||||
.map-scale i::before { left:0; }
|
||||
.map-scale i::after { right:0; }
|
||||
|
||||
/* === floating entry panel (top-left) === */
|
||||
.entry { position:absolute; left:24px; top:24px; width:380px; background:var(--bg-card); border:1px solid var(--border-card); border-radius:14px; box-shadow:0 12px 36px -16px rgba(15,23,42,0.22); }
|
||||
.entry-hd { padding:18px 20px 14px; border-bottom:1px solid var(--border-soft); }
|
||||
.entry-hd .eyebrow { font-size:10.5px; letter-spacing:0.14em; text-transform:uppercase; color:var(--fg-tertiary); font-weight:600; margin-bottom:6px; }
|
||||
.entry-hd h1 { font-size:18px; line-height:1.3; font-weight:600; letter-spacing:-0.01em; }
|
||||
.entry-hd .or { color:var(--fg-secondary); font-weight:400; }
|
||||
.entry-bd { padding:16px 20px; }
|
||||
.input-row { display:grid; grid-template-columns:1fr auto; gap:8px; align-items:stretch; }
|
||||
.input { position:relative; }
|
||||
.input input { width:100%; height:44px; padding:0 14px 0 38px; border:1px solid var(--border-strong); border-radius:8px; background:var(--bg-card); font:inherit; font-size:14px; color:var(--fg-primary); font-variant-numeric:tabular-nums; letter-spacing:0.01em; }
|
||||
.input input:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
|
||||
.input::before { content:''; position:absolute; left:12px; top:50%; width:18px; height:18px; transform:translateY(-50%); background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2373767E' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'/><circle cx='12' cy='10' r='3'/></svg>") center/contain no-repeat; }
|
||||
.btn { display:inline-flex; align-items:center; justify-content:center; gap:6px; height:44px; padding:0 18px; border:0; border-radius:8px; font-weight:600; font-size:13px; transition:background .12s, color .12s; white-space:nowrap; }
|
||||
.btn-primary { background:var(--accent); color:#fff; }
|
||||
.btn-primary:hover { background:var(--accent-hover); }
|
||||
.btn-secondary { background:var(--accent-2); color:#fff; }
|
||||
.btn-secondary:hover { filter:brightness(0.95); }
|
||||
.btn-ghost { background:transparent; color:var(--fg-primary); border:1px solid var(--border-card); height:36px; padding:0 14px; font-size:12.5px; font-weight:500; }
|
||||
.btn-ghost:hover { border-color:var(--border-strong); background:var(--bg-card-alt); }
|
||||
|
||||
.entry-help { display:flex; align-items:flex-start; gap:8px; margin-top:10px; font-size:12px; color:var(--fg-secondary); line-height:1.5; }
|
||||
.entry-help i { width:14px; height:14px; border-radius:50%; border:1px solid var(--border-strong); display:grid; place-items:center; font-size:10px; color:var(--fg-tertiary); flex:none; margin-top:1px; }
|
||||
.entry-fmt { display:inline-block; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; padding:1px 6px; border-radius:4px; background:var(--bg-card-alt); border:1px solid var(--border-soft); color:var(--fg-primary); }
|
||||
|
||||
.entry-or { display:flex; align-items:center; gap:10px; margin:14px 0 6px; font-size:11px; letter-spacing:0.14em; text-transform:uppercase; color:var(--fg-tertiary); }
|
||||
.entry-or::before, .entry-or::after { content:''; flex:1; height:1px; background:var(--border-soft); }
|
||||
.entry-or span { font-weight:600; }
|
||||
|
||||
.entry-recent { padding:8px 20px 18px; }
|
||||
.entry-recent h5 { font-size:11px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:600; margin:6px 0 8px; }
|
||||
.entry-recent ul { list-style:none; display:grid; gap:4px; }
|
||||
.entry-recent li a { display:grid; grid-template-columns:1fr auto; gap:8px; padding:8px 10px; border-radius:6px; font-size:12.5px; color:var(--fg-primary); }
|
||||
.entry-recent li a:hover { background:var(--bg-card-alt); }
|
||||
.entry-recent li .meta { color:var(--fg-tertiary); font-size:11px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
|
||||
.entry-recent .cad { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; color:var(--accent); }
|
||||
.entry-recent .desc { color:var(--fg-secondary); font-size:11.5px; margin-top:2px; }
|
||||
|
||||
/* === floating selected-parcel card (right side, appears when pin selected) === */
|
||||
.sel-card { position:absolute; right:24px; top:24px; width:340px; background:var(--bg-card); border:1px solid var(--border-card); border-radius:14px; box-shadow:0 12px 36px -16px rgba(15,23,42,0.22); overflow:hidden; }
|
||||
.sel-hd { padding:14px 18px; background:var(--bg-headline); color:var(--fg-on-dark); }
|
||||
.sel-hd .tag { font-size:10px; letter-spacing:0.14em; text-transform:uppercase; color:var(--accent-2); font-weight:600; }
|
||||
.sel-hd .cad { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; color:#fff; margin-top:4px; }
|
||||
.sel-hd .verdict { font-size:12.5px; color:var(--fg-on-dark-muted); margin-top:6px; line-height:1.45; }
|
||||
.sel-hd .verdict b { color:#fff; font-weight:600; }
|
||||
.sel-body { padding:14px 18px; }
|
||||
.sel-row { display:grid; grid-template-columns:1fr auto; gap:8px; padding:8px 0; border-top:1px solid var(--border-soft); font-size:12.5px; }
|
||||
.sel-row:first-child { border-top:0; padding-top:0; }
|
||||
.sel-row .l { color:var(--fg-secondary); }
|
||||
.sel-row .v { color:var(--fg-primary); font-weight:500; font-variant-numeric:tabular-nums; }
|
||||
.sel-row .v.good { color:var(--success); }
|
||||
.sel-row .v.warn { color:var(--warn); }
|
||||
.sel-foot { display:grid; grid-template-columns:1fr 1fr; gap:8px; padding:12px 18px; background:var(--bg-card-alt); border-top:1px solid var(--border-soft); }
|
||||
.sel-foot .btn { height:36px; font-size:12.5px; padding:0 12px; }
|
||||
|
||||
/* === bottom-center stats bar === */
|
||||
.stats { position:absolute; left:50%; transform:translateX(-50%); top:24px; display:flex; gap:0; background:var(--bg-card); border:1px solid var(--border-card); border-radius:10px; box-shadow:0 4px 14px -8px rgba(15,23,42,0.18); overflow:hidden; }
|
||||
.stats .s { padding:8px 16px; font-size:12px; color:var(--fg-secondary); border-right:1px solid var(--border-soft); display:flex; gap:6px; align-items:baseline; }
|
||||
.stats .s:last-child { border-right:0; }
|
||||
.stats .s b { color:var(--fg-primary); font-weight:600; font-variant-numeric:tabular-nums; }
|
||||
.stats .s.live::before { content:''; width:6px; height:6px; border-radius:50%; background:var(--success); display:inline-block; margin-right:4px; animation:pulse 2s infinite; }
|
||||
@keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.4; } }
|
||||
|
||||
/* === filters bar (top-center under stats, optional) === */
|
||||
.filters { position:absolute; left:430px; right:380px; top:24px; display:flex; gap:8px; flex-wrap:wrap; }
|
||||
.filters .chip { display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 12px; border-radius:6px; font-size:12.5px; font-weight:500; color:var(--fg-secondary); background:var(--bg-card); border:1px solid var(--border-card); }
|
||||
.filters .chip[aria-pressed="true"] { color:var(--accent); background:var(--accent-soft); border-color:var(--accent-soft); }
|
||||
.filters .chip .x { color:var(--fg-tertiary); font-size:14px; line-height:1; }
|
||||
|
||||
@media (max-width:1280px) {
|
||||
.filters { left:430px; right:380px; }
|
||||
}
|
||||
@media (max-width:1180px) {
|
||||
.filters { display:none; }
|
||||
.stats { display:none; }
|
||||
}
|
||||
|
||||
/* === tablet (≤1024px): keep map full, shrink panels === */
|
||||
@media (max-width:1024px) {
|
||||
.entry { width:340px; left:16px; top:16px; }
|
||||
.sel-card { width:300px; right:16px; top:16px; }
|
||||
.legend { left:16px; bottom:16px; min-width:200px; padding:12px 14px; }
|
||||
.legend li { font-size:12px; }
|
||||
.map-ctrl { right:16px; bottom:16px; }
|
||||
.map-scale { right:64px; bottom:24px; }
|
||||
.topbar nav.main { gap:14px; font-size:12.5px; }
|
||||
}
|
||||
|
||||
/* === narrow tablet / large mobile (≤860px): stack map + panels === */
|
||||
@media (max-width:860px) {
|
||||
body { overflow:auto; }
|
||||
.stage { height:auto; min-height:auto; overflow:visible; display:flex; flex-direction:column; }
|
||||
.topbar-inner { padding:0 16px; height:52px; }
|
||||
.topbar nav.main { display:none; }
|
||||
.topbar-user .who { padding:5px 10px; font-size:12px; }
|
||||
|
||||
/* map becomes a fixed-aspect strip at top + a positioning context */
|
||||
.map { position:relative; inset:auto; height:380px; border-bottom:1px solid var(--border-card); order:0; }
|
||||
.map svg { height:100%; }
|
||||
|
||||
/* hide overlay controls on small screens — keep map clean */
|
||||
.legend, .map-scale { display:none; }
|
||||
/* zoom anchors to top-right of map area (map height 380px, .stage is relative) */
|
||||
.map-ctrl { position:absolute; top:12px; right:12px; bottom:auto; flex-direction:column; gap:6px; z-index:10; }
|
||||
.map-ctrl button { width:30px; height:30px; font-size:14px; }
|
||||
|
||||
/* entry panel moves below map, full-width */
|
||||
.entry { position:relative; left:auto; top:auto; right:auto; width:auto; margin:16px; border-radius:12px; box-shadow:none; }
|
||||
.entry-hd { padding:14px 16px 12px; }
|
||||
.entry-hd h1 { font-size:16px; }
|
||||
.entry-hd h1 br { display:none; }
|
||||
.entry-hd .or { display:block; font-size:13px; color:var(--fg-tertiary); margin-top:2px; }
|
||||
.entry-bd { padding:12px 16px; }
|
||||
.input-row { grid-template-columns:1fr; }
|
||||
.input input { height:42px; }
|
||||
.btn { height:42px; }
|
||||
.entry-help { font-size:11.5px; }
|
||||
.entry-recent { padding:6px 16px 14px; }
|
||||
.entry-recent li a { grid-template-columns:1fr; gap:2px; padding:8px 10px; }
|
||||
.entry-recent li .meta { font-size:10.5px; }
|
||||
|
||||
/* sel-card moves below entry */
|
||||
.sel-card { position:relative; right:auto; top:auto; width:auto; margin:0 16px 16px; box-shadow:none; }
|
||||
.sel-hd { padding:12px 16px; }
|
||||
.sel-body { padding:12px 16px; }
|
||||
.sel-foot { padding:10px 16px; }
|
||||
}
|
||||
|
||||
/* === phone (≤520px): compact further === */
|
||||
@media (max-width:520px) {
|
||||
.dev-nav { gap:10px; padding:0 10px; }
|
||||
.dev-nav .dev-label { font-size:10.5px; }
|
||||
.dev-nav .dev-hint { display:none; }
|
||||
.topbar-inner { padding:0 12px; }
|
||||
.brand { font-size:14px; }
|
||||
.map { height:280px; }
|
||||
.map-ctrl { top:8px; right:8px; }
|
||||
.entry { margin:12px; }
|
||||
.sel-card { margin:0 12px 12px; }
|
||||
.sel-foot { grid-template-columns:1fr; }
|
||||
.topbar-user .who .avatar { display:none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="dev-nav">
|
||||
<span class="dev-label">Превью · gendsgn</span>
|
||||
<nav class="dev-tabs" aria-label="Превью страницы">
|
||||
<a href="index.html">обзор</a>
|
||||
<a href="landing.html">лендинг</a>
|
||||
<a href="analytics.html">/analytics</a>
|
||||
<a href="site-finder.html" aria-current="page">/site-finder</a>
|
||||
<a href="site-finder-analysis.html">/site-finder/анализ</a>
|
||||
<span class="dev-sep" aria-hidden="true"></span>
|
||||
<a href="developers.html">/developers</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<header class="topbar">
|
||||
<div class="topbar-inner">
|
||||
<div class="topbar-left">
|
||||
<a href="landing.html" class="brand"><span class="brand-mark" aria-hidden="true"></span> gendsgn</a>
|
||||
<nav class="main">
|
||||
<a href="site-finder.html" aria-current="page">Поиск участка</a>
|
||||
<a href="analytics.html">Аналитика рынка</a>
|
||||
<a href="developers.html">Девелоперы</a>
|
||||
<a>Мои подборки</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="topbar-user">
|
||||
<span class="who"><span class="avatar">АК</span> Алексей К. · PRINZIP</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="stage">
|
||||
|
||||
<!-- ============ MAP ============ -->
|
||||
<div class="map">
|
||||
<svg viewBox="0 0 1600 900" preserveAspectRatio="xMidYMid slice" aria-label="Карта Екатеринбурга">
|
||||
<defs>
|
||||
<pattern id="bgGrid" width="40" height="40" patternUnits="userSpaceOnUse">
|
||||
<line x1="0" y1="0" x2="40" y2="0" />
|
||||
<line x1="0" y1="0" x2="0" y2="40" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="1600" height="900" fill="#f0f2f5" />
|
||||
<g class="grid">
|
||||
<rect width="1600" height="900" fill="url(#bgGrid)" stroke="none" />
|
||||
</g>
|
||||
|
||||
<!-- districts (simplified Ekaterinburg polygons) -->
|
||||
<g>
|
||||
<path class="district" d="M120,180 L380,140 L500,260 L420,420 L200,440 Z" />
|
||||
<path class="district" d="M500,260 L760,180 L900,300 L820,500 L600,520 L420,420 Z" />
|
||||
<path class="district" d="M760,180 L1020,160 L1180,300 L1080,420 L900,300 Z" />
|
||||
<path class="district" d="M1180,300 L1400,260 L1480,440 L1380,580 L1180,560 L1080,420 Z" />
|
||||
<path class="district" d="M900,300 L1080,420 L1180,560 L1020,640 L820,620 L820,500 Z" />
|
||||
<path class="district" d="M420,420 L600,520 L820,500 L820,620 L640,720 L420,700 L300,580 L200,440 Z" />
|
||||
<path class="district" d="M820,620 L1020,640 L1180,560 L1380,580 L1340,760 L1140,780 L920,800 L640,720 Z" />
|
||||
<text class="district-label" x="280" y="320" text-anchor="middle">Верх-Исетский</text>
|
||||
<text class="district-label" x="660" y="380" text-anchor="middle">Ленинский</text>
|
||||
<text class="district-label" x="940" y="240" text-anchor="middle">Кировский</text>
|
||||
<text class="district-label" x="1280" y="380" text-anchor="middle">Орджоникидзевский</text>
|
||||
<text class="district-label" x="920" y="560" text-anchor="middle">Октябрьский</text>
|
||||
<text class="district-label" x="440" y="600" text-anchor="middle">Чкаловский</text>
|
||||
<text class="district-label" x="1020" y="730" text-anchor="middle">Академический</text>
|
||||
</g>
|
||||
|
||||
<!-- water (Iset river) -->
|
||||
<path class="water" d="M540,40 C 580,180 720,300 700,440 C 680,580 760,680 740,820 L780,840 C 820,700 720,580 760,440 C 800,300 660,180 600,40 Z" opacity="0.85" />
|
||||
<path class="water" d="M260,520 C 360,540 420,580 480,640 L460,680 C 380,620 300,580 240,560 Z" opacity="0.7" />
|
||||
|
||||
<!-- roads (major) -->
|
||||
<g>
|
||||
<path class="road-edge" d="M40,440 L1560,460" />
|
||||
<path class="road" d="M40,440 L1560,460" />
|
||||
<path class="road-edge" d="M820,40 L820,860" />
|
||||
<path class="road" d="M820,40 L820,860" />
|
||||
<path class="road-edge" d="M180,140 L1380,820" />
|
||||
<path class="road" d="M180,140 L1380,820" />
|
||||
</g>
|
||||
<!-- roads (minor) -->
|
||||
<g>
|
||||
<path class="road-minor-edge" d="M120,300 L1480,340" />
|
||||
<path class="road-minor" d="M120,300 L1480,340" />
|
||||
<path class="road-minor-edge" d="M120,620 L1480,640" />
|
||||
<path class="road-minor" d="M120,620 L1480,640" />
|
||||
<path class="road-minor-edge" d="M460,40 L500,860" />
|
||||
<path class="road-minor" d="M460,40 L500,860" />
|
||||
<path class="road-minor-edge" d="M1180,40 L1180,860" />
|
||||
<path class="road-minor" d="M1180,40 L1180,860" />
|
||||
</g>
|
||||
|
||||
<!-- parcels (clickable polygons) -->
|
||||
<g>
|
||||
<!-- vacant lots -->
|
||||
<polygon class="parcel" fill="#DCFCE7" points="240,360 320,360 320,420 240,420" data-cad="66:41:0501012:18" />
|
||||
<polygon class="parcel" fill="#DBEAFE" points="640,290 720,290 720,350 640,350" data-cad="66:41:0701102:7" />
|
||||
<polygon class="parcel" fill="#FEF3C7" points="1100,330 1180,330 1180,400 1100,400" data-cad="66:41:0301045:11" />
|
||||
<polygon class="parcel" fill="#DBEAFE" points="980,560 1060,560 1060,620 980,620" data-cad="66:41:0801009:3" />
|
||||
<polygon class="parcel sel" fill="#DCFCE7" points="940,680 1080,680 1080,760 940,760" data-cad="66:41:0701045:42" data-selected="true" />
|
||||
<polygon class="parcel" fill="#FEE2E2" points="520,560 600,560 600,620 520,620" data-cad="66:41:0601023:9" />
|
||||
<polygon class="parcel" fill="#FEF3C7" points="1280,500 1360,500 1360,570 1280,570" data-cad="66:41:0901014:5" />
|
||||
<polygon class="parcel" fill="#DBEAFE" points="380,260 460,260 460,320 380,320" data-cad="66:41:0501007:2" />
|
||||
</g>
|
||||
|
||||
<!-- pin for selected (Akademicheskij district) -->
|
||||
<g class="pin sel" transform="translate(1010,720)">
|
||||
<circle class="halo" r="22"></circle>
|
||||
<circle class="dot" r="9"></circle>
|
||||
</g>
|
||||
|
||||
<!-- other developer/competitor markers (faint) -->
|
||||
<g fill="#94A3B8" opacity="0.55">
|
||||
<circle cx="280" cy="380" r="4"></circle>
|
||||
<circle cx="680" cy="320" r="4"></circle>
|
||||
<circle cx="1140" cy="370" r="4"></circle>
|
||||
<circle cx="1020" cy="600" r="4"></circle>
|
||||
<circle cx="560" cy="600" r="4"></circle>
|
||||
<circle cx="1320" cy="540" r="4"></circle>
|
||||
<circle cx="420" cy="290" r="4"></circle>
|
||||
<circle cx="900" cy="450" r="4"></circle>
|
||||
<circle cx="760" cy="680" r="4"></circle>
|
||||
<circle cx="1240" cy="700" r="4"></circle>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- ============ ENTRY PANEL (left) ============ -->
|
||||
<section class="entry">
|
||||
<header class="entry-hd">
|
||||
<div class="eyebrow">site finder</div>
|
||||
<h1>Введите номер участка<br><span class="or">или кликните на карту →</span></h1>
|
||||
</header>
|
||||
<div class="entry-bd">
|
||||
<form class="input-row" onsubmit="event.preventDefault();window.location='site-finder-analysis.html'">
|
||||
<div class="input">
|
||||
<input type="text" placeholder="66:41:0701045:42" autocomplete="off" value="66:41:0701045:42" />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Анализ →</button>
|
||||
</form>
|
||||
<p class="entry-help">
|
||||
<i>i</i>
|
||||
Кадастровый номер из ЕГРН в формате <span class="entry-fmt">XX:XX:XXXXXXX:NN</span>. Поддерживаем Свердловскую область, Челябинскую, Тюменскую.
|
||||
</p>
|
||||
<div class="entry-or"><span>или</span></div>
|
||||
<button type="button" class="btn btn-ghost" style="width:100%; justify-content:center;">↗ Загрузить выписку ЕГРН (PDF)</button>
|
||||
</div>
|
||||
<div class="entry-recent">
|
||||
<h5>Недавние участки</h5>
|
||||
<ul>
|
||||
<li><a href="site-finder-analysis.html">
|
||||
<span><span class="cad">66:41:0701045:42</span> <span class="desc">· Академический, 0,82 га · собств. ООО «УралЗем»</span></span>
|
||||
<span class="meta">сегодня</span>
|
||||
</a></li>
|
||||
<li><a href="site-finder-analysis.html">
|
||||
<span><span class="cad">66:41:0301045:11</span> <span class="desc">· Кировский, 1,40 га · муниципальная</span></span>
|
||||
<span class="meta">вчера</span>
|
||||
</a></li>
|
||||
<li><a href="site-finder-analysis.html">
|
||||
<span><span class="cad">66:41:0801009:3</span> <span class="desc">· Октябрьский, 0,54 га · частная</span></span>
|
||||
<span class="meta">3 дня</span>
|
||||
</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ============ FILTERS BAR (top) ============ -->
|
||||
<div class="filters">
|
||||
<button class="chip" aria-pressed="true">Свободные участки <span class="x">×</span></button>
|
||||
<button class="chip" aria-pressed="true">от 0,3 га <span class="x">×</span></button>
|
||||
<button class="chip">+ ВРИ многоэтажка</button>
|
||||
<button class="chip">+ собственность</button>
|
||||
<button class="chip">+ район</button>
|
||||
</div>
|
||||
|
||||
<!-- ============ STATS (top-center) ============ -->
|
||||
<div class="stats">
|
||||
<div class="s">показано <b>148</b> участков</div>
|
||||
<div class="s">подходят <b>34</b></div>
|
||||
<div class="s live">обновлено <b>16 мин назад</b></div>
|
||||
</div>
|
||||
|
||||
<!-- ============ SELECTED PARCEL CARD (right) ============ -->
|
||||
<aside class="sel-card" aria-label="Выбранный участок">
|
||||
<header class="sel-hd">
|
||||
<div class="tag">подходит под комфорт-класс</div>
|
||||
<div class="cad">66:41:0701045:42</div>
|
||||
<p class="verdict">Академический район · <b>0,82 га</b> · собственность ООО «УралЗем». Score <b>78/100</b>. Окно дефицита 80+ м².</p>
|
||||
</header>
|
||||
<div class="sel-body">
|
||||
<div class="sel-row"><span class="l">Район</span><span class="v">Академический</span></div>
|
||||
<div class="sel-row"><span class="l">Площадь</span><span class="v">0,82 га</span></div>
|
||||
<div class="sel-row"><span class="l">Форма собственности</span><span class="v">Частная</span></div>
|
||||
<div class="sel-row"><span class="l">Текущий ВРИ</span><span class="v">Многоэтажная застройка</span></div>
|
||||
<div class="sel-row"><span class="l">Медиана цены, район</span><span class="v">186 тыс ₽/м²</span></div>
|
||||
<div class="sel-row"><span class="l">Sold % соседей</span><span class="v good">62%</span></div>
|
||||
<div class="sel-row"><span class="l">Конкуренция в радиусе 1 км</span><span class="v warn">7 ЖК</span></div>
|
||||
</div>
|
||||
<div class="sel-foot">
|
||||
<button type="button" class="btn btn-ghost">↗ Карточка ЕГРН</button>
|
||||
<a href="site-finder-analysis.html" class="btn btn-primary">Анализ →</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- ============ LEGEND (bottom-left) ============ -->
|
||||
<div class="legend">
|
||||
<h4>Раскраска участков</h4>
|
||||
<ul>
|
||||
<li><i style="background:#DCFCE7;"></i><span>свободные, score > 70</span><b>34</b></li>
|
||||
<li><i style="background:#DBEAFE;"></i><span>в работе, нужен анализ</span><b>62</b></li>
|
||||
<li><i style="background:#FEF3C7;"></i><span>обременения / спорный ВРИ</span><b>38</b></li>
|
||||
<li><i style="background:#FEE2E2;"></i><span>не подходит</span><b>14</b></li>
|
||||
<li><i style="background:#94A3B8;border-radius:50%;"></i><span>конкуренты (ЖК в продаже)</span><b>74</b></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- ============ MAP CONTROLS (bottom-right) ============ -->
|
||||
<div class="map-scale"><i></i> 2 км</div>
|
||||
<div class="map-ctrl">
|
||||
<button type="button" aria-label="Слои">⊞</button>
|
||||
<button type="button" aria-label="Увеличить">+</button>
|
||||
<button type="button" aria-label="Уменьшить">-</button>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<script>
|
||||
// simple parcel click: select + navigate-ish
|
||||
document.querySelectorAll('.parcel').forEach(p => {
|
||||
p.addEventListener('click', () => {
|
||||
document.querySelectorAll('.parcel').forEach(x => x.classList.remove('sel'));
|
||||
p.classList.add('sel');
|
||||
// for demo: update cadastral in input + selected card
|
||||
const cad = p.getAttribute('data-cad');
|
||||
const inp = document.querySelector('.input input');
|
||||
if (inp) inp.value = cad;
|
||||
const sel = document.querySelector('.sel-hd .cad');
|
||||
if (sel) sel.textContent = cad;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
2051
frontend/public/tradein.html
Normal file
2051
frontend/public/tradein.html
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue