feat: stage 0 overview dashboard — all stages in one screen, default view

This commit is contained in:
wasrusgen 2026-05-29 16:12:11 +03:00
parent f6d8e3b6c8
commit 7d6494499d

View File

@ -96,6 +96,62 @@ body{font-family:'Inter',sans-serif;background:var(--body-bg);color:var(--text);
.card-h{font-size:13px;font-weight:700;color:var(--text);margin-bottom:12px}
.two-col{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px}
/* ── Stage 0 — Overview Dashboard ───────────────────── */
.ov-top{background:var(--white);border:1.5px solid var(--border);border-radius:16px;padding:20px 22px;margin-bottom:20px;flex-shrink:0}
.ov-top-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
.ov-top-label{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:#9CA3AF}
.ov-top-pct{font-size:24px;font-weight:800;color:var(--primary);letter-spacing:-1px}
.ov-bar{height:8px;background:var(--border);border-radius:4px;overflow:hidden;margin-bottom:10px}
.ov-bar-fill{height:100%;background:linear-gradient(90deg,var(--primary),var(--mid));border-radius:4px;transition:width .5s}
.ov-next{display:flex;align-items:center;gap:8px;background:var(--light);border-radius:8px;padding:9px 12px}
.ov-next-ic{font-size:14px;flex-shrink:0}
.ov-next-txt{font-size:12px;color:var(--dark);font-weight:500;flex:1}
.ov-next-btn{font-size:12px;font-weight:700;color:var(--primary);background:none;border:none;cursor:pointer;font-family:'Inter',sans-serif;white-space:nowrap;padding:0}
.ov-next-btn:hover{text-decoration:underline}
.ov-stages{display:flex;flex-direction:column;gap:0;position:relative;flex-shrink:0}
.ov-stages::before{content:'';position:absolute;left:27px;top:20px;bottom:20px;width:2px;background:var(--border);z-index:0}
.ov-stage{display:flex;align-items:flex-start;gap:14px;background:var(--white);border:1.5px solid var(--border);border-radius:14px;padding:16px 18px;margin-bottom:10px;position:relative;cursor:pointer;transition:border-color .15s,box-shadow .15s;z-index:1}
.ov-stage:hover{border-color:#D1D5DB;box-shadow:0 2px 8px rgba(0,0,0,.06)}
.ov-stage.done{border-color:rgba(16,185,129,.2)}
.ov-stage.active{border-color:var(--primary);box-shadow:0 0 0 3px rgba(4,120,87,.08),0 4px 12px rgba(4,120,87,.12)}
.ov-stage.locked{opacity:.5;cursor:default}
.ov-stage.locked:hover{border-color:var(--border);box-shadow:none}
.ov-num{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:800;flex-shrink:0}
.ov-stage.done .ov-num{background:var(--light);color:var(--primary);font-size:18px}
.ov-stage.active .ov-num{background:var(--primary);color:#fff;box-shadow:0 4px 10px rgba(4,120,87,.35)}
.ov-stage.pending .ov-num{background:#FEF9C3;color:#854D0E}
.ov-stage.locked .ov-num{background:var(--subtle);color:#CBD5E1}
.ov-body{flex:1;min-width:0}
.ov-stage-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:#9CA3AF;margin-bottom:2px}
.ov-stage.done .ov-stage-lbl{color:var(--primary)}
.ov-stage.active .ov-stage-lbl{color:var(--primary)}
.ov-stage-name{font-size:15px;font-weight:700;color:var(--text);margin-bottom:4px}
.ov-stage.locked .ov-stage-name{color:#9CA3AF}
.ov-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.ov-meta-tag{font-size:11px;color:#374151;background:var(--subtle);border:1px solid var(--border);border-radius:5px;padding:2px 7px;font-weight:500}
.ov-stage.done .ov-meta-tag{background:var(--light);border-color:rgba(16,185,129,.2);color:var(--primary)}
.ov-meta-sep{color:#D1D5DB;font-size:10px}
.ov-right{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex-shrink:0}
.ov-status{font-size:11px;font-weight:700;padding:3px 9px;border-radius:20px}
.ov-status.done{background:var(--light);color:var(--primary)}
.ov-status.active{background:#EFF6FF;color:#1E40AF}
.ov-status.pending{background:#FEF9C3;color:#854D0E}
.ov-status.locked{background:var(--subtle);color:#9CA3AF}
.ov-cta{font-size:12px;font-weight:700;color:var(--primary);background:none;border:none;cursor:pointer;font-family:'Inter',sans-serif;padding:0;white-space:nowrap}
.ov-cta:hover{text-decoration:underline}
.ov-cta.muted{color:#9CA3AF;cursor:default;font-weight:500}
.ov-cta.muted:hover{text-decoration:none}
.ov-mini-bar{width:80px;height:4px;background:var(--border);border-radius:2px;overflow:hidden;margin-top:2px}
.ov-mini-fill{height:100%;border-radius:2px}
.ov-mini-fill.green{background:var(--mid)}
.ov-mini-fill.blue{background:#3B82F6;animation:run 2s ease-in-out infinite}
.ov-mini-fill.yellow{background:#F59E0B;width:50%}
/* Checklist */
.chk{display:flex;align-items:center;gap:9px;padding:8px 0;border-bottom:1px solid var(--subtle)}
.chk:last-child{border-bottom:none}
@ -391,6 +447,15 @@ body{font-family:'Inter',sans-serif;background:var(--body-bg);color:var(--text);
<div class="layout">
<aside class="sb">
<div class="sb-nav">
<div class="si active" id="si0" onclick="go(0)" style="margin-bottom:4px">
<div class="si-num" style="background:rgba(255,255,255,.12);color:rgba(255,255,255,.7);font-size:11px"></div>
<div class="si-body">
<div class="si-name">Обзор проекта</div>
<div class="si-sub">Все этапы · 60% готово</div>
</div>
</div>
<div style="height:1px;background:rgba(255,255,255,.06);margin:4px 18px 8px"></div>
<div class="sb-cap">Путь к результату</div>
<div class="si done" id="si1" onclick="go(1)">
@ -457,6 +522,120 @@ body{font-family:'Inter',sans-serif;background:var(--body-bg);color:var(--text);
<div class="main">
<!-- Stage 0 — Overview Dashboard -->
<div class="sv" id="sv0">
<!-- Overall progress -->
<div class="ov-top">
<div class="ov-top-row">
<div>
<div class="ov-top-label">Прогресс проекта</div>
<div style="font-size:13px;color:var(--muted);margin-top:2px">ООО «ВизелБерг» · Начат 26 мая 2026</div>
</div>
<div class="ov-top-pct">60%</div>
</div>
<div class="ov-bar"><div class="ov-bar-fill" style="width:60%"></div></div>
<div class="ov-next">
<div class="ov-next-ic"></div>
<div class="ov-next-txt">Следующий шаг: ответьте на 4 вопроса Фёдора (Stage 2) и загрузите 3 документа (Stage 3)</div>
<button class="ov-next-btn" onclick="go(2)">К анкете →</button>
</div>
</div>
<!-- Stage cards -->
<div class="ov-stages">
<!-- Stage 1 — Done -->
<div class="ov-stage done" onclick="go(1)">
<div class="ov-num"></div>
<div class="ov-body">
<div class="ov-stage-lbl">Этап 1</div>
<div class="ov-stage-name">Знакомство</div>
<div class="ov-meta">
<span class="ov-meta-tag">Протокол подтверждён</span>
<span class="ov-meta-tag">47 мин · 26 мая</span>
<span class="ov-meta-tag">Иванов А. подписал</span>
</div>
</div>
<div class="ov-right">
<span class="ov-status done">✓ Завершён</span>
<button class="ov-cta">Посмотреть →</button>
</div>
</div>
<!-- Stage 2 — In progress -->
<div class="ov-stage active" onclick="go(2)">
<div class="ov-num">2</div>
<div class="ov-body">
<div class="ov-stage-lbl">Этап 2 · Активен</div>
<div class="ov-stage-name">Диагностика</div>
<div class="ov-meta">
<span class="ov-meta-tag" style="background:#EFF6FF;border-color:#BFDBFE;color:#1E40AF">8 из 12 вопросов</span>
<span class="ov-meta-tag" style="background:#FEF3C7;border-color:#FDE68A;color:#92400E">Остался раздел Фёдор</span>
</div>
<div class="ov-mini-bar" style="margin-top:8px"><div class="ov-mini-fill blue" style="width:67%"></div></div>
</div>
<div class="ov-right">
<span class="ov-status active">В процессе</span>
<button class="ov-cta">Продолжить →</button>
</div>
</div>
<!-- Stage 3 — In progress -->
<div class="ov-stage pending" onclick="go(3)">
<div class="ov-num">3</div>
<div class="ov-body">
<div class="ov-stage-lbl">Этап 3</div>
<div class="ov-stage-name">Сбор документов</div>
<div class="ov-meta">
<span class="ov-meta-tag">3 из 6 загружено</span>
<span class="ov-meta-tag" style="background:#FEF3C7;border-color:#FDE68A;color:#92400E">Ждём Сидорова и Козлову</span>
</div>
<div class="ov-mini-bar" style="margin-top:8px"><div class="ov-mini-fill yellow"></div></div>
</div>
<div class="ov-right">
<span class="ov-status pending">⏳ Неполный</span>
<button class="ov-cta">Загрузить →</button>
</div>
</div>
<!-- Stage 4 — Pending -->
<div class="ov-stage locked">
<div class="ov-num">4</div>
<div class="ov-body">
<div class="ov-stage-lbl">Этап 4</div>
<div class="ov-stage-name">Анализ · Opus 4.8</div>
<div class="ov-meta">
<span class="ov-meta-tag">Запустится после Stage 3</span>
<span class="ov-meta-tag">~15 мин анализа</span>
</div>
</div>
<div class="ov-right">
<span class="ov-status locked">🔒 Ожидает</span>
<span class="ov-cta muted">Недоступен</span>
</div>
</div>
<!-- Stage 5 — Locked -->
<div class="ov-stage locked">
<div class="ov-num">5</div>
<div class="ov-body">
<div class="ov-stage-lbl">Этап 5</div>
<div class="ov-stage-name">TO-BE план</div>
<div class="ov-meta">
<span class="ov-meta-tag">PDF · Интерактив · Задачи</span>
<span class="ov-meta-tag">После анализа Opus 4.8</span>
</div>
</div>
<div class="ov-right">
<span class="ov-status locked">🔒 Заблокирован</span>
<span class="ov-cta muted">Недоступен</span>
</div>
</div>
</div><!-- /ov-stages -->
</div><!-- /sv0 -->
<!-- Этап 1 -->
<div class="sv" id="sv1">
<div class="hero">
@ -1192,8 +1371,9 @@ body{font-family:'Inter',sans-serif;background:var(--body-bg);color:var(--text);
<!-- Demo -->
<div class="demo">
<span class="demo-lbl">Демо</span>
<button class="db on" id="db0" onclick="go(0)">Обзор</button>
<button class="db" id="db1" onclick="go(1)">Этап 1</button>
<button class="db on" id="db2" onclick="go(2)">Этап 2</button>
<button class="db" id="db2" onclick="go(2)">Этап 2</button>
<button class="db" id="db3" onclick="go(3)">Этап 3</button>
<button class="db" id="db4" onclick="go(4)">Этап 4</button>
<button class="db" id="db5" onclick="go(5)">Этап 5</button>
@ -1202,8 +1382,8 @@ body{font-family:'Inter',sans-serif;background:var(--body-bg);color:var(--text);
</div>
<script>
const hints={1:'Этап 1/5 — знакомство завершено',2:'Этап 2/5 — опрос участников',3:'Этап 3/5 — сбор документов',4:'Этап 4/5 — анализ данных',5:'Этап 5/5 — план готов'};
const pcts={1:20,2:40,3:60,4:80,5:100};
const hints={0:'Обзор проекта — все этапы',1:'Этап 1/5 — знакомство завершено',2:'Этап 2/5 — опрос участников',3:'Этап 3/5 — сбор документов',4:'Этап 4/5 — анализ данных',5:'Этап 5/5 — план готов'};
const pcts={0:60,1:20,2:40,3:60,4:80,5:100};
function go(n){
for(let i=1;i<=5;i++){
@ -1272,7 +1452,7 @@ function unlock(nextN){
go(nextN);
}
go(2);
go(0);
</script>
</body>
</html>