sozday-analiz-rashodov-s-uka/index.html

197 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- Дизайн: Стандартный дизайн. Сохраняй все пять CSS; подробности в design.md. -->
<html lang="ru" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Анализ расходов по сервисным контрактам</title>
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
<link rel="stylesheet" href="design-system/kt-ai-components.css">
<link rel="stylesheet" href="design-system/kt-ai-page.css">
<link rel="stylesheet" href="design-system/vibe-theme.css">
<script defer src="design-system/icons/kt-ai-icons.js"></script>
<script defer src="design-system/kt-ai-chart-tip.js"></script>
<style>
.kt-ai-page { max-width: 1200px; }
.kt-ai-page .page-intro { padding: var(--kt-ai-space-8) 0 var(--kt-ai-space-5); }
.kt-ai-page .page-intro h1 { font-size: var(--kt-ai-text-2xl); font-weight: var(--kt-ai-weight-regular); letter-spacing: -.02em; margin: 0 0 var(--kt-ai-space-3); }
.kt-ai-page .page-intro .sub { color: var(--kt-ai-fg-muted); font-size: var(--kt-ai-text-md); max-width: 70ch; margin: 0; }
.kpi-block { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--kt-ai-stack-block); margin-top: var(--kt-ai-space-6); }
.kpi-cell { border: 1px solid var(--kt-ai-border); border-radius: var(--kt-ai-radius-xl); background: var(--kt-ai-card-bg); padding: var(--kt-ai-space-6); display: flex; flex-direction: column; gap: var(--kt-ai-space-2); }
.kpi-cell .lbl { font-size: var(--kt-ai-text-2xs); color: var(--kt-ai-fg-muted); }
.kpi-cell .num { font-size: var(--kt-ai-text-2xl); font-weight: var(--kt-ai-weight-semibold); letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.kpi-cell .note { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); display: flex; align-items: center; gap: var(--kt-ai-space-2); }
.kpi-cell .note .arr { display: inline-flex; width: 14px; height: 14px; flex: none; }
.kpi-cell .note .arr svg { width: 12px; height: 12px; }
.kpi-cell .note.up .arr { color: var(--kt-ai-chart-red); }
.kpi-cell .note.down .arr { color: var(--kt-ai-chart-green); }
.kpi-cell .note.flat .arr { color: var(--kt-ai-fg-faint); }
.anal-block { margin-top: var(--kt-ai-space-9); }
.anal-block h2 { font-size: var(--kt-ai-text-lg); font-weight: var(--kt-ai-weight-semibold); letter-spacing: -.01em; margin: 0 0 var(--kt-ai-space-2); }
.anal-block .hint { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); margin: 0 0 var(--kt-ai-space-5); max-width: 78ch; line-height: 1.5; }
.chart-card { border: 1px solid var(--kt-ai-border); border-radius: var(--kt-ai-radius-2xl); background: var(--kt-ai-bg-elevated); padding: var(--kt-ai-space-6); }
.chart-svg { width: 100%; height: auto; display: block; }
.chart-svg .grid-line { stroke: var(--kt-ai-divider); stroke-width: 1; }
.chart-svg .bar { fill: var(--kt-ai-brand-blue); }
.chart-svg .bar.muted { fill: var(--kt-ai-chart-bar-fill); }
.chart-svg .lbl { font-size: 11px; fill: var(--kt-ai-fg-muted); }
.chart-svg .val { font-size: 11px; font-weight: 600; fill: var(--kt-ai-fg); }
.delta-tbl th.ta-r, .delta-tbl td.ta-r { text-align: right; font-variant-numeric: tabular-nums; }
.delta-tbl th.ta-c { text-align: center; }
.delta-tbl td { vertical-align: middle; }
.delta-tbl .row-name { max-width: 420px; }
.delta-tbl .nm { font-weight: var(--kt-ai-weight-medium); color: var(--kt-ai-fg); }
.delta-tbl .barcell { width: 140px; }
.mini-bar { display: block; height: 6px; border-radius: var(--kt-ai-radius-full); min-width: 4px; }
.mini-bar.up { background: var(--kt-ai-chart-red); }
.mini-bar.down { background: var(--kt-ai-chart-green); }
.delta-tbl td.pos .d-val { color: var(--kt-ai-chart-red); font-weight: var(--kt-ai-weight-semibold); }
.delta-tbl td.neg .d-val { color: var(--kt-ai-chart-green); font-weight: var(--kt-ai-weight-semibold); }
.d-val { font-variant-numeric: tabular-nums; }
.badge-new { font-size: var(--kt-ai-text-2xs); color: var(--kt-ai-fg-muted); background: var(--kt-ai-bg-sunken); border-radius: var(--kt-ai-radius-tag); padding: 1px 6px; margin-left: var(--kt-ai-space-2); white-space: nowrap; }
.two-col { display: grid; grid-template-columns: 1.2fr .8fr; gap: var(--kt-ai-space-6); align-items: start; }
@media (max-width: 900px) { .two-col { grid-template-columns: 1fr; } }
.table-search { max-width: 340px; }
.table-wrap { margin-top: var(--kt-ai-space-5); overflow-x: auto; }
.tbl { font-variant-numeric: tabular-nums; }
.tbl th { white-space: nowrap; }
.tbl .ta-r { text-align: right; }
.tbl td { white-space: nowrap; }
.tbl .row-name { white-space: normal; min-width: 260px; max-width: 460px; }
.tbl tr:hover td { background: var(--kt-ai-bg-hover); }
.tbl .pos { color: var(--kt-ai-chart-red); font-weight: var(--kt-ai-weight-medium); }
.tbl .neg { color: var(--kt-ai-chart-green); font-weight: var(--kt-ai-weight-medium); }
.tbl .dim, .delta-tbl .dim { color: var(--kt-ai-fg-faint); }
.tbl tfoot td { font-weight: var(--kt-ai-weight-semibold); border-top: 1px solid var(--kt-ai-border-strong); }
.rowcount { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); margin-top: var(--kt-ai-space-4); }
.empty-row td { text-align: center; color: var(--kt-ai-fg-faint); padding: var(--kt-ai-space-10) 0; }
.concl { margin-top: var(--kt-ai-space-9); border: 1px solid var(--kt-ai-border); border-radius: var(--kt-ai-radius-2xl); background: var(--kt-ai-card-bg); padding: var(--kt-ai-space-7); }
.concl h2 { font-size: var(--kt-ai-text-lg); font-weight: var(--kt-ai-weight-semibold); margin: 0 0 var(--kt-ai-space-4); }
.concl ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--kt-ai-space-3); }
.concl li { display: flex; gap: var(--kt-ai-space-3); font-size: var(--kt-ai-text-sm); line-height: 1.55; color: var(--kt-ai-fg); }
.concl li .ic { flex: none; width: 18px; height: 18px; margin-top: 1px; display: inline-flex; }
.concl li .ic svg { width: 14px; height: 14px; }
.concl li.warn .ic { color: var(--kt-ai-chart-orange); }
.concl li.risk .ic { color: var(--kt-ai-chart-red); }
.concl li.ok .ic { color: var(--kt-ai-chart-green); }
.concl li.info .ic { color: var(--kt-ai-brand-blue); }
.concl li b { font-weight: var(--kt-ai-weight-semibold); font-variant-numeric: tabular-nums; }
</style>
</head>
<body>
<div class="kt-ai-wrap kt-ai-page" style="padding-top:var(--kt-ai-space-6)">
<div class="page-intro">
<h1>Анализ расходов по сервисным контрактам</h1>
<p class="sub">Детализация за 2023–2025 гг. и 1-е полугодие 2026 (факт). Источник: файл «Расходы по сервисным контрактам.xlsx», 103 позиции. Суммы в тенге, округлены до целых.</p>
</div>
<div class="kpi-block" id="kpiBlock"></div>
<section class="anal-block">
<h2>Динамика расходов по годам</h2>
<p class="hint">1пг 2026 — первые шесть месяцев; для сравнения с полными годами добавлен пунктирный столбец — экстраполированный год (1пг × 2).</p>
<div class="chart-card">
<svg id="yearChart" class="chart-svg" viewBox="0 0 720 260" role="img" aria-label="Динамика расходов по годам, млрд тг"></svg>
</div>
</section>
<section class="anal-block">
<h2>Топ-10 отклонений: 2025 vs 2024</h2>
<p class="hint">По позициям, где есть факт за оба года и отклонение не меньше 0,1 млрд тг. Красное — рост, зелёное — снижение.</p>
<div class="table-wrap">
<table class="kt-ai-table delta-tbl" id="dev25">
<thead><tr>
<th>Позиция</th><th class="ta-r">2024, тг</th><th class="ta-r">2025, тг</th>
<th class="ta-r">Отклонение</th><th class="ta-c">Δ %</th><th class="barcell">Масштаб</th>
</tr></thead>
<tbody></tbody>
</table>
</div>
</section>
<section class="anal-block">
<h2>1-е полугодие 2026: отклонения</h2>
<p class="hint">Сравнение с ориентиром «1-е полугодие 2025» (факт 2025 / 2, при равномерном распределении).</p>
<div class="two-col">
<div class="table-wrap">
<table class="kt-ai-table delta-tbl" id="dev26">
<thead><tr>
<th>Позиция</th><th class="ta-r">1пг 2025 *</th><th class="ta-r">1пг 2026</th>
<th class="ta-r">Отклонение</th><th class="ta-c">Δ %</th>
</tr></thead>
<tbody></tbody>
</table>
<p class="hint" style="margin-top:var(--kt-ai-space-4); margin-bottom:0">* = факт 2025 / 2. Показаны существующие позиции с отклонением &gt; ±0,05 млрд тг.</p>
</div>
<div class="table-wrap">
<table class="kt-ai-table delta-tbl">
<thead><tr><th>Появились в 1пг 2026</th><th class="ta-r">Сумма</th></tr></thead>
<tbody id="new26"></tbody>
</table>
<p class="hint" style="margin-top:var(--kt-ai-space-4); margin-bottom:0">Расходы, которых не было в 2025 году.</p>
</div>
</div>
</section>
<section class="anal-block">
<h2>Что изменилось по номенклатуре</h2>
<div class="two-col">
<div class="table-wrap">
<table class="kt-ai-table delta-tbl">
<thead><tr><th>Появились в 2025 (нет в 2024)</th><th class="ta-r">2025, тг</th></tr></thead>
<tbody id="new25"></tbody>
</table>
<p class="hint" style="margin-top:var(--kt-ai-space-4); margin-bottom:0">Топ-8 из 19 позиций.</p>
</div>
<div class="table-wrap">
<table class="kt-ai-table delta-tbl">
<thead><tr><th>Исчезли в 2025 (были в 2024)</th><th class="ta-r">2024, тг</th></tr></thead>
<tbody id="gone25"></tbody>
</table>
<p class="hint" style="margin-top:var(--kt-ai-space-4); margin-bottom:0">Топ-8 из 17 позиций.</p>
</div>
</div>
</section>
<section class="anal-block">
<h2>Полная детализация</h2>
<p class="hint">Все 103 позиции файла с итоговой строкой. Пусто — расход не был зафиксирован.</p>
<input type="search" id="tblSearch" class="kt-ai-search table-search" placeholder="Поиск по позиции…" aria-label="Поиск по позиции">
<div class="table-wrap" style="margin-top:var(--kt-ai-space-5)">
<table class="kt-ai-table tbl" id="mainTable">
<thead><tr>
<th>Позиция</th><th class="ta-r">2023</th><th class="ta-r">2024</th><th class="ta-r">2025</th><th class="ta-r">Откл. 25/24</th><th class="ta-r">1пг 2026</th>
</tr></thead>
<tbody></tbody>
<tfoot></tfoot>
</table>
</div>
<p class="rowcount" id="rowCount"></p>
</section>
<section class="concl">
<h2>Выводы</h2>
<ul id="conclusions"></ul>
</section>
<footer class="kt-ai-pagefoot" style="margin-top:var(--kt-ai-space-9)">
<span>© 2026 Анализ сервисных контрактов</span>
<span class="kt-ai-spacer"></span>
<span>Данные: факт, тг</span>
</footer>
</div>
<script src="script.js"></script>
</body>
</html>