Update metrics to on-time NSM and inputs

This commit is contained in:
Ruslan Bakiev
2026-02-10 17:40:47 +07:00
parent 72c8faa47d
commit c5959d5dbb

View File

@@ -150,7 +150,7 @@
</div>
</section>
<section id="flow" class="slide">
<section id="flow" class="slide flow-slide">
<div class="slide-top"><span class="slide-num">05</span><span class="slide-label">Key user flow</span></div>
<div class="slide-head">
<h2 class="slide-title">Как это работает: key user flow</h2>
@@ -159,16 +159,13 @@
как сервис их снимает через регламент, доказуемую проверку и эскроу.
</p>
</div>
<div class="slide-main">
<div class="slide-main flow-main">
<div class="flow-wrapper glass-panel rounded-3xl border border-base-300 p-4">
<ClientOnly>
<VueFlow
:nodes="flowNodes"
:edges="flowEdges"
:fit-view-on-init="false"
:default-viewport="{ x: 0, y: 0, zoom: 1 }"
:min-zoom="1"
:max-zoom="1"
:fit-view-on-init="true"
:nodes-draggable="true"
:nodes-connectable="false"
:elements-selectable="true"
@@ -310,10 +307,10 @@
<div class="grid gap-6 md:grid-cols-[1fr_1fr]">
<div>
<h3 class="font-display text-2xl">North Star Metric</h3>
<p class="mt-3 text-sm text-neutral/70">Доля этапов, принятых с первого раза без спора.</p>
<p class="mt-3 text-sm text-neutral/70">Доля этапов, выполненных в обещанный срок.</p>
<p class="mt-3 text-sm text-neutral/70">
Input-метрики: доля этапов с зафиксированными критериями, среднее время согласования
этапа, точность автосметы, доля приемок с «зеленым» статусом.
Input-метрики: ошибка прогноза по срокам (факт минус план), отклонение объема работ от плана,
фактическая длительность по типу работ (средние значения).
</p>
</div>
<div class="grid gap-4">
@@ -434,7 +431,7 @@ const flowNodes = ref([
{
id: '2',
type: 'step',
position: { x: 480, y: 40 },
position: { x: 180, y: 40 },
data: {
step: '02',
title: 'Смета и этапы',
@@ -444,7 +441,7 @@ const flowNodes = ref([
{
id: '3',
type: 'step',
position: { x: 960, y: 40 },
position: { x: 360, y: 40 },
data: {
step: '03',
title: 'Создание заявки',
@@ -454,7 +451,7 @@ const flowNodes = ref([
{
id: '4',
type: 'step',
position: { x: 1440, y: 40 },
position: { x: 540, y: 40 },
data: {
step: '04',
title: 'Выбор исполнителя',
@@ -464,7 +461,7 @@ const flowNodes = ref([
{
id: '5',
type: 'step',
position: { x: 1920, y: 40 },
position: { x: 720, y: 40 },
data: {
step: '05',
title: 'Эскроу и запуск',
@@ -474,7 +471,7 @@ const flowNodes = ref([
{
id: '6',
type: 'step',
position: { x: 2400, y: 40 },
position: { x: 900, y: 40 },
data: {
step: '06',
title: 'Фиксация прогресса',
@@ -484,7 +481,7 @@ const flowNodes = ref([
{
id: '7',
type: 'step',
position: { x: 2880, y: 40 },
position: { x: 1080, y: 40 },
data: {
step: '07',
title: 'Приемка и расчет',
@@ -494,12 +491,12 @@ const flowNodes = ref([
])
const flowEdges = ref([
{ id: 'e1-2', source: '1', target: '2', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'smoothstep', markerEnd: MarkerType.ArrowClosed },
{ id: 'e2-3', source: '2', target: '3', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'smoothstep', markerEnd: MarkerType.ArrowClosed },
{ id: 'e3-4', source: '3', target: '4', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'smoothstep', markerEnd: MarkerType.ArrowClosed },
{ id: 'e4-5', source: '4', target: '5', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'smoothstep', markerEnd: MarkerType.ArrowClosed },
{ id: 'e5-6', source: '5', target: '6', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'smoothstep', markerEnd: MarkerType.ArrowClosed },
{ id: 'e6-7', source: '6', target: '7', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'smoothstep', markerEnd: MarkerType.ArrowClosed }
{ id: 'e1-2', source: '1', target: '2', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'straight', markerEnd: MarkerType.ArrowClosed },
{ id: 'e2-3', source: '2', target: '3', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'straight', markerEnd: MarkerType.ArrowClosed },
{ id: 'e3-4', source: '3', target: '4', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'straight', markerEnd: MarkerType.ArrowClosed },
{ id: 'e4-5', source: '4', target: '5', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'straight', markerEnd: MarkerType.ArrowClosed },
{ id: 'e5-6', source: '5', target: '6', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'straight', markerEnd: MarkerType.ArrowClosed },
{ id: 'e6-7', source: '6', target: '7', sourceHandle: 'source-r', targetHandle: 'target-l', type: 'straight', markerEnd: MarkerType.ArrowClosed }
])
onMounted(() => {
@@ -557,10 +554,11 @@ html {
.flow-wrapper {
width: 100%;
height: 280px;
height: 100%;
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: thin;
position: relative;
}
.flow-wrapper::-webkit-scrollbar {
@@ -582,9 +580,27 @@ html {
height: 100%;
}
.vue-flow {
position: relative;
}
.vue-flow__nodes {
position: absolute;
top: 0;
left: 0;
}
.vue-flow__edges {
position: absolute;
inset: 0;
}
.flow-card {
min-width: 200px;
max-width: 220px;
min-width: 160px;
max-width: 160px;
background: rgba(255, 255, 255, 0.78);
border: 1px solid rgba(20, 20, 20, 0.12);
box-shadow: 0 14px 30px rgba(20, 20, 20, 0.14);
}
.flow-handle {
@@ -699,6 +715,16 @@ html {
gap: 1.5rem;
}
.flow-slide .slide-main {
flex: 1;
min-height: 420px;
}
.flow-main .flow-wrapper {
height: 100%;
min-height: 420px;
}
.glass-panel {
background: rgba(255, 255, 255, 0.55);
border: 1px solid rgba(255, 255, 255, 0.5);
@@ -732,6 +758,12 @@ html {
-webkit-backdrop-filter: blur(16px) saturate(1.05);
}
.flow-card.glass-card {
background: rgba(255, 255, 255, 0.78);
border: 1px solid rgba(20, 20, 20, 0.12);
box-shadow: 0 14px 30px rgba(20, 20, 20, 0.14);
}
.iphone-frame {
position: relative;
width: min(330px, 90vw);
@@ -774,12 +806,12 @@ html {
.iphone-notch {
position: absolute;
top: 10px;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 46%;
height: 24px;
border-radius: 0 0 18px 18px;
width: 42%;
height: 26px;
border-radius: 0 0 20px 20px;
background: #0b0b0e;
box-shadow: 0 6px 10px rgba(0, 0, 0, 0.35);
z-index: 2;