diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..6aa7e29
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+corepack pnpm run precommit
\ No newline at end of file
diff --git a/astro.config.mjs b/astro.config.mjs
index a4034fb..f31b21b 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -1,9 +1,22 @@
// @ts-check
-import { defineConfig } from 'astro/config';
-import tailwindcss from '@tailwindcss/vite';
+import tailwindcss from "@tailwindcss/vite";
+import { defineConfig } from "astro/config";
+
+const alias = {
+ "@app": new URL("./src/app", import.meta.url).pathname,
+ "@pageModules": new URL("./src/pageModules", import.meta.url).pathname,
+ "@widgets": new URL("./src/widgets", import.meta.url).pathname,
+ "@features": new URL("./src/features", import.meta.url).pathname,
+ "@entities": new URL("./src/entities", import.meta.url).pathname,
+ "@shared": new URL("./src/shared", import.meta.url).pathname,
+ "@mocks": new URL("./src/__mocks__", import.meta.url).pathname,
+};
export default defineConfig({
- vite: {
- plugins: [tailwindcss()]
- }
-});
\ No newline at end of file
+ vite: {
+ plugins: [tailwindcss()],
+ resolve: {
+ alias,
+ },
+ },
+});
diff --git a/biome.json b/biome.json
index fe05d88..e676bf9 100644
--- a/biome.json
+++ b/biome.json
@@ -30,5 +30,18 @@
"organizeImports": "on"
}
}
- }
+ },
+ "overrides": [
+ {
+ "includes": ["**/*.astro"],
+ "linter": {
+ "rules": {
+ "correctness": {
+ "noUnusedImports": "off",
+ "noUnusedVariables": "off"
+ }
+ }
+ }
+ }
+ ]
}
diff --git a/package.json b/package.json
index 46b5717..0889fe3 100644
--- a/package.json
+++ b/package.json
@@ -1,26 +1,43 @@
{
- "name": "nikitapozd_website",
- "type": "module",
- "version": "0.0.1",
- "engines": {
- "node": "24.13.0",
- "pnpm": ">=9.0.0"
- },
- "enginesStrict": true,
- "scripts": {
- "dev": "astro dev",
- "build": "astro build",
- "preview": "astro preview",
- "astro": "astro",
- "preinstall": "node ./scripts/enforce-pnpm.mjs"
- },
- "dependencies": {
- "@tailwindcss/vite": "^4.2.4",
- "@webtui/css": "^0.1.7",
- "astro": "^6.1.8",
- "tailwindcss": "^4.2.4"
- },
- "devDependencies": {
- "@biomejs/biome": "2.4.13"
- }
-}
\ No newline at end of file
+ "name": "nikitapozd_website",
+ "type": "module",
+ "version": "0.0.1",
+ "engines": {
+ "node": ">=24.13.0 <25",
+ "pnpm": ">=10.28.0"
+ },
+ "enginesStrict": true,
+ "scripts": {
+ "dev": "astro dev",
+ "build": "astro build",
+ "preview": "astro preview",
+ "astro": "astro",
+ "preinstall": "node ./scripts/enforce-pnpm.mjs",
+ "lint": "astro check --minimumFailingSeverity warning && biome check .",
+ "format": "biome format . --write",
+ "prepare": "husky",
+ "precommit": "lint-staged",
+ "ci": "astro check && biome ci ."
+ },
+ "lint-staged": {
+ "*.{js,jsx,ts,tsx,json,jsonc,css,scss}": [
+ "biome check --no-errors-on-unmatched"
+ ],
+ "*.{astro}": [
+ "astro check --minimumFailingSeverity warning"
+ ]
+ },
+ "dependencies": {
+ "@astrojs/check": "^0.9.9",
+ "@tailwindcss/vite": "^4.2.4",
+ "@webtui/css": "^0.1.7",
+ "astro": "^6.1.8",
+ "tailwindcss": "^4.2.4",
+ "typescript": "^6.0.3"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "2.4.13",
+ "husky": "^9.1.7",
+ "lint-staged": "^16.4.0"
+ }
+}
diff --git a/scripts/enforce-pnpm.mjs b/scripts/enforce-pnpm.mjs
index b9397ae..b9ed041 100644
--- a/scripts/enforce-pnpm.mjs
+++ b/scripts/enforce-pnpm.mjs
@@ -1,6 +1,6 @@
-if (!process.env.npm_execpath || !process.env.npm_execpath.includes('pnpm')) {
- console.error(
- 'Ошибка: используйте только `pnpm` для установки зависимостей (запускать: `pnpm install`).'
- );
- process.exit(1);
+if (!process.env.npm_execpath?.includes("pnpm")) {
+ console.error(
+ "Ошибка: используйте только `pnpm` для установки зависимостей (запускать: `pnpm install`).",
+ );
+ process.exit(1);
}
diff --git a/src/__mocks__/demo.ts b/src/__mocks__/demo.ts
new file mode 100644
index 0000000..ca5b9ff
--- /dev/null
+++ b/src/__mocks__/demo.ts
@@ -0,0 +1,43 @@
+export const articles = [
+ {
+ title: "Нативный light/dark без лишнего JS",
+ tag: "CSS / UI",
+ meta: "06.04.2026",
+ desc: "Разбор переключения темы, системных предпочтений и аккуратной деградации интерфейса.",
+ },
+ {
+ title: "Astro + WebTUI: терминальный UI без боли",
+ tag: "ASTRO / WEBTUI",
+ meta: "02.04.2026",
+ desc: "Как подключить стили, разнести слои и не потерять читаемость в гибридном интерфейсе.",
+ },
+ {
+ title: "React-архитектура для pet-проектов",
+ tag: "REACT / TS",
+ meta: "27.03.2026",
+ desc: "Минимальный, но живучий сетап: фичи, shared-слой, UI-кит и понятные контракты.",
+ },
+];
+
+export const projects = [
+ {
+ title: "UI System",
+ type: "DESIGN SYSTEM",
+ status: "ONLINE",
+ desc: "Компоненты и паттерны для React / Solid с единым visual language.",
+ },
+ {
+ title: "Lab Notes",
+ type: "BLOG",
+ status: "SYNCED",
+ desc: "Статьи, заметки и эксперименты по фронтенду, DX и интерфейсам.",
+ },
+ {
+ title: "Experiments",
+ type: "PLAYGROUND",
+ status: "WIP",
+ desc: "Графика, WebGPU, 3D и интерактивные эксперименты.",
+ },
+];
+
+export const contacts = ["GitHub", "Telegram", "Email", "LinkedIn"];
diff --git a/src/__mocks__/index.ts b/src/__mocks__/index.ts
new file mode 100644
index 0000000..dd560c2
--- /dev/null
+++ b/src/__mocks__/index.ts
@@ -0,0 +1 @@
+export * from "./demo.ts";
diff --git a/src/app/layouts/BaseLayout/BaseLayout.astro b/src/app/layouts/BaseLayout/BaseLayout.astro
new file mode 100644
index 0000000..1b742c2
--- /dev/null
+++ b/src/app/layouts/BaseLayout/BaseLayout.astro
@@ -0,0 +1,26 @@
+---
+import "@app/styles/global.css";
+
+interface Props {
+ title?: string;
+ description?: string;
+}
+
+const a = "asdsad";
+const { title = "NikitaPozd Dev", description = "" } = Astro.props;
+---
+
+
+
+
+
+
+
+
+ {title}
+
+
+
+
+
+
diff --git a/src/app/layouts/BaseLayout/index.ts b/src/app/layouts/BaseLayout/index.ts
new file mode 100644
index 0000000..c045a66
--- /dev/null
+++ b/src/app/layouts/BaseLayout/index.ts
@@ -0,0 +1 @@
+export { default } from "./BaseLayout.astro";
diff --git a/src/styles/global.css b/src/app/styles/global.css
similarity index 57%
rename from src/styles/global.css
rename to src/app/styles/global.css
index e33475d..d08cad3 100644
--- a/src/styles/global.css
+++ b/src/app/styles/global.css
@@ -7,9 +7,9 @@
@import "@webtui/css/utils/box.css" layer(utilities);
/* components */
-@import "@webtui/css/components/typography.css" layer(components);
-
+@import "@webtui/css/components/accordion.css" layer(components);
+@import "@webtui/css/components/badge.css" layer(components);
@import "@webtui/css/components/button.css" layer(components);
-@import '@webtui/css/components/accordion.css' layer(components);
-@import '@webtui/css/components/dialog.css' layer(components);
-
+@import "@webtui/css/components/dialog.css" layer(components);
+@import "@webtui/css/components/pre.css" layer(components);
+@import "@webtui/css/components/typography.css" layer(components);
diff --git a/src/entities/.gitkeep b/src/entities/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/features/.gitkeep b/src/features/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
deleted file mode 100644
index 80907c2..0000000
--- a/src/layouts/Layout.astro
+++ /dev/null
@@ -1,16 +0,0 @@
----
-import "../styles/global.css";
----
-
-
-
-
-
-
-
- NikitaPozd Dev
-
-
-
-
-
diff --git a/src/pageModules/demo/index.ts b/src/pageModules/demo/index.ts
new file mode 100644
index 0000000..a895e8c
--- /dev/null
+++ b/src/pageModules/demo/index.ts
@@ -0,0 +1 @@
+export { default } from "./ui/DemoPage.astro";
diff --git a/src/pageModules/demo/ui/DemoPage.astro b/src/pageModules/demo/ui/DemoPage.astro
new file mode 100644
index 0000000..4a1b00d
--- /dev/null
+++ b/src/pageModules/demo/ui/DemoPage.astro
@@ -0,0 +1,680 @@
+---
+import { articles, contacts, projects } from "@mocks/demo.ts";
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+ personal node / online
+
+
Никита Поздняков
+
+ Фронтенд-разработчик. Делаю быстрые, аккуратные интерфейсы на React,
+ TypeScript, Next.js и Astro. Люблю дизайн-системы, терминальную эстетику и
+ чуть-чуть киберпанка.
+
+
+
+
+
+ status
+ v0.01
+
+ stack React / TS
+ focus DX / UI
+ mode building
+ location remote
+
+
+
+
+
Статьи 013
+
Проекты 008
+
Опыт с UI 06+
+
+
+
+ Смотреть статьи
+ Открыть проекты
+
+
+
+
+
+
+ mission feed
+ active
+
+
+
Собрать личный сайт с сильной визуальной системой
+
Показать статьи, проекты и стек без визуального шума
+
Смешать WebTUI и HUD Watch Dogs в современный лендинг
+
+
+
+
+
+ quick links
+ sync
+
+
+ {contacts.map((item) => (
+
{item}
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+ Мне нравится делать интерфейсы, в которых есть структура, ритм и понятная
+ логика. Люблю, когда дизайн не спорит с контентом, а усиливает его.
+
+
+ Этот макет опирается на спокойную структуру персонального сайта, но сверху
+ добавляет HUD-слои, статусы, терминальные компоненты и акцентные панели в
+ духе ctOS.
+
+
+
+
+ {["Next.js", "TypeScript", "Design Systems", "Astro", "Accessibility", "Motion"].map((item) => (
+ {item}
+ ))}
+
+
+
+
+
+
+
articles.log
+
Последние статьи
+
+
Все записи
+
+
+
+ {articles.map((article) => (
+
+
+ {article.tag}
+ {article.meta}
+
+ {article.title}
+ {article.desc}
+
+ ))}
+
+
+
+
+
+
+
+
projects.map
+
Избранные проекты
+
+
3 active nodes
+
+
+
+ {projects.map((project) => (
+
+
+ {project.type}
+ {project.status}
+
+ {project.title}
+ {project.desc}
+
+
+ ))}
+
+
+
+
+
+
+
+
+
diff --git a/src/pageModules/home/index.ts b/src/pageModules/home/index.ts
new file mode 100644
index 0000000..dd26f78
--- /dev/null
+++ b/src/pageModules/home/index.ts
@@ -0,0 +1 @@
+export { default } from "./ui/HomePage.astro";
diff --git a/src/pageModules/home/ui/HomePage.astro b/src/pageModules/home/ui/HomePage.astro
new file mode 100644
index 0000000..f6c0f38
--- /dev/null
+++ b/src/pageModules/home/ui/HomePage.astro
@@ -0,0 +1,13 @@
+
+
+ home page
+ Hello WebTUI
+
+ Базовая главная страница собрана как page module и подключается маршрутом из
+ `src/pages/index.astro`.
+
+
+ Открыть демо
+
+
+
\ No newline at end of file
diff --git a/src/pageModules/uiSandbox/index.ts b/src/pageModules/uiSandbox/index.ts
new file mode 100644
index 0000000..f4b9608
--- /dev/null
+++ b/src/pageModules/uiSandbox/index.ts
@@ -0,0 +1 @@
+export { default } from "./ui/UiSandboxPage.astro";
diff --git a/src/pageModules/uiSandbox/ui/UiSandboxPage.astro b/src/pageModules/uiSandbox/ui/UiSandboxPage.astro
new file mode 100644
index 0000000..9d80e9c
--- /dev/null
+++ b/src/pageModules/uiSandbox/ui/UiSandboxPage.astro
@@ -0,0 +1,39 @@
+
+ Heading 1
+
+ Summary title
+ Accordion content
+
+
+
+
+
Are you sure you want to delete this?
+
+ Cancel
+ Delete
+
+
+
+ Open Dialog
+
+
+
+
diff --git a/src/pages/demo.astro b/src/pages/demo.astro
index f2a4c72..f165e2b 100644
--- a/src/pages/demo.astro
+++ b/src/pages/demo.astro
@@ -1,749 +1,11 @@
---
-// src/pages/index.astro
-// Для полноценного проекта лучше вынести WebTUI-импорты в src/styles/global.css
-// и подключить файл в root layout, но этот single-file макет можно сразу вставить
-// в Astro для быстрого старта.
-
-const articles = [
- {
- title: "Нативный light/dark без лишнего JS",
- tag: "CSS / UI",
- meta: "06.04.2026",
- desc: "Разбор переключения темы, системных предпочтений и аккуратной деградации интерфейса.",
- },
- {
- title: "Astro + WebTUI: терминальный UI без боли",
- tag: "ASTRO / WEBTUI",
- meta: "02.04.2026",
- desc: "Как подключить стили, разнести слои и не потерять читаемость в гибридном интерфейсе.",
- },
- {
- title: "React-архитектура для pet-проектов",
- tag: "REACT / TS",
- meta: "27.03.2026",
- desc: "Минимальный, но живучий сетап: фичи, shared-слой, UI-кит и понятные контракты.",
- },
-];
-
-const projects = [
- {
- title: "UI System",
- type: "DESIGN SYSTEM",
- status: "ONLINE",
- desc: "Компоненты и паттерны для React / Solid с единым visual language.",
- },
- {
- title: "Lab Notes",
- type: "BLOG",
- status: "SYNCED",
- desc: "Статьи, заметки и эксперименты по фронтенду, DX и интерфейсам.",
- },
- {
- title: "Experiments",
- type: "PLAYGROUND",
- status: "WIP",
- desc: "Графика, WebGPU, 3D и интерактивные эксперименты.",
- },
-];
-
-const contacts = ["GitHub", "Telegram", "Email", "LinkedIn"];
+import BaseLayout from "@app/layouts/BaseLayout";
+import DemoPage from "@pageModules/demo";
---
-
-
-
-
- Никита Поздняков — Frontend Engineer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- personal node / online
-
-
Никита Поздняков
-
- Фронтенд-разработчик. Делаю быстрые, аккуратные интерфейсы на React,
- TypeScript, Next.js и Astro. Люблю дизайн-системы, терминальную эстетику и
- чуть-чуть киберпанка.
-
-
-
-
-
- status
- v0.01
-
- stack React / TS
- focus DX / UI
- mode building
- location remote
-
-
-
-
-
Статьи 013
-
Проекты 008
-
Опыт с UI 06+
-
-
-
- Смотреть статьи
- Открыть проекты
-
-
-
-
-
-
- mission feed
- active
-
-
-
Собрать личный сайт с сильной визуальной системой
-
Показать статьи, проекты и стек без визуального шума
-
Смешать WebTUI и HUD Watch Dogs в современный лендинг
-
-
-
-
-
- quick links
- sync
-
-
- {contacts.map((item) => (
-
{item}
- ))}
-
-
-
-
-
-
-
-
-
-
-
- Мне нравится делать интерфейсы, в которых есть структура, ритм и понятная
- логика. Люблю, когда дизайн не спорит с контентом, а усиливает его.
-
-
- Этот макет опирается на спокойную структуру персонального сайта, но сверху
- добавляет HUD-слои, статусы, терминальные компоненты и акцентные панели в
- духе ctOS.
-
-
-
-
- {['Next.js', 'TypeScript', 'Design Systems', 'Astro', 'Accessibility', 'Motion'].map((item) => (
- {item}
- ))}
-
-
-
-
-
-
-
articles.log
-
Последние статьи
-
-
Все записи
-
-
-
- {articles.map((article) => (
-
-
- {article.tag}
- {article.meta}
-
- {article.title}
- {article.desc}
-
- ))}
-
-
-
-
-
-
-
-
projects.map
-
Избранные проекты
-
-
3 active nodes
-
-
-
- {projects.map((project) => (
-
-
- {project.type}
- {project.status}
-
- {project.title}
- {project.desc}
-
-
- ))}
-
-
-
-
-
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 639fce5..f3118d2 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,7 +1,8 @@
---
-import Layout from "../layouts/Layout.astro";
+import BaseLayout from "@app/layouts/BaseLayout";
+import HomePage from "@pageModules/home";
---
-
- Hello WebTUI
-
+
+
+
diff --git a/src/pages/ui-sandbox.astro b/src/pages/ui-sandbox.astro
new file mode 100644
index 0000000..9aba8d1
--- /dev/null
+++ b/src/pages/ui-sandbox.astro
@@ -0,0 +1,8 @@
+---
+import BaseLayout from "@app/layouts/BaseLayout";
+import UiSandboxPage from "@pageModules/uiSandbox";
+---
+
+
+
+
diff --git a/src/pages/ui.astro b/src/pages/ui.astro
deleted file mode 100644
index a715f9b..0000000
--- a/src/pages/ui.astro
+++ /dev/null
@@ -1,48 +0,0 @@
----
-import Layout from "../layouts/Layout.astro";
----
-
-
-
- Heading 1
- Heading 2
- Heading 3
- Heading 4
- Heading 5
- Heading 6
-
- Summary title
- Accordion content
-
-
-
-
-
Are you sure you want to delete this?
-
- Cancel
- Delete
-
-
-
- Open Dialog
-
-
-
-
-
\ No newline at end of file
diff --git a/src/shared/.gitkeep b/src/shared/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/widgets/.gitkeep b/src/widgets/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tsconfig.json b/tsconfig.json
index 8bf91d3..d8c4679 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,17 @@
{
- "extends": "astro/tsconfigs/strict",
- "include": [".astro/types.d.ts", "**/*"],
- "exclude": ["dist"]
+ "extends": "astro/tsconfigs/strict",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@app/*": ["src/app/*"],
+ "@pageModules/*": ["src/pageModules/*"],
+ "@widgets/*": ["src/widgets/*"],
+ "@features/*": ["src/features/*"],
+ "@entities/*": ["src/entities/*"],
+ "@shared/*": ["src/shared/*"],
+ "@mocks/*": ["src/__mocks__/*"]
+ }
+ },
+ "include": [".astro/types.d.ts", "**/*"],
+ "exclude": ["dist"]
}