diff --git a/index.html b/index.html
new file mode 100644
index 0000000..0a5ea92
--- /dev/null
+++ b/index.html
@@ -0,0 +1,289 @@
+
+
+
+
+
+
+Тимбилдинг ДЦБ Астана — регистрация
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Тимбилдинг ДЦБ Астана
+
+
+
Регистрация
+
+
+
+
+
+
18 сентября · суббота
+
Тимбилдинг ДЦБ Астана
+
День вне привычной рабочей обстановки: командные активности, общение, отдых — и просто классное время вместе. Место: зона отдыха «Лазурный берег», Косшы.
+
+
+
+
+
+
+
+
Как всё будет проходить
+
Три остановки — офис, дорога, база. Всё остальное позади.
+
+
+
+
+ 08:30
+ Приходим на работу как обычно — БЦ «Асылтау».
+
+
+
+ 10:30
+ Выезжаем от БЦ «Асылтау», ул. Алматы, 1.
+
+
+
+ День на базе
+ Зона отдыха «Лазурный берег», г. Косшы, ул. Айтебе би, 32.
+
+
+
+ 18:00
+ Обратный выезд с базы отдыха — ориентировочно.
+
+
+
+
Берите с собой хорошее настроение — остальное организуем на месте.
+
+
+
+
+
+
+
+
Регистрация
+
Оставьте контакты — и вы в списке участников. Подтверждение появится у администратора мероприятия.
+
+
+
+
+
+
Регистрация принята
+
Вы в списке участников. До встречи 18 сентября!
+
Зарегистрировать ещё одного
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Всего участников — зарегистрировано на 18 сентября
+
Подтверждены — место на трансфере зафиксировано
+
Ждут подтверждения — требуют внимания администратора
+
+
+
+
+
+
+
+
+ Участник
+ Телефон
+ Зарегистрирован
+ Статус
+
+
+
+
+
+
+
+
Никого нет
+
Попробуйте изменить запрос или фильтр.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Для работы регистрации включите JavaScript в браузере.
+
+
+
+
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..4c1cf49
--- /dev/null
+++ b/script.js
@@ -0,0 +1,323 @@
+/* Тимбилдинг ДЦБ Астана — регистрация участников и список администратора.
+ Данные живут в localStorage (общий хранилище страницы); при первом заходе
+ список наполняется примерами участников для показа структуры. */
+(function () {
+ "use strict";
+
+ var LS_KEY = "teambuilding_dcb_participants";
+
+ var STATUS = {
+ waiting: { label: "Ждёт подтверждения", tone: "warn" },
+ confirmed: { label: "Подтверждён", tone: "ok" }
+ };
+
+ var SEED = [
+ { id: 1, name: "Данияр", lastname: "Орынбаев", phone: "+7 705 214 88 30", status: "confirmed", date: "08.09.2026" },
+ { id: 2, name: "Айгерим", lastname: "Сатыбаева", phone: "+7 702 551 40 12", status: "confirmed", date: "09.09.2026" },
+ { id: 3, name: "Ержан", lastname: "Абдрахимов", phone: "+7 771 902 33 56", status: "waiting", date: "09.09.2026" },
+ { id: 4, name: "Гульнара", lastname: "Касымжанова", phone: "+7 747 635 21 08", status: "confirmed", date: "10.09.2026" },
+ { id: 5, name: "Мадина", lastname: "Турсынбаева", phone: "+7 708 442 17 65", status: "confirmed", date: "11.09.2026" },
+ { id: 6, name: "Асхат", lastname: "Жаманкулов", phone: "+7 700 118 92 44", status: "waiting", date: "12.09.2026" },
+ { id: 7, name: "Сейіл", lastname: "Кенжарик", phone: "+7 748 276 50 91", status: "confirmed", date: "13.09.2026" },
+ { id: 8, name: "Жанна", lastname: "Мырзахметова", phone: "+7 706 390 77 14", status: "confirmed", date: "15.09.2026" },
+ { id: 9, name: "Бахыт", lastname: "Айтимов", phone: "+7 775 813 26 40", status: "confirmed", date: "15.09.2026" },
+ { id: 10, name: "Алия", lastname: "Исмухамбетова", phone: "+7 707 564 38 29", status: "waiting", date: "16.09.2026" },
+ { id: 11, name: "Нурлан", lastname: "Сейткалиев", phone: "+7 702 837 15 73", status: "confirmed", date: "16.09.2026" },
+ { id: 12, name: "Карлыгаш", lastname: "Ералиева", phone: "+7 749 620 84 57", status: "waiting", date: "17.09.2026" }
+ ];
+
+ /* ── Хранилище ── */
+ function load() {
+ try {
+ var raw = localStorage.getItem(LS_KEY);
+ if (raw) {
+ var arr = JSON.parse(raw);
+ if (Array.isArray(arr)) return arr;
+ }
+ } catch (e) { /* повреждённые данные — пересеять */ }
+ localStorage.setItem(LS_KEY, JSON.stringify(SEED));
+ return SEED.slice();
+ }
+ function save(list) {
+ try { localStorage.setItem(LS_KEY, JSON.stringify(list)); } catch (e) {}
+ }
+
+ var participants = load();
+ var nextId = 1;
+ for (var i = 0; i < participants.length; i++) {
+ if (participants[i].id >= nextId) nextId = participants[i].id + 1;
+ }
+
+ /* ── Хелперы ── */
+ function $(sel, root) { return (root || document).querySelector(sel); }
+ function esc(s) {
+ return String(s == null ? "" : s).replace(/[&<>"']/g, function (c) {
+ return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c];
+ });
+ }
+ function todayStr() {
+ var d = new Date();
+ var m = ("0" + (d.getMonth() + 1)).slice(-2);
+ var day = ("0" + d.getDate()).slice(-2);
+ return day + "." + m + "." + d.getFullYear();
+ }
+
+ var toastsRoot = $("#toasts");
+ function toast(text, tone) {
+ var el = document.createElement("div");
+ el.className = "kt-ai-toast";
+ if (tone) el.setAttribute("data-tone", tone);
+ el.textContent = text;
+ toastsRoot.appendChild(el);
+ setTimeout(function () {
+ el.style.opacity = "0";
+ el.style.transition = "opacity 200ms";
+ setTimeout(function () { el.remove(); }, 220);
+ }, 3200);
+ }
+
+ /* ── Переключение видов ── */
+ function showView(name) {
+ var p = $("#view-participant");
+ var a = $("#view-admin");
+ if (name === "admin") {
+ p.hidden = true;
+ a.hidden = false;
+ } else {
+ a.hidden = true;
+ p.hidden = false;
+ }
+ if (name === "admin") renderAdmin();
+ try { location.hash = name; } catch (e) {}
+ }
+
+ /* ── Форма регистрации ── */
+ var form = $("#regform");
+ var done = $("#regdone");
+ var fName = $("#f-name");
+ var fLast = $("#f-lastname");
+ var fPhone = $("#f-phone");
+
+ form.addEventListener("submit", function (ev) {
+ ev.preventDefault();
+ var name = fName.value.trim();
+ var lastname = fLast.value.trim();
+ var phone = fPhone.value.trim();
+
+ if (!name) { flashField(fName, "Введите имя"); return; }
+ if (!lastname) { flashField(fLast, "Введите фамилию"); return; }
+ if (!/\+?[0-9](?:[0-9 ()\-]{6,14})/.test(phone)) {
+ flashField(fPhone, "Укажите телефон в формате +7 XXX XXX XX XX");
+ return;
+ }
+ var dup = null;
+ for (var i = 0; i < participants.length; i++) {
+ var p = participants[i];
+ var key = (p.name + " " + p.lastname).trim().replace(/\s+/g, " ").toLowerCase();
+ if (key === (name + " " + lastname).replace(/\s+/g, " ").toLowerCase() &&
+ p.phone.replace(/\D/g, "") === phone.replace(/\D/g, "")) { dup = p; break; }
+ }
+ if (dup) {
+ toast("Этот участник уже зарегистрирован", "warn");
+ return;
+ }
+
+ var rec = {
+ id: nextId++,
+ name: name,
+ lastname: lastname,
+ phone: phone,
+ status: "waiting",
+ date: todayStr()
+ };
+ participants.unshift(rec);
+ save(participants);
+
+ form.hidden = true;
+ done.hidden = false;
+ $("#regdone-text").textContent =
+ name + ", вы в списке участников. Администратор подтвердит участие до 18 сентября.";
+ toast("Регистрация принята", "ok");
+ });
+
+ function flashField(input, msg) {
+ input.focus();
+ toast(msg, "warn");
+ }
+
+ $("#regdone-again").addEventListener("click", function () {
+ form.reset();
+ done.hidden = true;
+ form.hidden = false;
+ fName.focus();
+ });
+
+ /* ── Админка ── */
+ var statusFilter = "all";
+ var searchQuery = "";
+ var selectedId = null;
+
+ function filtered() {
+ return participants.filter(function (p) {
+ if (statusFilter !== "all" && p.status !== statusFilter) return false;
+ if (searchQuery) {
+ var hay = (p.name + " " + p.lastname + " " + p.phone).toLowerCase();
+ if (hay.indexOf(searchQuery) === -1) return false;
+ }
+ return true;
+ });
+ }
+
+ function statusPill(status) {
+ var s = STATUS[status] || STATUS.waiting;
+ return '' + esc(s.label) + " ";
+ }
+
+ function renderAdmin() {
+ /* навигация-счётчик */
+ $("#nav-count").textContent = participants.length;
+
+ /* KPI */
+ var total = participants.length;
+ var confirmed = 0, waiting = 0;
+ for (var i = 0; i < participants.length; i++) {
+ if (participants[i].status === "confirmed") confirmed++; else waiting++;
+ }
+ $("#kpi-total").textContent = total;
+ $("#kpi-confirmed").textContent = confirmed;
+ $("#kpi-waiting").textContent = waiting;
+
+ /* фильтр-чипы */
+ var chips = document.querySelectorAll(".kt-ai-filter-chip");
+ for (var j = 0; j < chips.length; j++) {
+ chips[j].setAttribute("data-active", chips[j].getAttribute("data-status") === statusFilter ? "true" : "false");
+ }
+
+ /* таблица */
+ var list = filtered();
+ var tbody = $("#adm-tbody");
+ var html = "";
+ for (var k = 0; k < list.length; k++) {
+ var p = list[k];
+ html += "" +
+ '' + esc(p.lastname) + " " + esc(p.name) + " " +
+ 'ДЦБ Астана ' +
+ '' + esc(p.phone) + " " +
+ '' + esc(p.date) + " " +
+ '' + statusPill(p.status) + " " +
+ ' ' +
+ " ";
+ }
+ tbody.innerHTML = html;
+
+ /* пустое состояние */
+ var empty = $("#adm-empty");
+ if (list.length === 0) {
+ empty.hidden = false;
+ var hasFilter = statusFilter !== "all" || searchQuery !== "";
+ $("#adm-empty-title").textContent = hasFilter ? "Никого не нашлось" : "Пока никто не зарегистрировался";
+ $("#adm-empty-text").textContent = hasFilter
+ ? "Попробуйте изменить запрос или фильтр."
+ : "Регистрации участников появятся здесь, как только коллеги отправят форму.";
+ } else {
+ empty.hidden = true;
+ }
+ }
+
+ /* клики по строке и по «открыть» */
+ $("#adm-tbody").addEventListener("click", function (ev) {
+ var tr = ev.target.closest("tr[data-id]");
+ if (!tr) return;
+ openDrawer(parseInt(tr.getAttribute("data-id"), 10));
+ });
+
+ /* поиск + фильтры */
+ $("#adm-search").addEventListener("input", function () {
+ searchQuery = this.value.trim().toLowerCase();
+ renderAdmin();
+ });
+ document.querySelectorAll(".kt-ai-filter-chip").forEach(function (chip) {
+ chip.addEventListener("click", function () {
+ statusFilter = this.getAttribute("data-status");
+ renderAdmin();
+ });
+ });
+
+ /* ── Drawer ── */
+ var drawer = $("#drawer");
+
+ function openDrawer(id) {
+ var p = null;
+ for (var i = 0; i < participants.length; i++) if (participants[i].id === id) { p = participants[i]; break; }
+ if (!p) return;
+ selectedId = id;
+
+ $("#d-name").textContent = p.lastname + " " + p.name;
+ var phoneEl = $("#d-phone");
+ phoneEl.textContent = p.phone;
+ phoneEl.toggleAttribute("data-empty", !p.phone);
+ $("#d-date").textContent = p.date;
+ $("#d-status").innerHTML = statusPill(p.status);
+ $("#d-confirm").hidden = p.status === "confirmed";
+ $("#d-confirm").setAttribute("data-tone", p.status === "confirmed" ? "ok" : "");
+
+ drawer.hidden = false;
+ document.documentElement.classList.add("kt-ai-scroll-locked");
+ renderAdmin();
+ }
+ function closeDrawer() {
+ drawer.hidden = true;
+ selectedId = null;
+ document.documentElement.classList.remove("kt-ai-scroll-locked");
+ renderAdmin();
+ }
+ $(".drawer-close").addEventListener("click", closeDrawer);
+ $("#d-close").addEventListener("click", closeDrawer);
+ document.addEventListener("keydown", function (e) {
+ if (e.key === "Escape" && !drawer.hidden) closeDrawer();
+ });
+
+ $("#d-confirm").addEventListener("click", function () {
+ var p = null;
+ for (var i = 0; i < participants.length; i++) if (participants[i].id === selectedId) { p = participants[i]; break; }
+ if (!p) return;
+ p.status = "confirmed";
+ save(participants);
+ toast(p.lastname + " " + p.name + ": участие подтверждено", "ok");
+ openDrawer(p.id);
+ });
+
+ $("#d-unlink").addEventListener("click", function () {
+ var p = null;
+ for (var i = 0; i < participants.length; i++) if (participants[i].id === selectedId) { p = participants[i]; break; }
+ if (!p) return;
+ var idx = participants.indexOf(p);
+ participants.splice(idx, 1);
+ save(participants);
+ closeDrawer();
+ toast(p.lastname + " " + p.name + " убран из списка");
+ });
+
+ /* ── Навигация ── */
+ document.querySelectorAll("[data-nav]").forEach(function (el) {
+ el.addEventListener("click", function (ev) {
+ ev.preventDefault();
+ showView("participant");
+ var target = this.getAttribute("data-nav");
+ if (target && target !== "reg") {
+ setTimeout(function () {
+ var sec = document.getElementById(target);
+ if (sec) sec.scrollIntoView({ behavior: "smooth", block: "start" });
+ }, 60);
+ } else {
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ }
+ });
+ });
+ var adminLink = document.querySelector(".tb-admin-link-strong");
+ if (adminLink) adminLink.addEventListener("click", function () { showView("admin"); });
+
+ /* стартовый вид по location.hash */
+ if (location.hash === "#admin" || location.hash === "#view-admin") showView("admin");
+ else showView("participant");
+})();
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..5c8efc1
--- /dev/null
+++ b/style.css
@@ -0,0 +1,114 @@
+/* Страница «Тимбилдинг» — только раскладка и мелочи; цвета и компоненты рисует ДС. */
+
+/* ── Шапка участника: логотип + название рядом ── */
+.tb-brand {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--kt-ai-space-4);
+ min-width: 0;
+}
+.tb-logo { display: block; flex: 0 0 auto; }
+.tb-brand-name {
+ font-size: var(--kt-ai-text-md);
+ font-weight: var(--kt-ai-weight-medium);
+ color: var(--kt-ai-fg);
+ white-space: nowrap;
+}
+.tb-pagehead-in { gap: var(--kt-ai-space-5); }
+
+/* ── Chip в hero: отбить от заголовка ── */
+.kt-ai-hero .kt-ai-chip { margin-top: calc(-1 * var(--kt-ai-space-9)); }
+
+/* ── Иконка в плитке: спокойный контейнер ── */
+.kt-ai-tile-icon {
+ display: inline-grid;
+ place-items: center;
+ width: 40px;
+ height: 40px;
+ margin-bottom: var(--kt-ai-space-4);
+ border-radius: var(--vibe-card-radius, var(--kt-ai-radius-xl));
+ background: var(--vibe-tint, var(--kt-ai-primary-subtle));
+ color: var(--kt-ai-fg);
+}
+.kt-icon { width: 18px; height: 18px; }
+
+/* ── Примечание под расписанием ── */
+.tb-note { padding: var(--kt-ai-space-5) var(--kt-ai-space-6); }
+
+/* ── Форма регистрации ── */
+#regform .kt-ai-btn { width: 100%; margin-top: var(--kt-ai-space-2); }
+#regdone {
+ border: 1px dashed var(--kt-ai-border-strong);
+ margin-top: 0;
+}
+.kt-ai-empty-ic {
+ display: inline-grid;
+ place-items: center;
+ width: 44px;
+ height: 44px;
+ border-radius: var(--kt-ai-radius-full);
+ background: var(--kt-ai-status-ok-bg, var(--kt-ai-primary-subtle));
+ color: var(--kt-ai-status-ok-fg, var(--kt-ai-fg));
+}
+.kt-ai-empty-ic .kt-icon { width: 20px; height: 20px; }
+
+/* ── Подвал ── */
+.tb-admin-link {
+ background: none;
+ border: none;
+ cursor: pointer;
+ font-size: var(--kt-ai-text-xs);
+ color: var(--kt-ai-fg-muted);
+ padding: var(--kt-ai-space-2) var(--kt-ai-space-3);
+ border-radius: var(--kt-ai-radius-md);
+}
+.tb-admin-link:hover { background: var(--kt-ai-bg-hover); color: var(--kt-ai-fg); }
+
+/* ── Сайдбар админки ── */
+.tb-brand-v { padding: 0 var(--kt-ai-space-5); }
+.kt-ai-spacer-tb { flex: 1; min-height: var(--kt-ai-space-8); }
+.tb-admin-card { margin: 0 var(--kt-ai-space-5); background: var(--kt-ai-bg) !important; border: 1px solid var(--kt-ai-border); padding: var(--kt-ai-space-4) var(--kt-ai-space-5); }
+.tb-admin-card p { margin: var(--kt-ai-space-2) 0 0; font-size: var(--kt-ai-text-2xs); line-height: var(--kt-ai-leading-normal); }
+
+/* ── Topbar: хлебные крошки ── */
+.kt-ai-breadcrumb {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--kt-ai-space-3);
+ font-size: var(--kt-ai-text-sm);
+ min-width: 0;
+}
+.kt-ai-breadcrumb .kt-icon { width: 14px; height: 14px; opacity: .6; }
+.kt-ai-breadcrumb strong { font-weight: var(--kt-ai-weight-semibold); }
+
+/* KPI-полоса админки: плотнее дефолта */
+#adm-kpis { margin-top: var(--kt-ai-space-6); }
+
+/* ── Tabula: строки кликабельны ── */
+#adm-tbody tr { cursor: pointer; }
+#adm-tbody .cell-name { font-weight: var(--kt-ai-weight-medium); }
+#adm-tbody .cell-sub { display: block; font-size: var(--kt-ai-text-2xs); color: var(--kt-ai-fg-faint); margin-top: 1px; }
+#adm-tbody td.num { white-space: nowrap; }
+
+/* ── Drawer ── */
+.drawer-head { display: flex; align-items: center; gap: var(--kt-ai-space-4); margin-bottom: var(--kt-ai-space-6); }
+.drawer-head > .kt-ai-t-muted { font-size: var(--kt-ai-text-2xs); text-transform: uppercase; letter-spacing: .8px; white-space: nowrap; }
+.drawer-head strong { font-size: var(--kt-ai-text-xl); font-weight: var(--kt-ai-weight-semibold); flex: 1; min-width: 0; }
+.drawer-close {
+ display: inline-grid; place-items: center;
+ width: 32px; height: 32px; flex: 0 0 auto;
+ border-radius: var(--kt-ai-radius-lg);
+ color: var(--kt-ai-fg-muted); cursor: pointer;
+ border: 1px solid var(--kt-ai-border);
+}
+.drawer-close:hover { background: var(--kt-ai-bg-hover); color: var(--kt-ai-fg); }
+.drawer-body .kt-ai-prop { border-bottom: 1px solid var(--kt-ai-divider); padding-bottom: var(--kt-ai-space-4); }
+.drawer-body .kt-ai-prop:last-child { border-bottom: none; padding-bottom: 0; }
+#d-phone { font-variant-numeric: tabular-nums; }
+
+/* ── Мобильные ── */
+@media (max-width: 639.98px) {
+ .tb-brand-name { font-size: var(--kt-ai-text-sm); }
+ .kt-ai-kpi-strip { gap: var(--kt-ai-space-6); }
+ .kt-ai-kpi .hint { max-width: 100%; }
+}