v1 — справочник нарушений законодательства РК

This commit is contained in:
samruk_1 2026-06-01 05:11:32 +00:00
parent ac3e62bdda
commit fd43fdc10e
3 changed files with 621 additions and 0 deletions

173
AGENTS.md Normal file
View File

@ -0,0 +1,173 @@
<!-- vibe42-agents-version: v3-guided-2026-06-01 -->
# Vibe42 — учебная песочница для лендингов
Workspace юзера `samruk_1`. Это **учебная среда**, где обычные люди (не разработчики) пробуют сделать свой первый сайт.
---
## 🎯 ТВОЯ РОЛЬ
Ты — **гид и помощник**, а не слепой исполнитель. Цель сессии — чтобы юзер вышел с:
1. **рабочим лендингом**, опубликованным по адресу `https://pages.git.vibe42.kz/samruk_1/<repo>/`,
2. ощущением «это было легко» — без серверов, БД, токенов, конфигов.
Юзер не разработчик. Ему важен **результат, который видно в браузере**, а не код.
---
## 🗺 СЦЕНАРИЙ ПЕРВОГО ЗАХОДА (юзер только зашёл, ещё ничего нет)
1. Поздоровайся коротко: «Привет! Тут за 10 минут собираем лендинг и публикуем его в интернете. О чём хочешь сделать?»
2. Если он не знает — предложи **4 конкретных идеи** (выбирай близкие к нему, не абстрактные):
- Промо хобби (фотография / музыка / спорт)
- Резюме / personal page с контактами
- Афиша мероприятия (концерт, день рождения, мастер-класс)
- Меню заведения / прайс услуг
- Лендинг продукта или будущего проекта (waitlist)
3. Уточни **2 короткие детали**: стиль (тёмный/светлый/яркий) и главную цель (рассказать / собрать заявку / показать работы).
4. Сразу делай `./new-project <name>` и собирай страницу. Не спрашивай разрешения на каждый шаг.
---
## 💬 ЕСЛИ ЮЗЕР ОТВЕЧАЕТ РАСПЛЫВЧАТО
Юзер говорит «сделай что-нибудь» / «ну хз» / «сюрприз» → **не делай ничего абстрактного**.
Скажи: «Давай определимся, я задам 3 коротких вопроса:
1. Это для тебя лично, для проекта/бизнеса, или для события?
2. Главная цель — рассказать о чём-то / собрать заявку / показать портфолио?
3. Любимое настроение — строгое тёмное, лёгкое светлое, яркое цветное?»
После ответов **сразу** предложи 2 конкретных варианта названия+структуры. Дай выбрать и иди делать.
---
## 🚫 ЕСЛИ ЮЗЕР ХОЧЕТ СЛОЖНОЕ — ПЕРЕФОРМУЛИРУЙ В ЛЕНДИНГ
| Запрос | Что делаем вместо |
|--------|-------------------|
| «магазин с корзиной» | лендинг с товарами + кнопка «купить» = ссылка на WhatsApp / Telegram |
| «соцсеть» | лендинг будущего проекта + waitlist-форма (Formspree / Getform) |
| «блог с админкой» | personal-page + ссылки на статьи в Telegram/Medium |
| «приложение для записи» | лендинг услуги + ссылка на Calendly / WhatsApp |
| «сайт с входом юзеров» | публичный лендинг без логина (нам логин не нужен) |
| «бот в Telegram» | лендинг с описанием бота + кнопка `t.me/...` |
**Не говори «это невозможно».** Скажи: «У нас песочница только для статических сайтов. Давай сделаем лендинг, который покажет твою идею — а кнопки/формы свяжем с готовыми сервисами (WhatsApp, Telegram, Formspree)». Юзер счастлив, результат за 15 минут.
---
## 📐 ШАБЛОНЫ СТРАНИЦ (выбирай под идею юзера)
### A — Промо продукта/услуги
**Секции:** Hero (заголовок + подзаголовок + CTA-кнопка) → 3-4 преимущества (иконка emoji + текст) → социальное доказательство (отзыв или цифра) → CTA (кнопка/телефон/мессенджер).
### B — Personal / резюме
**Секции:** Hero (фото-аватарка + имя + одна фраза «кто я») → О себе (1-2 абзаца) → 3-5 карточек проектов/опыта → Контакты (email, telegram, github как ссылки-кнопки).
### C — Афиша мероприятия
**Секции:** Hero (название + дата + место крупно) → Программа (список с временем) → Локация (картинка-placeholder + адрес) → Регистрация (форма Formspree или контакт).
### D — Меню / прайс
**Секции:** Hero (название + слоган) → Меню/прайс (категории с ценами) → Контакты (телефон, адрес, часы работы, карта-картинка).
### E — Waitlist для будущего проекта
**Секции:** Hero (название проекта + одна фраза + email-форма) → 3 фичи «что будет» → FAQ (3 пункта) → CTA (та же email-форма).
Все шаблоны — **одна страница, прокрутка вниз**. Никаких роутов, ничего динамического.
---
## ⚡ РИТУАЛ ПОСЛЕ ПЕРВОГО ЗАПУСКА
Как только готов первый рабочий вариант (даже грубый):
1. **Сразу запушь:**
```bash
git add -A
git commit -m "v1"
git push origin HEAD:pages
```
2. **ОБЯЗАТЕЛЬНО** дай юзеру ссылку **жирно**:
> 🎉 Готово! Твой лендинг здесь: **https://pages.git.vibe42.kz/samruk_1/<repo>/**
3. Скажи: «Открой в новой вкладке, посмотри. Что хочешь поменять?»
4. Дальше короткие итерации: правка → push → новый URL-показ. Каждые 2-3 правки — push.
---
## ⚠️ ЖЕЛЕЗНЫЕ ПРАВИЛА (НЕ нарушать никогда)
1. **Только статика — HTML + CSS + JS в браузере.**
2. **Никакого бэкенда.** Никаких Node/Express/FastAPI/Django/PHP/Go-серверов. Никаких БД. Никакого Redis.
3. **Никакой аутентификации / OAuth / JWT.**
4. **Никакого Docker, nginx, sudo, системных настроек.**
5. **Никаких тяжёлых сборщиков** (`npm install` дерево на 500МБ). Tailwind — только через CDN.
6. **НИКОГДА `git init` в workspace root (`/srv/opencode/workspaces/users/samruk_1`)** — это папка-контейнер юзера, не репозиторий.
---
## ✅ ВСЕГДА работай через `./new-project`
Если юзер сказал «сделай сайт NAME» / «создай проект NAME»:
```bash
cd /srv/opencode/workspaces/users/samruk_1
./new-project NAME # создаёт repo в Gitea + клонит локально в ./NAME/
cd NAME
# теперь создавай index.html / style.css / script.js внутри ./NAME
```
`./new-project` сам создаёт repo, клонит, и копирует туда `AGENTS.md` + `design.md`.
---
## 🌐 Git и публикация
**НЕТ GitHub.** Self-hosted git: **https://git.vibe42.kz**
- Профиль юзера: https://git.vibe42.kz/samruk_1
- Pages (живые лендинги): https://pages.git.vibe42.kz/samruk_1/<repo>/
- Креды уже в `/srv/opencode/workspaces/users/samruk_1/.git-credentials` — git push/clone работают без пароля
- **НЕ спрашивай юзера про GitHub URL / токен** — их не нужно
### Опубликовать лендинг
```bash
git add -A
git commit -m "site"
git push origin HEAD:pages
```
Ветка **`pages`** (Caddy её обслуживает; `gh-pages` тоже работает как fallback). Push → лендинг доступен мгновенно.
---
## 🔧 Когда что-то идёт не так
- **Pages 404** → запушь ветку `pages` снова: `git push origin HEAD:pages -f`
- **Не дёргай Gitea API типа `/repos/.../pages`, `/settings/pages`, `/deploy_keys`** — их нет
- **Не пытайся «настроить Pages через UI Gitea»** — Pages у нас работают только через push в ветку `pages`
- Запуталось — сделай новый чистый проект через `./new-project NAME-v2`, перенеси туда работающий index.html
---
## ❌ Чего НЕ делать НИКОГДА
- ❌ `git init` в workspace root
- ❌ `npm install` с прод-зависимостями (express/mongoose/pg/prisma/next/nuxt)
- ❌ Создавать `server.js` / `app.py` / `main.go` как backend
- ❌ Использовать `gh` CLI или GitHub API
- ❌ Вызывать Gitea Pages-API (его нет)
- ❌ Долгое отлаживание Pages — почти всегда решение «push HEAD:pages»
- ❌ Просить юзера ввести токен/URL/пароль — всё уже настроено
- ❌ Задавать юзеру 10 вопросов подряд (максимум 2-3 за раз)
- ❌ Показывать юзеру голый код больше 1 раза — ему важен результат, а не как написано
- ❌ Предлагать «давай сначала дизайн в Figma» — мы делаем сразу в HTML
- ❌ Говорить «это сложно» — переформулируй в простое
- ❌ Зависать в обсуждениях — сделай первый вариант грубо, потом итерируй
---
## 🎨 design.md
Рядом лежит `design.md` с готовой палитрой, типографикой и стартер-шаблоном `index.html`. **Начинай с него.** Не выдумывай новые цвета — модифицируй существующие.

110
design.md Normal file
View File

@ -0,0 +1,110 @@
<!-- vibe42-design-version: v1-2026-06-01 -->
# Design system — Vibe42 песочница
Базовые цвета и типографика для лендингов. Можно отклоняться, но начинай с этого.
## Палитра
| Token | Hex | Использование |
|-------|-----|---------------|
| `--ink` | `#0F1218` | Тёмный фон / основной текст |
| `--cyan` | `#00E5FF` | Основной акцент (кнопки, лого) |
| `--cyan-50` | `#E8FCFF` | Светлая подложка для акцентов |
| `--white` | `#FFFFFF` | Основной фон |
| `--gray-500` | `#5B6573` | Вторичный текст |
| `--gray-100` | `#F2F4F7` | Сепараторы / тонкие фоны |
## Типографика
```css
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
```
| Уровень | Размер | Вес | line-height |
|---------|--------|-----|-------------|
| h1 (hero) | 56px | 800 | 1.05 |
| h2 (section) | 36px | 700 | 1.15 |
| h3 | 22px | 700 | 1.3 |
| body | 17px | 400 | 1.6 |
| small | 14px | 400 | 1.5 |
На мобиле — h1 уменьши до 36px, h2 до 28px.
## Лейаут
- max-width контента: **1140px** (контейнер с padding по бокам)
- секция: `padding: 80px 24px` (мобила: `48px 20px`)
- gap между блоками внутри секции: `24-32px`
- border-radius: `8px` (кнопки, карточки), `16px` (большие карточки)
## Кнопки
```css
.btn-primary {
background: var(--cyan); color: var(--ink);
padding: 14px 28px; border-radius: 8px;
font-weight: 700; text-decoration: none;
display: inline-block;
}
.btn-secondary {
background: transparent; color: var(--ink);
border: 2px solid var(--ink);
padding: 12px 26px; border-radius: 8px;
}
```
## Стартер `index.html`
```html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Мой проект</title>
<style>
:root{--ink:#0F1218;--cyan:#00E5FF;--cyan-50:#E8FCFF;--white:#fff;--gray-500:#5B6573;--gray-100:#F2F4F7}
*{box-sizing:border-box;margin:0;padding:0}
body{font:17px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;color:var(--ink);background:var(--white)}
.container{max-width:1140px;margin:0 auto;padding:80px 24px}
.hero{background:var(--ink);color:var(--white)}
.hero h1{font-size:56px;font-weight:800;line-height:1.05;margin-bottom:24px}
.hero p{font-size:20px;color:#9aa3b2;max-width:600px;margin-bottom:32px}
.btn{display:inline-block;background:var(--cyan);color:var(--ink);padding:14px 28px;border-radius:8px;font-weight:700;text-decoration:none}
.btn:hover{background:#1be5ff}
.section h2{font-size:36px;font-weight:700;margin-bottom:24px}
.card{background:var(--gray-100);border-radius:16px;padding:32px;margin-bottom:16px}
@media (max-width:640px){.hero h1{font-size:36px}.section h2{font-size:28px}.container{padding:48px 20px}}
</style>
</head>
<body>
<section class="hero">
<div class="container">
<h1>Заголовок проекта</h1>
<p>Подзаголовок — пара предложений о чём это.</p>
<a class="btn" href="#section">Начать</a>
</div>
</section>
<section id="section" class="section">
<div class="container">
<h2>Секция</h2>
<div class="card">Контент карточки.</div>
<div class="card">Контент карточки.</div>
</div>
</section>
</body>
</html>
```
## Чем НЕ пользоваться
- Bootstrap, Material UI, Chakra, Ant Design — слишком тяжело и не нужно для лендинга
- Font Awesome — используй emoji (🚀 ⚡ ✨) или inline SVG
- jQuery — vanilla JS более чем достаточно
## Чем МОЖНО (если очень надо)
- **Tailwind через CDN**: `<script src="https://cdn.tailwindcss.com"></script>` — для прототипа OK
- **Lottie animations через CDN**
- **Placeholder картинки**: `https://picsum.photos/800/600`, `https://placehold.co/600x400`
- **Шрифты Google Fonts через `<link>`** в head

338
index.html Normal file
View File

@ -0,0 +1,338 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Нарушения законодательства РК — справочник</title>
<style>
:root {
--ink: #0F1218;
--cyan: #00E5FF;
--cyan-50: #E8FCFF;
--white: #fff;
--gray-500: #5B6573;
--gray-100: #F2F4F7;
--red: #E53935;
--red-light: #FFEBEE;
--orange: #F57C00;
--orange-light: #FFF3E0;
--green: #2E7D32;
--green-light: #E8F5E9;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font: 17px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
color: var(--ink);
background: var(--white);
}
.container { max-width: 1140px; margin: 0 auto; padding: 0 24px; }
.hero {
background: var(--ink);
color: var(--white);
padding: 100px 0 80px;
}
.hero h1 {
font-size: 48px; font-weight: 800; line-height: 1.1;
margin-bottom: 16px;
}
.hero p {
font-size: 20px; color: #9aa3b2;
max-width: 600px; margin-bottom: 40px;
}
.search-box {
display: flex; gap: 12px; max-width: 700px;
background: rgba(255,255,255,0.08);
border: 2px solid rgba(255,255,255,0.15);
border-radius: 12px; padding: 8px;
}
.search-box input {
flex: 1; background: none; border: none;
color: var(--white); font-size: 17px; padding: 12px 16px;
outline: none;
}
.search-box input::placeholder { color: rgba(255,255,255,0.4); }
.search-box button {
background: var(--cyan); color: var(--ink);
border: none; padding: 12px 28px; border-radius: 8px;
font-size: 16px; font-weight: 700; cursor: pointer;
}
.search-box button:hover { background: #1be5ff; }
.results-section { padding: 64px 0 80px; }
.stats-bar {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 32px; flex-wrap: wrap; gap: 16px;
}
.stats-bar .count { font-size: 15px; color: var(--gray-500); }
.filters {
display: flex; gap: 8px; flex-wrap: wrap;
}
.filter-btn {
padding: 6px 16px; border-radius: 20px; border: 1.5px solid var(--gray-100);
background: var(--white); font-size: 14px; cursor: pointer;
transition: all 0.15s; color: var(--gray-500);
}
.filter-btn:hover { border-color: var(--cyan); color: var(--ink); }
.filter-btn.active {
background: var(--ink); color: var(--white); border-color: var(--ink);
}
.filter-btn.code-koap.active { background: #1565C0; border-color: #1565C0; }
.filter-btn.code-uk.active { background: var(--red); border-color: var(--red); }
.filter-btn.code-tk.active { background: var(--orange); border-color: var(--orange); }
.filter-btn.code-nk.active { background: var(--green); border-color: var(--green); }
.results-grid {
display: grid; gap: 16px;
}
.violation-card {
border: 1px solid var(--gray-100); border-radius: 12px;
padding: 28px 32px; display: grid;
grid-template-columns: 1fr auto;
gap: 16px 24px; align-items: start;
transition: box-shadow 0.15s, transform 0.15s;
}
.violation-card:hover {
box-shadow: 0 4px 24px rgba(0,0,0,0.06);
transform: translateY(-1px);
}
.violation-card .info { min-width: 0; }
.violation-card .info h3 {
font-size: 18px; font-weight: 700; margin-bottom: 6px;
}
.violation-card .info .desc {
font-size: 15px; color: var(--gray-500); line-height: 1.55;
}
.violation-card .article {
display: flex; align-items: center; gap: 8px;
padding: 10px 18px; border-radius: 8px;
font-weight: 700; font-size: 14px; white-space: nowrap;
text-align: center; flex-shrink: 0;
}
.article.koap { background: #E3F2FD; color: #1565C0; }
.article.uk { background: var(--red-light); color: var(--red); }
.article.tk { background: var(--orange-light); color: var(--orange); }
.article.nk { background: var(--green-light); color: var(--green); }
.article .code-label { font-size: 11px; font-weight: 600; }
.violation-card .penalty {
grid-column: 1 / -1; font-size: 14px; color: var(--gray-500);
padding-top: 12px; border-top: 1px solid var(--gray-100);
display: flex; gap: 6px; align-items: baseline;
}
.penalty-label {
font-weight: 600; color: var(--ink); white-space: nowrap;
}
.empty-state {
text-align: center; padding: 80px 20px; color: var(--gray-500);
}
.empty-state .emoji { font-size: 48px; margin-bottom: 16px; }
.empty-state h3 { font-size: 20px; color: var(--ink); margin-bottom: 8px; }
footer {
text-align: center; padding: 40px 24px;
color: var(--gray-500); font-size: 14px;
border-top: 1px solid var(--gray-100);
}
footer a { color: var(--cyan); text-decoration: none; }
@media (max-width: 640px) {
.hero { padding: 64px 0 48px; }
.hero h1 { font-size: 30px; }
.hero p { font-size: 17px; }
.search-box { flex-direction: column; gap: 8px; }
.search-box button { width: 100%; }
.violation-card { grid-template-columns: 1fr; padding: 20px; }
.violation-card .article { justify-self: start; }
}
</style>
</head>
<body>
<section class="hero">
<div class="container">
<h1>&#x1F4DC; Нарушения законодательства РК</h1>
<p>Опишите ситуацию или введите ключевые слова — найдём соответствующие статьи КоАП, УК, ТК и НК РК.</p>
<div class="search-box">
<input type="text" id="search" placeholder="Например: драка, шум ночью, кража, без прав за рулём..." autofocus>
<button onclick="search()">Найти</button>
</div>
</div>
</section>
<section class="results-section">
<div class="container">
<div class="stats-bar">
<span class="count" id="stats">Всего: 50 нарушений</span>
<div class="filters" id="filters">
<button class="filter-btn active" data-code="all" onclick="setFilter('all',this)">Все</button>
<button class="filter-btn code-koap" data-code="koap" onclick="setFilter('koap',this)">КоАП</button>
<button class="filter-btn code-uk" data-code="uk" onclick="setFilter('uk',this)">УК</button>
<button class="filter-btn code-tk" data-code="tk" onclick="setFilter('tk',this)">ТК</button>
<button class="filter-btn code-nk" data-code="nk" onclick="setFilter('nk',this)">НК</button>
</div>
</div>
<div class="results-grid" id="results"></div>
<div class="empty-state" id="empty" style="display:none">
<div class="emoji">&#x1F50D;</div>
<h3>Ничего не найдено</h3>
<p>Попробуйте другие ключевые слова или измените фильтр.</p>
</div>
</div>
</section>
<footer>
<div class="container">
Справочник носит ознакомительный характер. Точные формулировки — см. официальные тексты кодексов на <a href="https://adilet.zan.kz" target="_blank">adilet.zan.kz</a>
</div>
</footer>
<script>
const VIOLATIONS = [
{ id:1, keywords:["мелкое хулиганство","хулиган","ругался матом","нецензурная брань","приставал","оскорблял прохожих","нарушал общественный порядок","сквернословие"], desc:"Мелкое хулиганство — нецензурная брань в общественных местах, оскорбительное приставание к гражданам, нарушение общественного порядка", code:"koap", article:"ст. 434", penalty:"Штраф 20 МРП, либо административный арест до 15 суток" },
{ id:2, keywords:["тишина","шум","ночью","ночной шум","громкая музыка","ремонт ночью","крики","нарушение тишины","соседи шумят","шумят соседи"], desc:"Нарушение тишины и покоя граждан в ночное время (с 23:00 до 06:00), в выходные и праздничные дни", code:"koap", article:"ст. 437", penalty:"Штраф 10 МРП, при повторном — 20 МРП" },
{ id:3, keywords:["распитие","алкоголь","пьёт","пьют","пьяный","пьяные","общественное место","пиво на улице","водка","нетрезвый вид","пьянство","выпивка"], desc:"Распитие алкогольных напитков в общественных местах или появление в общественных местах в пьяном виде, оскорбляющем человеческое достоинство", code:"koap", article:"ст. 440", penalty:"Штраф 5 МРП, при повторном — 10 МРП, либо административный арест до 5 суток" },
{ id:4, keywords:["курение","курил","курит","сигарета","кальян","вейп","неположенное место","табак"], desc:"Курение табачных изделий, кальяна, вейпов в неположенных местах (подъезды, остановки, детские площадки, транспорт, учреждения)", code:"koap", article:"ст. 441", penalty:"Штраф 3 МРП" },
{ id:5, keywords:["скорость","превышение","гонка","быстрая езда","лихач","превысил скорость"], desc:"Превышение установленной скорости движения транспортного средства", code:"koap", article:"ст. 592", penalty:"Штраф от 10 до 40 МРП, в зависимости от величины превышения" },
{ id:6, keywords:["красный свет","проезд на красный","светофор","проехал на запрещающий","на красный"], desc:"Проезд на запрещающий сигнал светофора или жест регулировщика", code:"koap", article:"ст. 599", penalty:"Штраф 10 МРП" },
{ id:7, keywords:["без прав","нет прав","права","лишён прав","не имел права управления","водитель без прав","управление без прав"], desc:"Управление транспортным средством лицом, не имеющим права управления, или лишённым такого права", code:"koap", article:"ст. 612", penalty:"Штраф 30 МРП, при повторном — 70 МРП, либо административный арест до 15 суток" },
{ id:8, keywords:["пьяный за рулём","нетрезвый водитель","алкоголь за рулём","выпил и сел за руль","управление в нетрезвом","алкогольное опьянение за рулём","пьяная езда"], desc:"Управление транспортным средством в состоянии алкогольного, наркотического или токсикоманического опьянения", code:"koap", article:"ст. 608", penalty:"Лишение прав на 3 года, административный арест до 15 суток. При повторном — уголовная ответственность по ст. 346 УК" },
{ id:9, keywords:["неповиновение","полиция","полицейский","не подчинился","сопротивление полиции","не выполнил требование","законное требование"], desc:"Неповиновение законному требованию сотрудника правоохранительного органа", code:"koap", article:"ст. 667", penalty:"Штраф 10 МРП, либо административный арест до 10 суток" },
{ id:10, keywords:["мелкое хищение","украл","воровство","магазин","супермаркет","шоплифтинг","кража в магазине","стянул","мелкая кража","хищение"], desc:"Мелкое хищение чужого имущества на сумму до 10 МРП", code:"koap", article:"ст. 187", penalty:"Штраф до 25 МРП, либо административный арест до 15 суток. Свыше 10 МРП — уголовная ответственность по ст. 188 УК" },
{ id:11, keywords:["без билета","заяц","безбилетный проезд","не оплатил проезд","проезд без билета","автобус без билета","контролёр"], desc:"Безбилетный проезд в общественном транспорте", code:"koap", article:"ст. 622", penalty:"Штраф 0,5 МРП" },
{ id:12, keywords:["благоустройство","мусор","грязь","урна","выбросил мусор","мусорил","загрязнение","загрязнил","не убрал"], desc:"Нарушение правил благоустройства, загрязнение общественных мест, выброс мусора вне установленных мест", code:"koap", article:"ст. 505", penalty:"Штраф 10 МРП" },
{ id:13, keywords:["пожарная безопасность","пожар","не потушил костёр","костёр","развёл огонь","поджёг траву","сжигание мусора"], desc:"Нарушение правил пожарной безопасности, разведение костров в неположенных местах", code:"koap", article:"ст. 410", penalty:"Штраф 5-10 МРП" },
{ id:14, keywords:["санитарные нормы","антисанитария","грязь в заведении","кафе грязное","ресторан нарушение","санпин","санитария","пищевое отравление"], desc:"Нарушение санитарно-эпидемиологических норм и правил гигиены", code:"koap", article:"ст. 425", penalty:"Штраф до 200 МРП для юрлиц, до 30 МРП для физлиц" },
{ id:15, keywords:["незаконная торговля","торговля без регистрации","стихийная торговля","без лицензии","без патента","уличная торговля","базар без разрешения"], desc:"Незаконная предпринимательская деятельность, торговля без регистрации и разрешительных документов", code:"koap", article:"ст. 463", penalty:"Штраф 15-50 МРП" },
{ id:16, keywords:["обман потребителя","обвес","обсчёт","недолив","недовес","обманули в магазине","завысили цену","чек не тот","обсчитали"], desc:"Обман потребителей — обвес, обсчёт, введение в заблуждение о потребительских свойствах товара", code:"koap", article:"ст. 190", penalty:"Штраф 10-50 МРП" },
{ id:17, keywords:["оскорбление","оскорбил","унижение чести","ущемил достоинство","обозвал","обзывался","хамство","личное оскорбление"], desc:"Оскорбление — унижение чести и достоинства другого лица, выраженное в неприличной форме", code:"koap", article:"ст. 131", penalty:"Штраф 20 МРП" },
{ id:18, keywords:["клевета","клевещет","распускает слухи","ложные сведения","порочащие сведения","очернил","ложь","напраслина","поклёп"], desc:"Клевета — распространение заведомо ложных сведений, порочащих честь и достоинство другого лица", code:"uk", article:"ст. 130", penalty:"Штраф до 500 МРП, исправительные работы, либо ограничение свободы до 1 года" },
{ id:19, keywords:["побои","избил","ударил","драка","избиение","пощёчина","телесные повреждения","синяки","рукоприкладство","нападение"], desc:"Побои — нанесение побоев, не повлёкших причинения лёгкого вреда здоровью, или совершение иных насильственных действий, причинивших физическую боль", code:"koap", article:"ст. 73-1", penalty:"Штраф 10 МРП, либо административный арест до 10 суток" },
{ id:20, keywords:["жилище","квартирный вопрос","соседи","затопил","затопили","шум в квартире","проживание без регистрации","незаконная перепланировка","жилищные споры"], desc:"Нарушение правил пользования жилыми помещениями, самовольная перепланировка, нарушение прав соседей", code:"koap", article:"ст. 506", penalty:"Штраф 10-50 МРП" },
{ id:21, keywords:["кража","украл","вор","воровство","похитил","обокрал","грабёж","разбой","хищение","тайное хищение","карманник"], desc:"Кража — тайное хищение чужого имущества", code:"uk", article:"ст. 188", penalty:"Штраф до 2000 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 12 лет (в зависимости от размера и обстоятельств)" },
{ id:22, keywords:["грабёж","грабитель","ограбление","отобрал","отнял","вырвал сумку","сорвал цепочку","открытое хищение","уличное ограбление"], desc:"Грабёж — открытое хищение чужого имущества", code:"uk", article:"ст. 191", penalty:"Штраф до 3000 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 12 лет" },
{ id:23, keywords:["разбой","нападение","напал","ограбление с насилием","разбойное нападение","угрожал ножом","вооружённое нападение"], desc:"Разбой — нападение с целью хищения чужого имущества, сопряжённое с насилием либо угрозой применения насилия", code:"uk", article:"ст. 192", penalty:"Лишение свободы от 3 до 15 лет с конфискацией имущества" },
{ id:24, keywords:["мошенничество","мошенник","обманул","обман","афера","аферист","лохотрон","развод","финансовая пирамида","выманил деньги","кинул"], desc:"Мошенничество — хищение чужого имущества или приобретение права на чужое имущество путём обмана или злоупотребления доверием", code:"uk", article:"ст. 190", penalty:"Штраф до 4000 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 10 лет" },
{ id:25, keywords:["уголовное хулиганство","хулиган","особо дерзкое","групповое хулиганство","хулиганство с оружием","злостное хулиганство"], desc:"Хулиганство — особо дерзкое нарушение общественного порядка, сопровождающееся применением насилия, угрозой его применения, уничтожением или повреждением имущества", code:"uk", article:"ст. 293", penalty:"Штраф до 2000 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 7 лет" },
{ id:26, keywords:["убийство","убил","умертвил","лишил жизни","смерть","убийца","смертельный исход"], desc:"Убийство — противоправное умышленное причинение смерти другому человеку", code:"uk", article:"ст. 99", penalty:"Лишение свободы от 6 до 20 лет, либо пожизненное лишение свободы" },
{ id:27, keywords:["вред здоровью","тяжкий вред","избил до больницы","покалечил","сломал руку","сломал ногу","перелом","инвалидность","тяжкие телесные"], desc:"Умышленное причинение тяжкого вреда здоровью — опасного для жизни, или повлёкшего потерю зрения, речи, слуха, органа, или заболевание наркоманией/токсикоманией", code:"uk", article:"ст. 106", penalty:"Ограничение свободы, либо лишение свободы от 3 до 12 лет" },
{ id:28, keywords:["изнасилование","насилие","сексуальное насилие","надругательство","насильственные действия сексуального характера"], desc:"Изнасилование — половое сношение с применением насилия, угрозы или с использованием беспомощного состояния потерпевшего", code:"uk", article:"ст. 120", penalty:"Лишение свободы от 5 до 20 лет, либо пожизненно" },
{ id:29, keywords:["вымогательство","вымогает","шантаж","рэкет","требует деньги","угрожает","крыша","дань"], desc:"Вымогательство — требование передачи чужого имущества или права на имущество под угрозой применения насилия, уничтожения имущества или распространения позорящих сведений", code:"uk", article:"ст. 194", penalty:"Ограничение свободы, либо лишение свободы до 15 лет с конфискацией" },
{ id:30, keywords:["присвоение","растрата","присвоил","растратил","казнокрадство","растрата бюджета","хищение на работе","бухгалтер украл","менеджер присвоил"], desc:"Присвоение или растрата — хищение чужого имущества, вверенного виновному", code:"uk", article:"ст. 189", penalty:"Штраф до 3000 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 12 лет" },
{ id:31, keywords:["взятка","взяткодатель","дал взятку","подкуп","коррупция","дал на лапу","откат","благодарность должностному лицу"], desc:"Дача взятки — незаконная передача должностному лицу денег, ценных бумаг, имущества, оказание услуг за действия/бездействие в пользу взяткодателя", code:"uk", article:"ст. 367", penalty:"Штраф до 60-кратной суммы взятки, исправительные работы, либо лишение свободы до 15 лет с конфискацией" },
{ id:32, keywords:["взятка","получение взятки","взяточник","чиновник взял","коррупционер","получил взятку","мздоимство","продажный чиновник"], desc:"Получение взятки — незаконное получение должностным лицом денег, ценных бумаг, имущества, услуг за действия/бездействие в пользу взяткодателя", code:"uk", article:"ст. 366", penalty:"Штраф до 80-кратной суммы взятки, либо лишение свободы до 15 лет с конфискацией и пожизненным лишением права занимать должности" },
{ id:33, keywords:["должностные полномочия","превышение полномочий","злоупотребил","чиновник нарушил","власть","административный ресурс","превысил полномочия"], desc:"Злоупотребление должностными полномочиями — использование должностным лицом своих полномочий вопреки интересам службы", code:"uk", article:"ст. 361", penalty:"Штраф до 5000 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 8 лет" },
{ id:34, keywords:["угон","угнал","автоугон","машину угнали","угнали авто","угнал машину","неправомерное завладение авто"], desc:"Неправомерное завладение автомобилем или иным транспортным средством без цели хищения (угон)", code:"uk", article:"ст. 200", penalty:"Штраф до 500 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 12 лет" },
{ id:35, keywords:["наркотики","наркота","хранение","марихуана","трава","героин","мефедрон","синтетика","закладка","наркоман","запрещённые вещества","психотропы"], desc:"Незаконное приобретение, хранение, перевозка, изготовление, переработка наркотических средств без цели сбыта", code:"uk", article:"ст. 296", penalty:"Штраф до 5000 МРП, исправительные работы, ограничение свободы, либо лишение свободы до 15 лет" },
{ id:36, keywords:["наркотики","сбыт","продажа наркотиков","закладчик","дилер","распространение","торговля наркотиками","наркоторговля","наркоторговец"], desc:"Незаконный сбыт, пересылка наркотических средств и психотропных веществ", code:"uk", article:"ст. 297", penalty:"Лишение свободы от 5 до 20 лет, либо пожизненно с конфискацией" },
{ id:37, keywords:["трудовой договор","без договора","не оформлен","нелегальный работник","теневая занятость","трудоустройство без договора","без трудовой","работает без оформления"], desc:"Допуск работника к работе без заключения трудового договора", code:"tk", article:"ст. 90 КоАП", penalty:"Штраф 30-100 МРП" },
{ id:38, keywords:["зарплата","не платит зарплату","задержка зарплаты","не выплатил","долг по зарплате","недоплатил","чёрная зарплата","зарплата в конверте"], desc:"Невыплата заработной платы в полном объёме и в установленные сроки", code:"tk", article:"ст. 113 ТК РК", penalty:"Штраф до 200 МРП для работодателя, пеня за каждый день просрочки" },
{ id:39, keywords:["увольнение","незаконно уволили","сократили","уволен без причины","восстановление на работе","трудовой спор","нарушение при увольнении"], desc:"Незаконное увольнение работника или нарушение процедуры расторжения трудового договора", code:"tk", article:"ст. 52, 56 ТК РК", penalty:"Восстановление на работе, компенсация за вынужденный прогул, возмещение морального вреда" },
{ id:40, keywords:["отпуск","не дали отпуск","без отпуска","отказ в отпуске","не оплачен отпуск","отпускные","отгул","работа без отпуска"], desc:"Непредоставление ежегодного оплачиваемого трудового отпуска в течение двух лет подряд", code:"tk", article:"ст. 87, 92 ТК РК", penalty:"Штраф до 100 МРП для работодателя" },
{ id:41, keywords:["сверхурочные","переработка","работа сверх нормы","ненормированный график","без доплаты за сверхурочные","переработки без оплаты"], desc:"Привлечение к сверхурочной работе без согласия работника либо без соответствующей оплаты", code:"tk", article:"ст. 77, 78 ТК РК", penalty:"Штраф до 100 МРП, предписание устранить нарушение с доплатой" },
{ id:42, keywords:["налоги","не платит налоги","уклонение от налогов","сокрытие доходов","налоговая","не сдал декларацию","налоговая проверка","недоимка"], desc:"Уклонение от уплаты налогов и других обязательных платежей в бюджет", code:"nk", article:"ст. 275 КоАП", penalty:"Штраф от 20% до 50% от неуплаченной суммы налога" },
{ id:43, keywords:["налоговая декларация","не подал декларацию","просрочил декларацию","всеобщее декларирование","декларация о доходах","фно 270","не сдал отчёт"], desc:"Непредставление налоговой отчётности в установленный срок", code:"nk", article:"ст. 272 КоАП", penalty:"Штраф 30-70 МРП, при повторном — до 110 МРП" },
{ id:44, keywords:["чек","не выбил чек","касса","контрольно-кассовая машина","ккм","без чека","онлайн-ккм","не применил ккм"], desc:"Неприменение контрольно-кассовой машины (ККМ) при осуществлении денежных расчётов", code:"nk", article:"ст. 284 КоАП", penalty:"Штраф 25-50 МРП, при повторном — до 100 МРП" },
{ id:45, keywords:["семья","домашнее насилие","бытовое насилие","избил жену","избил мужа","семейный скандал","агрессор","побои в семье","бьёт жену","домашний тиран"], desc:"Противоправные действия в сфере семейно-бытовых отношений — насилие, жестокое обращение в семье", code:"koap", article:"ст. 73, 73-1, 73-2", penalty:"Штраф, административный арест до 30 суток, защитное предписание. При систематичности — уголовная ответственность" },
{ id:46, keywords:["ребёнок","несовершеннолетний","детский труд","незаконная работа ребёнка","эксплуатация детей","детский сад без лицензии","оставил ребёнка без присмотра"], desc:"Нарушение прав и законных интересов несовершеннолетних, вовлечение в совершение административных правонарушений", code:"koap", article:"ст. 127, 442", penalty:"Штраф до 200 МРП, лишение родительских прав" },
{ id:47, keywords:["тоналды көлік","авто без номеров","скрытые номера","тонировка","затемнённые стёкла","тонировка не по госту"], desc:"Управление транспортным средством со стёклами, не соответствующими нормам светопропускания (незаконная тонировка)", code:"koap", article:"ст. 590 ч.5", penalty:"Штраф 10 МРП, предписание устранить в течение суток" },
{ id:48, keywords:["ремни безопасности","не пристёгнут","езда без ремня","не пристегнулся","пассажир без ремня","без ремня"], desc:"Управление транспортным средством либо перевозка пассажиров без использования ремней безопасности", code:"koap", article:"ст. 593 ч.1", penalty:"Штраф 3 МРП" },
{ id:49, keywords:["телефон за рулём","мобильный","разговор по телефону","смс за рулём","телефон без гарнитуры","писал за рулём"], desc:"Использование телефона во время управления транспортным средством без устройства hands-free", code:"koap", article:"ст. 591", penalty:"Штраф 5 МРП" },
{ id:50, keywords:["лес","незаконная вырубка","вырубил дерево","ёлка","сосна","браконьерство","незаконная охота","рыболовство без лицензии","незаконная рыбалка"], desc:"Незаконная порубка деревьев и кустарников, незаконная охота, рыболовство без разрешения", code:"koap", article:"ст. 381, 382, 383", penalty:"Штраф до 500 МРП с конфискацией орудий, возмещение ущерба" }
];
let currentQuery = "";
let currentCode = "all";
function codeLabel(c) {
const map = { koap: "КоАП", uk: "УК", tk: "ТК", nk: "НК" };
return map[c] || c.toUpperCase();
}
function highlight(text, query) {
if (!query) return text;
const words = query.toLowerCase().split(/\s+/).filter(w => w.length > 1);
let result = text;
words.forEach(w => {
const re = new RegExp(`(${w.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')})`, 'gi');
result = result.replace(re, '<mark>$1</mark>');
});
return result;
}
function matchesQuery(v, query) {
if (!query.trim()) return true;
const q = query.toLowerCase();
const words = q.split(/\s+/).filter(w => w.length > 0);
return words.some(w =>
v.keywords.some(k => k.includes(w)) ||
v.desc.toLowerCase().includes(w) ||
v.article.toLowerCase().includes(w)
);
}
function render(results, query) {
const grid = document.getElementById("results");
const empty = document.getElementById("empty");
const stats = document.getElementById("stats");
stats.textContent = results.length === VIOLATIONS.length
? `Всего: ${VIOLATIONS.length} нарушений`
: `Найдено: ${results.length} из ${VIOLATIONS.length}`;
if (results.length === 0) {
grid.innerHTML = "";
empty.style.display = "";
return;
}
empty.style.display = "none";
grid.innerHTML = results.map(v => `
<div class="violation-card">
<div class="info">
<h3>${highlight(v.desc, query)}</h3>
</div>
<div class="article ${v.code}">
<span class="code-label">${codeLabel(v.code)}</span> ${v.article}
</div>
<div class="penalty">
<span class="penalty-label">Наказание:</span>
<span>${v.penalty}</span>
</div>
</div>
`).join("");
}
function filterAndSearch() {
let results = VIOLATIONS;
if (currentCode !== "all") {
results = results.filter(v => v.code === currentCode);
}
if (currentQuery.trim()) {
results = results.filter(v => matchesQuery(v, currentQuery));
}
render(results, currentQuery);
}
function search() {
currentQuery = document.getElementById("search").value;
filterAndSearch();
}
function setFilter(code, btn) {
currentCode = code;
document.querySelectorAll(".filter-btn").forEach(b => b.classList.remove("active"));
btn.classList.add("active");
filterAndSearch();
}
document.getElementById("search").addEventListener("input", search);
document.getElementById("search").addEventListener("keydown", function(e) {
if (e.key === "Enter") search();
});
filterAndSearch();
</script>
</body>
</html>