218 lines
14 KiB
HTML
218 lines
14 KiB
HTML
<!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>
|
||
|
||
<div style="margin-top:var(--kt-ai-space-6); padding:var(--kt-ai-space-5) var(--kt-ai-space-6); border:1px dashed var(--kt-ai-border-strong); border-radius:var(--kt-ai-radius-xl); background:var(--kt-ai-bg-sunken); font-size:var(--kt-ai-text-sm); color:var(--kt-ai-fg); display:flex; flex-wrap:wrap; gap:var(--kt-ai-space-3); align-items:center">
|
||
<strong>Скачать отчёт:</strong>
|
||
<a class="kt-ai-btn" data-variant="primary" data-size="sm" href="Отчёт_анализ_расходов_2023-1пг26.xlsx" download>
|
||
<svg style="width:14px;height:14px;vertical-align:-2px;margin-right:6px"><use href="design-system/icons/kt-ai-lucide-sprite.svg#download"></use></svg>
|
||
Отчёт_анализ_расходов_2023-1пг26.xlsx
|
||
</a>
|
||
<a class="kt-ai-btn" data-variant="ghost" data-size="sm" href="presentation.html">
|
||
<svg style="width:14px;height:14px;vertical-align:-2px;margin-right:6px"><use href="design-system/icons/kt-ai-lucide-sprite.svg#external"></use></svg>
|
||
Показать презентацию
|
||
</a>
|
||
<span class="kt-ai-fg-faint" style="font-size:var(--kt-ai-text-xs)">По кнопке «Опубликовать» откроется таблица; презентация живёт на отдельном URL — её можно открыть в другом окне.</span>
|
||
</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. Показаны существующие позиции с отклонением > ±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>
|
||
<div style="margin:var(--kt-ai-space-6) 0 var(--kt-ai-space-6); padding:var(--kt-ai-space-5) var(--kt-ai-space-6); border:1px dashed var(--kt-ai-border-strong); border-radius:var(--kt-ai-radius-xl); background:var(--kt-ai-bg-sunken); font-size:var(--kt-ai-text-sm); color:var(--kt-ai-fg); display:flex; flex-wrap:wrap; gap:var(--kt-ai-space-3); align-items:center">
|
||
<strong>Скачать Excel с отчётом:</strong>
|
||
<a class="kt-ai-btn" data-variant="primary" data-size="sm" href="Отчёт_анализ_расходов_2023-1пг26.xlsx" download>
|
||
<svg style="width:14px;height:14px;vertical-align:-2px;margin-right:6px"><use href="design-system/icons/kt-ai-lucide-sprite.svg#download"></use></svg>
|
||
Отчёт_анализ_расходов_2023-1пг26.xlsx
|
||
</a>
|
||
<span class="kt-ai-fg-faint" style="font-size:var(--kt-ai-text-xs)">6 листов: Сводка, Отклонения 2025/2024, 1пг 2026/1пг 2025, Новые-исчезнувшие, Детализация, Выводы.</span>
|
||
</div>
|
||
</body>
|
||
</html>
|