4 HTML mockups (landing/site-finder/analytics/monitoring) — alternative designs для audit-review без замены существующих React-страниц. - Caddy file_server на handle_path /preview/* (внутри gendsgn.ru block) - Bind mount ./preview:/srv/preview:ro в caddy container - basic auth: user=preview / pwd shared via private channel - Static, isolated — не влияет на /, /site-finder, /analytics (Next.js routes)
597 lines
38 KiB
HTML
597 lines
38 KiB
HTML
<!doctype html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>/analytics/recommend — Рекомендатор площадки · 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 { 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; }
|
||
|
||
/* ============ LAYOUT — form left, result right ============ */
|
||
.rec-grid { display:grid; grid-template-columns:340px 1fr; gap:24px; align-items:start; }
|
||
|
||
.form-card { position:sticky; top:88px; background:var(--bg-card); border:1px solid var(--border-card); border-radius:12px; padding:20px; }
|
||
.form-card h2 { font-size:16px; font-weight:600; margin-bottom:4px; }
|
||
.form-card .sub { font-size:12.5px; color:var(--fg-secondary); margin-bottom:16px; }
|
||
.field { margin-bottom:16px; }
|
||
.field label { display:block; font-size:11px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; margin-bottom:6px; }
|
||
.field input, .field select { width:100%; height:36px; padding:0 12px; border:1px solid var(--border-strong); border-radius:6px; background:var(--bg-card); font:inherit; color:var(--fg-primary); font-variant-numeric:tabular-nums; }
|
||
.field input:focus, .field select:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft); }
|
||
.field .row2 { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
|
||
.field .with-suffix { position:relative; }
|
||
.field .with-suffix .suf { position:absolute; right:12px; top:50%; transform:translateY(-50%); font-size:12px; color:var(--fg-tertiary); pointer-events:none; }
|
||
.chip-group { display:flex; flex-wrap:wrap; gap:4px; }
|
||
.chip-group .chip { display:inline-flex; align-items:center; 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); cursor:pointer; transition:all .12s; }
|
||
.chip-group .chip[aria-pressed="true"] { color:var(--accent); background:var(--accent-soft); border-color:var(--accent-soft); }
|
||
.form-cta { margin-top:16px; padding-top:16px; border-top:1px solid var(--border-soft); }
|
||
.form-cta .btn-primary { width:100%; justify-content:center; }
|
||
.form-meta { margin-top:12px; font-size:11.5px; color:var(--fg-tertiary); line-height:1.5; }
|
||
|
||
/* ============ RESULT ============ */
|
||
.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-3 { display:grid; grid-template-columns:repeat(3,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); height:44px; padding:0 20px; font-size:14px; }
|
||
.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; }
|
||
|
||
/* ============ VELOCITY PANEL (slider + live KPI) ============ */
|
||
.velocity { display:grid; grid-template-columns:1fr 280px; gap:24px; align-items:start; }
|
||
.velocity-slider { padding-top:16px; }
|
||
.velocity-slider .lbl-row { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:12px; }
|
||
.velocity-slider .lbl-row .name { font-size:13px; font-weight:500; color:var(--fg-primary); }
|
||
.velocity-slider .lbl-row .val { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; font-weight:600; color:var(--accent); font-variant-numeric:tabular-nums; }
|
||
.slider-track { position:relative; height:8px; background:var(--bg-card-alt); border-radius:4px; }
|
||
.slider-track .fill { position:absolute; top:0; left:0; height:100%; background:var(--accent); border-radius:4px; width:62%; }
|
||
.slider-track .handle { position:absolute; top:50%; left:62%; transform:translate(-50%,-50%); width:20px; height:20px; background:#fff; border:2px solid var(--accent); border-radius:50%; cursor:grab; box-shadow:0 1px 4px rgba(0,0,0,0.1); }
|
||
.slider-ticks { display:flex; justify-content:space-between; margin-top:8px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:10px; color:var(--fg-tertiary); }
|
||
.velocity-side { background:var(--bg-card-alt); border:1px solid var(--border-soft); border-radius:8px; padding:16px; }
|
||
.velocity-side h3 { font-size:11px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; margin-bottom:12px; }
|
||
.velocity-side .row { display:flex; justify-content:space-between; align-items:baseline; padding:8px 0; border-top:1px solid var(--border-soft); }
|
||
.velocity-side .row:first-of-type { border-top:0; padding-top:0; }
|
||
.velocity-side .row .lbl { font-size:12.5px; color:var(--fg-secondary); }
|
||
.velocity-side .row .val { font-size:14px; font-weight:600; color:var(--fg-primary); font-variant-numeric:tabular-nums; }
|
||
.velocity-side .row .val.pos { color:var(--success); }
|
||
.velocity-side .row .val.neg { color:var(--danger); }
|
||
|
||
/* ============ MIX SLIDERS ============ */
|
||
.mix-list { display:flex; flex-direction:column; gap:12px; }
|
||
.mix-row { display:grid; grid-template-columns:130px 1fr 60px 80px; gap:12px; align-items:center; }
|
||
.mix-row .name { font-size:13px; color:var(--fg-primary); font-weight:500; }
|
||
.mix-row .bar-wrap { height:8px; background:var(--bg-card-alt); border-radius:4px; position:relative; }
|
||
.mix-row .bar-wrap .fill { height:100%; border-radius:4px; background:var(--accent); }
|
||
.mix-row .pct { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; font-weight:600; color:var(--fg-primary); text-align:right; font-variant-numeric:tabular-nums; }
|
||
.mix-row .pop { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; color:var(--fg-secondary); text-align:right; font-variant-numeric:tabular-nums; }
|
||
.mix-foot { margin-top:16px; padding-top:12px; border-top:1px solid var(--border-soft); display:flex; justify-content:space-between; font-size:12.5px; color:var(--fg-secondary); }
|
||
.mix-foot b { color:var(--fg-primary); font-weight:600; }
|
||
|
||
/* ============ DISTRICT KPI GRID (5 cards) ============ */
|
||
.dist-grid { display:grid; grid-template-columns:repeat(5,1fr); gap:8px; }
|
||
.dist-cell { background:var(--bg-card-alt); border:1px solid var(--border-soft); border-radius:8px; padding:12px 14px; }
|
||
.dist-cell .lbl { font-size:10.5px; letter-spacing:0.04em; text-transform:uppercase; color:var(--fg-secondary); font-weight:500; }
|
||
.dist-cell .val { font-size:20px; font-weight:600; color:var(--fg-primary); letter-spacing:-0.01em; margin-top:4px; font-variant-numeric:tabular-nums; }
|
||
.dist-cell .meta { font-size:11.5px; color:var(--fg-tertiary); margin-top:4px; }
|
||
.dist-cell.warn .val { color:var(--warn); }
|
||
.dist-cell.ok .val { color:var(--success); }
|
||
|
||
/* ============ LIQUIDITY CHART ============ */
|
||
.liq-chart { position:relative; height:240px; border-left:1px solid var(--border-soft); border-bottom:1px solid var(--border-soft); }
|
||
.liq-chart svg { width:100%; height:100%; display:block; }
|
||
|
||
/* ============ BUCKETS CHART + TABLE ============ */
|
||
.buckets-row { display:grid; grid-template-columns:1fr 1fr; gap:24px; }
|
||
.bucket-chart { padding:8px 0; }
|
||
.bucket-chart svg { width:100%; height:200px; display:block; }
|
||
.buckets-table { width:100%; border-collapse:collapse; }
|
||
.buckets-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); }
|
||
.buckets-table th:not(:first-child), .buckets-table td:not(:first-child) { text-align:right; }
|
||
.buckets-table td { font-size:13px; padding:10px 8px 10px 0; border-bottom:1px solid var(--border-soft); color:var(--fg-primary); font-variant-numeric:tabular-nums; }
|
||
.buckets-table tr:last-child td { border-bottom:0; }
|
||
.buckets-table tr.total td { font-weight:600; background:var(--bg-card-alt); border-top:2px solid var(--border-card); }
|
||
|
||
/* ============ COMPARABLES ============ */
|
||
.comparables { display:flex; flex-direction:column; gap:8px; }
|
||
.comp-row { display:grid; grid-template-columns:1fr 100px 80px 70px 80px; gap:12px; align-items:center; padding:10px 0; border-top:1px solid var(--border-soft); }
|
||
.comp-row:first-child { border-top:0; }
|
||
.comp-row .name a { color:var(--accent); font-weight:500; font-size:13px; }
|
||
.comp-row .name a:hover { text-decoration:underline; }
|
||
.comp-row .name .meta { font-size:11.5px; color:var(--fg-secondary); margin-top:2px; }
|
||
.comp-row .num { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13px; font-weight:500; text-align:right; font-variant-numeric:tabular-nums; }
|
||
|
||
/* ============ ACCORDIONS ============ */
|
||
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; }
|
||
details.acc[open] summary::after { content:'–'; }
|
||
details.acc .acc-body { padding:0 20px 20px; font-size:13px; color:var(--fg-primary); line-height:1.55; }
|
||
|
||
/* ============ CAVEAT ============ */
|
||
.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) {
|
||
.rec-grid { grid-template-columns:1fr; }
|
||
.form-card { position:relative; top:auto; }
|
||
.kpi-row-3 { grid-template-columns:1fr; }
|
||
.velocity { grid-template-columns:1fr; }
|
||
.dist-grid { grid-template-columns:repeat(2,1fr); }
|
||
.buckets-row { grid-template-columns:1fr; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<aside class="dev-nav" aria-label="Dev navigation">
|
||
<span class="dev-label">DEV · ТОЛЬКО ДЛЯ РАЗРАБОТКИ</span>
|
||
<nav class="dev-tabs" aria-label="WIP страницы">
|
||
<a href="landing.html">лендинг</a>
|
||
<a href="analytics.html">/analytics</a>
|
||
<a href="site-finder.html" aria-current="page">/recommend</a>
|
||
<a href="monitoring.html">/developers</a>
|
||
<span class="dev-sep"></span>
|
||
<a href="audit.html">audit (live)</a>
|
||
<a href="gendsgn-audit.html">audit (отчёт)</a>
|
||
</nav>
|
||
<span class="dev-hint">временная панель · скроется в print</span>
|
||
</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">recommend — рекомендатор площадки</span>
|
||
</nav>
|
||
|
||
<div class="page-head">
|
||
<div>
|
||
<h1>Рекомендатор площадки</h1>
|
||
<div class="sub">Mix квартир по комнатности, прогноз срока 80 % продаж, расчёт выручки на основе sold % сегмента и района</div>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="a-tabs" aria-label="Разделы аналитики">
|
||
<a href="analytics.html">Свердл рынок</a>
|
||
<a href="site-finder.html" aria-current="page">Рекомендатор</a>
|
||
<a href="monitoring.html">Девелоперы</a>
|
||
<a href="#">PRINZIP · профиль</a>
|
||
<a href="#">Объекты</a>
|
||
</nav>
|
||
|
||
<div class="rec-grid">
|
||
|
||
<!-- LEFT: form -->
|
||
<aside class="form-card" aria-label="Параметры площадки">
|
||
<h2>Параметры площадки</h2>
|
||
<div class="sub">Заполните, рекомендатор пересчитает за < 1 сек</div>
|
||
|
||
<div class="field">
|
||
<label for="f-district">Район</label>
|
||
<select id="f-district">
|
||
<option>Академический</option>
|
||
<option>Центр</option>
|
||
<option>ВИЗ</option>
|
||
<option>Пионерский</option>
|
||
<option>Юго-Запад</option>
|
||
<option>Уралмаш</option>
|
||
<option>Уктус</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Класс жилья</label>
|
||
<div class="chip-group" role="group">
|
||
<button class="chip" aria-pressed="false">эконом</button>
|
||
<button class="chip" aria-pressed="true">комфорт</button>
|
||
<button class="chip" aria-pressed="false">бизнес</button>
|
||
<button class="chip" aria-pressed="false">премиум</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label for="f-area">Площадь застройки</label>
|
||
<div class="with-suffix">
|
||
<input id="f-area" type="text" value="12 000" />
|
||
<span class="suf">м²</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Окно ввода</label>
|
||
<div class="row2">
|
||
<div class="with-suffix"><input type="text" value="Q3 2026" /></div>
|
||
<div class="with-suffix"><input type="text" value="Q1 2028" /></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label for="f-target">Целевой срок 80 % продаж</label>
|
||
<div class="with-suffix">
|
||
<input id="f-target" type="text" value="24" />
|
||
<span class="suf">мес</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label for="f-price">Price factor</label>
|
||
<div class="with-suffix">
|
||
<input id="f-price" type="text" value="1,00" />
|
||
<span class="suf">× медианы района</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-cta">
|
||
<button class="btn btn-primary">Рассчитать</button>
|
||
<div class="form-meta">Расчёт по 6 832 411 ДДУ Росреестра и портфелю ДОМ.РФ. Доверительный интервал ±p25/p75.</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- RIGHT: result -->
|
||
<div>
|
||
|
||
<div class="headline-bar" role="status">
|
||
<span class="tag">рекомендация</span>
|
||
<p class="verdict"><b>Академический</b> · комфорт · <b>12 000 м²</b>: mix <b>32/26/22/15/5</b> · срок 80 % продаж <b>22 мес</b> · выручка <b>2,4 млрд ₽</b></p>
|
||
<span class="caveat">пересчитано: 12 сек назад</span>
|
||
</div>
|
||
|
||
<!-- 3 KPI -->
|
||
<div class="kpi-row-3">
|
||
<div class="kpi">
|
||
<div class="label">Выручка</div>
|
||
<div class="value">2,4<small>млрд ₽</small></div>
|
||
<div class="hint">по медианной цене района ×1,00</div>
|
||
<span class="delta pos">↑ +180 млн vs дефолтный mix</span>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="label">Срок 80 % продаж</div>
|
||
<div class="value">22<small>мес</small></div>
|
||
<div class="hint">target 24 мес — внутри окна</div>
|
||
<span class="delta pos">опережает target на 2 мес</span>
|
||
</div>
|
||
<div class="kpi">
|
||
<div class="label">Liquidity score</div>
|
||
<div class="value">7,8<small>/ 10</small></div>
|
||
<div class="hint">взвешенно по sold % сегментов</div>
|
||
<span class="delta pos">в топ-30 % площадок района</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Velocity Panel -->
|
||
<section class="section">
|
||
<div class="section-head">
|
||
<div>
|
||
<h2>Velocity Panel — влияние цены</h2>
|
||
<div class="sub">Сдвиньте price factor, чтобы увидеть, как меняется срок 80 % продаж и выручка</div>
|
||
</div>
|
||
</div>
|
||
<div class="velocity">
|
||
<div class="velocity-slider">
|
||
<div class="lbl-row"><span class="name">Price factor (× медианы района)</span><span class="val">1,00</span></div>
|
||
<div class="slider-track"><div class="fill"></div><div class="handle"></div></div>
|
||
<div class="slider-ticks"><span>0,75</span><span>0,85</span><span>0,95</span><span>1,00</span><span>1,10</span><span>1,20</span><span>1,30</span></div>
|
||
<div style="margin-top:16px;font-size:12.5px;color:var(--fg-secondary);line-height:1.55;">
|
||
При factor <b style="color:var(--fg-primary);">0,90</b> срок падает до <b style="color:var(--success);">18 мес</b>, выручка снижается до <b>2,16 млрд ₽</b> (−240 млн). При <b style="color:var(--fg-primary);">1,15</b> срок растёт до <b style="color:var(--danger);">31 мес</b> — выходим из окна. Сладкое пятно — 0,95–1,05.
|
||
</div>
|
||
</div>
|
||
<aside class="velocity-side">
|
||
<h3>На текущем factor 1,00</h3>
|
||
<div class="row"><span class="lbl">Срок 80 %</span><span class="val">22 мес</span></div>
|
||
<div class="row"><span class="lbl">Выручка</span><span class="val">2,4 млрд</span></div>
|
||
<div class="row"><span class="lbl">Маржа vs target</span><span class="val pos">+ 2 мес</span></div>
|
||
<div class="row"><span class="lbl">Liquidity</span><span class="val pos">7,8 / 10</span></div>
|
||
<div class="row"><span class="lbl">Δ sold % мес</span><span class="val">3,8 пп</span></div>
|
||
</aside>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- CAVEAT -->
|
||
<div class="caveat-bar">
|
||
<span class="icon">!</span>
|
||
<div>
|
||
<b>Caveat по прогнозу.</b> Срок продаж предсказывается по выборке из 38 ЖК комфорт-класса в Академическом за последние 14 мес. Доверительный интервал p25/p75: 19–26 мес. Прогноз чувствителен к курсу ипотеки — при ставке > 18 % сместите окно на +6 мес.
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ACCORDIONS -->
|
||
<details class="acc" open>
|
||
<summary>5 KPI района — Академический · комфорт</summary>
|
||
<div class="acc-body">
|
||
<div class="dist-grid">
|
||
<div class="dist-cell"><div class="lbl">Конкуренты</div><div class="val">11</div><div class="meta">ЖК в открытой продаже</div></div>
|
||
<div class="dist-cell"><div class="lbl">Velocity покрытие</div><div class="val">94 %</div><div class="meta">38 / 40 объектов в выборке</div></div>
|
||
<div class="dist-cell ok"><div class="lbl">Sold % медиана</div><div class="val">71 %</div><div class="meta">по комфорт-классу района</div></div>
|
||
<div class="dist-cell ok"><div class="lbl">Тренд 6 мес</div><div class="val">+4,2 пп</div><div class="meta">sold % растёт</div></div>
|
||
<div class="dist-cell"><div class="lbl">Class × District</div><div class="val">A−</div><div class="meta">приоритет mix-инвестиций</div></div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="acc" open>
|
||
<summary>Mix квартир — рекомендованное распределение</summary>
|
||
<div class="acc-body">
|
||
<div class="mix-list">
|
||
<div class="mix-row">
|
||
<span class="name">Студии до 30 м²</span>
|
||
<div class="bar-wrap"><div class="fill" style="width:5%"></div></div>
|
||
<span class="pct">5 %</span>
|
||
<span class="pop">≈ 38 кв</span>
|
||
</div>
|
||
<div class="mix-row">
|
||
<span class="name">1-комн. 30–45 м²</span>
|
||
<div class="bar-wrap"><div class="fill" style="width:15%"></div></div>
|
||
<span class="pct">15 %</span>
|
||
<span class="pop">≈ 115 кв</span>
|
||
</div>
|
||
<div class="mix-row">
|
||
<span class="name">2-комн. 45–65 м²</span>
|
||
<div class="bar-wrap"><div class="fill" style="width:22%"></div></div>
|
||
<span class="pct">22 %</span>
|
||
<span class="pop">≈ 168 кв</span>
|
||
</div>
|
||
<div class="mix-row">
|
||
<span class="name">3-комн. 65–85 м²</span>
|
||
<div class="bar-wrap"><div class="fill" style="width:26%"></div></div>
|
||
<span class="pct">26 %</span>
|
||
<span class="pop">≈ 198 кв</span>
|
||
</div>
|
||
<div class="mix-row">
|
||
<span class="name">4+ комн. / 85+ м²</span>
|
||
<div class="bar-wrap"><div class="fill" style="width:32%"></div></div>
|
||
<span class="pct">32 %</span>
|
||
<span class="pop">≈ 244 кв</span>
|
||
</div>
|
||
</div>
|
||
<div class="mix-foot">
|
||
<span>Итого <b>763 кв</b> · <b>59 800 м²</b> жилой площади</span>
|
||
<span>Sold % взвешенный по mix: <b style="color:var(--success);">74,1 %</b></span>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="acc">
|
||
<summary>Liquidity по месяцам — 36 мес прогноз</summary>
|
||
<div class="acc-body">
|
||
<div class="liq-chart">
|
||
<svg viewBox="0 0 800 240" preserveAspectRatio="none">
|
||
<g stroke="#EEF0F3" stroke-width="1">
|
||
<line x1="0" y1="48" x2="800" y2="48"/>
|
||
<line x1="0" y1="96" x2="800" y2="96"/>
|
||
<line x1="0" y1="144" x2="800" y2="144"/>
|
||
<line x1="0" y1="192" x2="800" y2="192"/>
|
||
</g>
|
||
<!-- prediction band -->
|
||
<path d="M 0,200 L 50,180 L 100,150 L 150,120 L 200,98 L 250,82 L 300,70 L 350,62 L 400,52 L 450,46 L 500,42 L 550,38 L 600,36 L 650,34 L 700,32 L 750,30 L 800,28 L 800,80 L 750,82 L 700,84 L 650,88 L 600,90 L 550,94 L 500,98 L 450,102 L 400,108 L 350,118 L 300,128 L 250,140 L 200,156 L 150,178 L 100,206 L 50,224 L 0,240 Z" fill="rgba(14,165,233,0.18)"/>
|
||
<!-- main line -->
|
||
<polyline fill="none" stroke="#1D4ED8" stroke-width="2.5" points="0,220 50,200 100,178 150,156 200,134 250,116 300,98 350,84 400,72 450,62 500,54 550,48 600,42 650,38 700,34 750,32 800,30"/>
|
||
<!-- 80% target line -->
|
||
<line x1="0" y1="48" x2="800" y2="48" stroke="#0A7A3A" stroke-width="1.5" stroke-dasharray="6,4"/>
|
||
<text x="6" y="42" font-family="ui-monospace,Menlo" font-size="10" fill="#0A7A3A">target 80 %</text>
|
||
<!-- 22 mo marker -->
|
||
<line x1="490" y1="0" x2="490" y2="240" stroke="#F2994A" stroke-width="1.5" stroke-dasharray="4,3"/>
|
||
<text x="496" y="14" font-family="ui-monospace,Menlo" font-size="10" fill="#F2994A">22 мес — выход на target</text>
|
||
<!-- month axis -->
|
||
<g font-family="ui-monospace,Menlo" font-size="9" fill="#73767E">
|
||
<text x="0" y="236">0</text><text x="130" y="236">6</text><text x="262" y="236">12</text><text x="394" y="236">18</text><text x="526" y="236">24</text><text x="658" y="236">30</text><text x="780" y="236">36</text>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div style="margin-top:12px;font-size:12px;color:var(--fg-secondary);">Прогноз кумулятивного sold % по месяцам с учётом mix. Полоса — доверительный интервал p25/p75 на основе выборки 38 ЖК комфорт-класса района.</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="acc">
|
||
<summary>Buckets — графика + таблица + Export Excel</summary>
|
||
<div class="acc-body">
|
||
<div class="buckets-row">
|
||
<div class="bucket-chart">
|
||
<svg viewBox="0 0 400 200" preserveAspectRatio="none">
|
||
<g stroke="#EEF0F3" stroke-width="1">
|
||
<line x1="0" y1="40" x2="400" y2="40"/>
|
||
<line x1="0" y1="80" x2="400" y2="80"/>
|
||
<line x1="0" y1="120" x2="400" y2="120"/>
|
||
<line x1="0" y1="160" x2="400" y2="160"/>
|
||
</g>
|
||
<g>
|
||
<rect x="20" y="160" width="50" height="30" fill="#93C5FD"/>
|
||
<text x="45" y="155" font-family="Inter" font-size="11" fill="#5B6066" text-anchor="middle">5 %</text>
|
||
<rect x="90" y="130" width="50" height="60" fill="#60A5FA"/>
|
||
<text x="115" y="125" font-family="Inter" font-size="11" fill="#5B6066" text-anchor="middle">15 %</text>
|
||
<rect x="160" y="102" width="50" height="88" fill="#3B82F6"/>
|
||
<text x="185" y="97" font-family="Inter" font-size="11" fill="#5B6066" text-anchor="middle">22 %</text>
|
||
<rect x="230" y="86" width="50" height="104" fill="#1D4ED8"/>
|
||
<text x="255" y="81" font-family="Inter" font-size="11" fill="#5B6066" text-anchor="middle">26 %</text>
|
||
<rect x="300" y="62" width="50" height="128" fill="#1E3A8A"/>
|
||
<text x="325" y="57" font-family="Inter" font-size="11" fill="#5B6066" text-anchor="middle">32 %</text>
|
||
</g>
|
||
<g font-family="ui-monospace,Menlo" font-size="9" fill="#73767E">
|
||
<text x="45" y="200" text-anchor="middle">студ</text>
|
||
<text x="115" y="200" text-anchor="middle">1к</text>
|
||
<text x="185" y="200" text-anchor="middle">2к</text>
|
||
<text x="255" y="200" text-anchor="middle">3к</text>
|
||
<text x="325" y="200" text-anchor="middle">4+</text>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<table class="buckets-table">
|
||
<thead>
|
||
<tr><th>Сегмент</th><th>Кв</th><th>м²</th><th>Выручка</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>студии</td><td>38</td><td>1 140</td><td>180 М</td></tr>
|
||
<tr><td>1-к</td><td>115</td><td>4 600</td><td>740 М</td></tr>
|
||
<tr><td>2-к</td><td>168</td><td>9 240</td><td>1,49 Б</td></tr>
|
||
<tr><td>3-к</td><td>198</td><td>14 850</td><td>2,39 Б</td></tr>
|
||
<tr><td>4+</td><td>244</td><td>29 970</td><td>4,82 Б</td></tr>
|
||
<tr class="total"><td>Итого</td><td>763</td><td>59 800</td><td>9,62 Б</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div style="margin-top:16px;display:flex;justify-content:space-between;align-items:center;padding-top:12px;border-top:1px solid var(--border-soft);">
|
||
<span style="font-size:12.5px;color:var(--fg-secondary);">Цифры в подсказке headline-bar — это выручка по сценарию price factor 1,00. Полная выгрузка — Export Excel.</span>
|
||
<button class="btn btn-secondary btn-compact">Export Excel ⤓</button>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="acc">
|
||
<summary>Comparables — топ-5 похожих ЖК в районе</summary>
|
||
<div class="acc-body">
|
||
<div class="comparables">
|
||
<div class="comp-row">
|
||
<div class="name"><a href="#">Каменные палатки</a><div class="meta">PRINZIP · комфорт · 1 824 кв</div></div>
|
||
<div class="num">78 %</div>
|
||
<div class="num">22 мес</div>
|
||
<div class="num">173 ₽</div>
|
||
<div class="num">1,4 Б</div>
|
||
</div>
|
||
<div class="comp-row">
|
||
<div class="name"><a href="#">Северная корона</a><div class="meta">Брусника · комфорт · 1 408 кв</div></div>
|
||
<div class="num">71 %</div>
|
||
<div class="num">24 мес</div>
|
||
<div class="num">198 ₽</div>
|
||
<div class="num">1,8 Б</div>
|
||
</div>
|
||
<div class="comp-row">
|
||
<div class="name"><a href="#">Светлый</a><div class="meta">Атомстройком. · комфорт · 962 кв</div></div>
|
||
<div class="num">68 %</div>
|
||
<div class="num">26 мес</div>
|
||
<div class="num">156 ₽</div>
|
||
<div class="num">0,9 Б</div>
|
||
</div>
|
||
<div class="comp-row">
|
||
<div class="name"><a href="#">Радуга-Парк</a><div class="meta">Форум-групп · комфорт · 720 кв</div></div>
|
||
<div class="num">62 %</div>
|
||
<div class="num">28 мес</div>
|
||
<div class="num">162 ₽</div>
|
||
<div class="num">0,7 Б</div>
|
||
</div>
|
||
<div class="comp-row">
|
||
<div class="name"><a href="#">Уют</a><div class="meta">Атлас Девел. · комфорт · 612 кв</div></div>
|
||
<div class="num">52 %</div>
|
||
<div class="num">31 мес</div>
|
||
<div class="num">141 ₽</div>
|
||
<div class="num">0,5 Б</div>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top:12px;font-size:11.5px;color:var(--fg-secondary);">Колонки: sold %, срок 80 %, ср. цена ₽/м², оценочная выручка. Клик по названию → /analytics/objects/[id].</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="acc">
|
||
<summary>Caveats — что важно учесть</summary>
|
||
<div class="acc-body">
|
||
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:8px;">
|
||
<li>• Выборка для прогноза — только ЖК с лотностью > 200 кв; малоквартирные клубные дома (< 100 кв) дают другой режим спроса.</li>
|
||
<li>• Расчёт не учитывает паркинг и кладовые — добавьте 4–7 % к выручке при наличии паркинга 1:1.</li>
|
||
<li>• Прогноз 36 мес — экстраполяция; при горизонте > 24 мес доверительный интервал расширяется до p10/p90.</li>
|
||
<li>• Mix чувствителен к политике ипотеки: при ставке > 18 % спрос смещается в студии и 1-к — пересмотрите mix.</li>
|
||
</ul>
|
||
</div>
|
||
</details>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</main>
|
||
|
||
</body>
|
||
</html>
|