Leskov Oleg пре 5 дана
комит
2cd0525cde

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+html.json
+pug.json
+styl.json

+ 486 - 0
AI_CONTEXT_PROMPT.txt

@@ -0,0 +1,486 @@
+# PROJECT CONTEXT FOR AI AGENT
+
+## PROJECT OVERVIEW
+Vue.js application with CoffeeScript, Pug, Stylus stack
+- 24 files total
+- 2 priority documentation files
+- 0 current work files
+- 0 priority configuration files
+- Main components: 
+- Routes: 
+
+## PRIORITY DOCUMENTATION (Complete):
+
+### 📋 README.md
+```markdown
+# Текущее задание (Выполнить)
+
+## Общее задание:
+Разработать веб-приложение [название], используя платформу **s5l.ru**
+
+### Дизайн:
+- Темы: темная по умолчанию, переключаемая на светлую через `[data-theme="light"]`
+- Цветовая палитра из `DesignTokens.styl`
+- Atomic Design + User-Centered подход
+- Полная поддержка WCAG 2.2 (контраст ≥ 4.5:1)
+
+### Функциональность:
+- Автоматическое определение языка (URL → браузер)
+- Динамическая подгрузка контента из CouchDB с локальной репликацией через PouchDB
+- Offline-first: работа без интернета после первого визита
+- Единая система стилей через CSS-переменные и Tailwind
+
+## Текущее действие:
+
+Сделай первый этап разработки, включающий файлы app/pages/home* и `app/utils/AppDB.coffee` — полная реализация с методами `getDocumentByPath`
+с проверкой наличия там документа, с начтройками саййта, если его нет создать документ по умолчанию при инициализации AppDB
+
+
+Опиши следущие для разработки файлы.
+
+---
+
+# Промт для разработки на платформе s5l.ru
+
+Ты — Senior Fullstack-архитектор и UI/UX-прагматик. Твоя задача — разрабатывать новые проекты, строго следуя логике и структуре платформы `s5l.ru`.
+
+## Стек (НЕИЗМЕНЕН)
+- **Frontend**: Vue 3 (Composition API через `render` функции), CoffeeScript, Pug, Stylus, Tailwind CSS, svg, webp, webm, peerjs, websocket, webtorrent
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы, админка)  
+- **Сборка**: все шаблоны → `pug.json`, стили → `styl.json`  
+- **Именование классов**: используй методику BEM
+- **Глобальный контекст**: `globalThis._` — ссылка на корневой Vue-экземпляр из `app/app.coffee`
+
+# Проект: s5l.ru
+
+## Общее описание
+`s5l.ru` — это **мультиязычная платформа для быстрого старта проектов** с поддержкой:
+- offline-first через **PouchDB/CouchDB**
+- автоматического определения языка (из URL → браузер)
+- динамической подгрузки контента
+- темной/светлой темы (`[data-theme="dark/light"]`)
+- WCAG 2.2 (контраст ≥ 4.5:1)
+
+## Стек
+- **Frontend**: Vue 3 (render-функции), CoffeeScript, Pug, Stylus, Tailwind CSS
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы)
+- **Сборка**: `pug.json`, `styl.json`
+
+## Запуск нового проекта
+1. Создать дизайн-документы в CouchDB
+2. Положить стартовые документы с `type: 'page'`, `path: '/'`, и `translations`
+3. Использовать `AppDB.getDocumentByPath` в `beforeMount`
+4. Стили — только через CSS-переменные из `DesignTokens.styl`
+
+## Доступность
+- Поддержка тем: `:root` → `[data-theme="light"]`
+- Контраст ≥ 4.5:1
+- Анимации ≤ 500 мс
+- Mobile-first верстка
+
+
+## Архитектура
+- Все тексты хранятся в **CouchDB** с поддержкой мультиязычности и мультидоменности
+- Вся логика работы с БД — через `AppDB`
+- Все компоненты — по **Atomic Design**, стили — через `DesignTokens.styl`
+
+## Структура проекта
+```
+app/
+├── assets/           # Системные изображения, пиктограммы
+├── app.coffee        # инициализация Vue, AppDB, глобальный _ 
+├── app.pug           # Основной шаблон с Хедером, <router-view>, Футером
+├── app.styl          # Глобальные стили
+├── DesignTokens.styl # дизайн-система
+├── utils/
+|    └── AppDB.coffee # доступ к данным
+├── pages/            # Страницы проекта
+|    ├── Home.coffee
+|    ├── Home.pug
+|    └── Home.styl
+└── shared/
+     ├── AppLink.*     # компонент ссылок
+     └── ...
+```
+
+## Правила
+
+### 1. Vue-компоненты
+- **Имя файла**: PascalCase (`NewsList.coffee`, `NewsList.pug`, `NewsList.styl`)  
+- **Экспорт**: `module.exports = { name: '...', render: ..., data: -> {}, ... }`  
+- **Стили**: подключать через  
+  ```coffee
+  document.head.insertAdjacentHTML 'beforeend', '<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+  ```
+- **Шаблон**: рендерить через  
+  ```coffee
+  render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+  ```
+- **Жизненный цикл**:  
+  ❌ НЕПРАВИЛЬНО:  
+  ```coffeescript
+  async beforeMount: ->
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```coffeescript
+  beforeMount: ->
+  ```  
+  *(асинхронность обрабатывается внутри метода через `await`, но сигнатура — без `async`)*
+
+### 2. Роутинг
+- Все маршруты — в `temp.coffee` → `VueRouter.createRouter({ routes: [...] })`  
+- Компонент страницы должен быть `require`'нут без `.default` только если не экспортирует как `default`
+
+### 3. Ссылки
+- **ЗАПРЕЩЕНО**: `a(href="...")`, `router-link(to="...")`  
+- **ТОЛЬКО**: `app-link(to="...")` с подключением компонента `'app-link': require 'app/shared/AppLink'`
+
+### 4. Стили
+- **Цвета, отступы, шрифты** — ТОЛЬКО из `DesignTokens.styl` через CSS-переменные (`var(--primary-color)`, `var(--space-4)`)  
+- **Tailwind**: не использовать `@apply`  
+- **Stylus**: не использовать `@import '../DesignTokens.styl'` — он уже подключен глобально
+
+### 5. Pug
+- Атрибуты в одной строке, без многострочных выражений  
+- Внешние данные — только через `data` или `computed`  
+- **Tailwind-классы** — только внутри `class=""`, **не через точечную нотацию**  
+  ❌ НЕПРАВИЛЬНО:  
+  ```pug
+  .max-w-4xl.mx-auto.px-4
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```pug
+  div(class="max-w-4xl mx-auto px-4")
+  ```  
+- Пример правильно:
+  ```pug
+  div(v-for="item in items" :key="item.id")
+  div(:class="isActive ? 'active' : 'inactive'" class="w-full")
+  ```
+
+### 6. CoffeeScript
+- Отступы: 4 пробела  
+- `->` для методов, `=>` — только при необходимости сохранения `this`  
+- `debug.log "сообщение"` вместо `console.log`  
+- Строки: `"строка="+переменная`, без интерполяции
+
+### 7. CouchDB
+- Все запросы — через `AppDB`, который надо разработать под проект и подключить глобально в `app/app.coffee`
+- Дизайн-документы: создавать функции `.toString()`
+
+### 8. Доступность и дизайн
+- WCAG 2.2 (контраст ≥ 4.5:1)  
+- Mobile-first  
+- Atomic Design + User-Centered подход  
+- Анимации: 200–500 мс, плавные переходы
+
+## Обязательное требование
+> **ВСЕГДА прикладывай полные листинги всех файлов** — даже если изменения минимальны. Частичные или сокращённые фрагменты недопустимы. Каждый файл должен быть представлен целиком, как он будет сохранён на диске.
+
+## Шаблон компонента (полный пример)
+**Файл**: `app/shared/NewsList.coffee`
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend','<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+module.exports =
+    name: 'NewsList'
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+    data: ->
+        return {
+            _: _
+            posts: []
+        }
+    beforeMount: ->
+        @posts = await AppDB.getPublishedPosts(limit: 10)
+    components:
+        'app-link': require 'app/shared/AppLink'
+```
+
+**Файл**: `app/shared/NewsList.pug`
+```pug
+div(class="space-y-4")
+    app-link(v-for="post in posts" :key="post.id" :to="'/pages/'+post.id")
+        h3(class="text-xl") {{ post.doc.h }}
+```
+
+**Файл**: `app/shared/NewsList.styl`
+```stylus
+// Только стили компонента. DesignTokens — через var()
+.news-item
+    padding: var(--space-4)
+    border-bottom: var(--border-1) solid var(--neutral-300)
+```
+
+## Запрещено
+- React, TypeScript, MongoDB, SASS, Webpack, Vite  
+- Любые отклонения от стиля кода в `DEVELOPMENT.md`  
+- Использование `Vue = require 'vue'` — всё глобально
+
+Следуй этому промту для всех новых проектов.
+
+---
+
+```
+
+### 📋 app/DesignTokens.styl
+```stylus
+:root 
+    // Цветовая система для темной темы по умолчанию
+    --primary-color: #f87171
+    --primary-dark: #ef4444
+    --primary-light: #fca5a5
+
+    --secondary-color: #1e293b
+    --secondary-dark: #0f172a
+    --secondary-light: #334155
+
+    --accent-color: #22d3ee
+    --accent-dark: #06b6d4
+    --accent-light: #67e8f9
+
+    // Нейтральные цвета для темной темы
+    --neutral-50: #0f172a
+    --neutral-100: #1e293b
+    --neutral-200: #334155
+    --neutral-300: #475569
+    --neutral-400: #64748b
+    --neutral-500: #94a3b8
+    --neutral-600: #cbd5e1
+    --neutral-700: #e2e8f0
+    --neutral-800: #f1f5f9
+    --neutral-900: #f8fafc
+
+    // Цвета текста для темной темы
+    --text-primary: #f8fafc
+    --text-secondary: #e2e8f0
+    --text-muted: #94a3b8
+
+    // Цвета фона для темной темы
+    --bg-primary: #0f172a
+    --bg-secondary: #1e293b
+    --bg-card: #1e293b
+    --bg-overlay: rgba(15, 23, 42, 0.8)
+
+    // Градиенты для темной темы
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--secondary-dark) 0%, var(--secondary-color) 100%)
+
+    // Типографическая система
+    --font-family-sans: 'Inter', 'Segoe UI', system-ui, sans-serif
+    --font-family-serif: 'Georgia', 'Times New Roman', serif
+
+    --text-xs: 0.75rem
+    --text-sm: 0.875rem
+    --text-base: 1rem
+    --text-lg: 1.125rem
+    --text-xl: 1.25rem
+    --text-2xl: 1.5rem
+    --text-3xl: 1.875rem
+    --text-4xl: 2.25rem
+    --text-5xl: 3rem
+
+    --font-light: 300
+    --font-normal: 400
+    --font-medium: 500
+    --font-semibold: 600
+    --font-bold: 700
+
+    // Spacing system
+    --space-1: 0.25rem
+    --space-2: 0.5rem
+    --space-3: 0.75rem
+    --space-4: 1rem
+    --space-5: 1.25rem
+    --space-6: 1.5rem
+    --space-8: 2rem
+    --space-10: 2.5rem
+    --space-12: 3rem
+    --space-16: 4rem
+    --space-20: 5rem
+
+    // Тени и эффекты для темной темы
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6), 0 2px 4px -1px rgba(0, 0, 0, 0.4)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7), 0 4px 6px -2px rgba(0, 0, 0, 0.5)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8), 0 10px 10px -5px rgba(0, 0, 0, 0.6)
+
+    // Анимации
+    --transition-fast: 0.15s ease-in-out
+    --transition-normal: 0.3s ease-in-out
+    --transition-slow: 0.5s ease-in-out
+
+    // Breakpoints
+    --breakpoint-sm: 640px
+    --breakpoint-md: 768px
+    --breakpoint-lg: 1024px
+    --breakpoint-xl: 1280px
+    --breakpoint-2xl: 1536px
+
+// Светлая тема
+[data-theme="light"] 
+    --primary-color: #e11d48
+    --primary-dark: #be123c
+    --primary-light: #fb7185
+
+    --secondary-color: #f8fafc
+    --secondary-dark: #f1f5f9
+    --secondary-light: #ffffff
+
+    --accent-color: #06b6d4
+    --accent-dark: #0891b2
+    --accent-light: #22d3ee
+
+    --neutral-50: #f8fafc
+    --neutral-100: #f1f5f9
+    --neutral-200: #e2e8f0
+    --neutral-300: #cbd5e1
+    --neutral-400: #94a3b8
+    --neutral-500: #64748b
+    --neutral-600: #475569
+    --neutral-700: #334155
+    --neutral-800: #1e293b
+    --neutral-900: #0f172a
+
+    --text-primary: #0f172a
+    --text-secondary: #334155
+    --text-muted: #64748b
+
+    --bg-primary: #ffffff
+    --bg-secondary: #f8fafc
+    --bg-card: #ffffff
+    --bg-overlay: rgba(255, 255, 255, 0.8)
+
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--neutral-100) 0%, var(--neutral-50) 100%)
+
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)
+
+// Утилитарные классы для кастомных свойств
+.bg-primary 
+    background-color: var(--primary-color)
+
+.text-primary 
+    color: var(--primary-color)
+
+.border-primary 
+    border-color: var(--primary-color)
+
+.bg-accent 
+    background-color: var(--accent-color)
+
+.text-accent 
+    color: var(--accent-color)
+
+.bg-neutral 
+    background-color: var(--neutral-500)
+
+.text-neutral 
+    color: var(--neutral-500)
+
+.bg-dark 
+    background-color: var(--bg-primary)
+
+.text-dark 
+    color: var(--text-primary)
+
+.bg-card 
+    background-color: var(--bg-card)
+
+.text-card 
+    color: var(--text-primary)
+
+// Анимации
+.transition-fast 
+    transition: var(--transition-fast)
+
+.transition-normal 
+    transition: var(--transition-normal)
+
+.transition-slow 
+    transition: var(--transition-slow)
+
+// Тени
+.shadow-custom-sm 
+    box-shadow: var(--shadow-sm)
+
+.shadow-custom-md 
+    box-shadow: var(--shadow-md)
+
+.shadow-custom-lg 
+    box-shadow: var(--shadow-lg)
+
+.shadow-custom-xl 
+    box-shadow: var(--shadow-xl)
+// Добавляем дополнительные утилитарные классы для лучшей поддержки компонентов
+.card-primary 
+    background-color: var(--bg-card)
+    border: 1px solid var(--neutral-300)
+    border-radius: 8px
+    box-shadow: var(--shadow-sm)
+    transition: all var(--transition-normal)
+
+.card-primary:hover 
+    border-color: var(--primary-color)
+    box-shadow: var(--shadow-md)
+
+.text-icon 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .text-icon 
+    filter: brightness(0) invert(1)
+
+.icon-primary 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .icon-primary 
+    filter: brightness(0) invert(1)
+
+// Утилиты для контрастного текста
+.text-contrast-high 
+    color: var(--text-primary)
+
+.text-contrast-medium 
+    color: var(--text-secondary)
+
+.text-contrast-low 
+    color: var(--text-muted)
+
+// Утилиты для фонов
+.bg-surface 
+    background-color: var(--bg-card)
+
+.bg-surface-alt 
+    background-color: var(--bg-secondary)
+
+```
+
+## CURRENT WORK FILES
+No current work files specified in WORKFILES
+
+## OTHER FILES (brief overview):
+// .gitignore (Unknown) - 29 chars
+// app/app.coffee (CoffeeScript) - 3584 chars
+// app/app.pug (Pug Template) - 699 chars
+// app/app.styl (Stylus) - 1013 chars
+// app/layout.pug (Pug Template) - 324 chars
+// app/pages/Home.coffee (CoffeeScript) - 697 chars
+// app/pages/Home.pug (Pug Template) - 845 chars
+// app/pages/Home.styl (Stylus) - 281 chars
+// app/shared/AppLink.coffee (CoffeeScript) - 633 chars
+// app/shared/AppLink.pug (Pug Template) - 214 chars
+// app/shared/AppLink.styl (Stylus) - 1264 chars
+// app/shared/HeroSection.coffee (CoffeeScript) - 311 chars
+// app/shared/HeroSection.pug (Pug Template) - 574 chars
+// app/shared/HeroSection.styl (Stylus) - 125 chars
+// app/shared/ImageGallery.coffee (CoffeeScript) - 367 chars
+// app/shared/ImageGallery.pug (Pug Template) - 414 chars
+// app/shared/ImageGallery.styl (Stylus) - 324 chars
+// app/utils/AppDB.coffee (CoffeeScript) - 4684 chars
+// doc.coffee (CoffeeScript) - 1285 chars
+// lzma.coffee (CoffeeScript) - 1010 chars
+// pug/base.pug (Pug Template) - 504 chars
+// pug/bem.pug (Pug Template) - 1035 chars

+ 70 - 0
AI_QUICK_CONTEXT.txt

@@ -0,0 +1,70 @@
+# PROJECT QUICK CONTEXT
+# Generated: 2025-11-05T09:26:28.251Z
+
+## PROJECT STRUCTURE
+- Total files: 24
+- File types: Markdown, Stylus, Unknown, CoffeeScript, Pug Template
+- Main components: 
+- Routes: 
+
+## KEY FILES AND THEIR PURPOSES:
+### app/DesignTokens.styl
+Stylus stylesheet. Contains component-specific or global styles.
+
+### app/app.pug
+Pug template. Defines HTML structure and Vue.js template syntax.
+
+### app/app.styl
+Stylus stylesheet. Contains component-specific or global styles.
+
+### app/layout.pug
+Pug template. Defines HTML structure and Vue.js template syntax.
+
+### app/pages/Home.pug
+Pug template. Defines HTML structure and Vue.js template syntax.
+
+### app/pages/Home.styl
+Stylus stylesheet. Contains component-specific or global styles.
+
+### app/shared/AppLink.coffee
+Shared component: AppLink. Reusable UI component used across multiple pages.
+
+### app/shared/AppLink.pug
+Shared component: AppLink. Reusable UI component used across multiple pages.
+
+### app/shared/AppLink.styl
+Shared component: AppLink. Reusable UI component used across multiple pages.
+
+### app/shared/HeroSection.coffee
+Shared component: HeroSection. Reusable UI component used across multiple pages.
+
+### app/shared/HeroSection.pug
+Shared component: HeroSection. Reusable UI component used across multiple pages.
+
+### app/shared/HeroSection.styl
+Shared component: HeroSection. Reusable UI component used across multiple pages.
+
+### app/shared/ImageGallery.coffee
+Shared component: ImageGallery. Reusable UI component used across multiple pages.
+
+### app/shared/ImageGallery.pug
+Shared component: ImageGallery. Reusable UI component used across multiple pages.
+
+### app/shared/ImageGallery.styl
+Shared component: ImageGallery. Reusable UI component used across multiple pages.
+
+### app/utils/AppDB.coffee
+Database service layer for PouchDB/CouchDB operations. Handles authentication, data synchronization, and CRUD operations.
+
+### pug/base.pug
+Pug template. Defines HTML structure and Vue.js template syntax.
+
+### pug/bem.pug
+Pug template. Defines HTML structure and Vue.js template syntax.
+
+## DEPENDENCIES:
+No dependencies found
+
+## PROJECT ARCHITECTURE:
+PouchDB/CouchDB for data persistence
+- 3 shared components: AppLink, HeroSection, ImageGallery

+ 2403 - 0
PROJECT_ANALYSIS.md

@@ -0,0 +1,2403 @@
+# PROJECT ANALYSIS REPORT
+# Generated: 2025-11-05T09:26:28.189Z
+# Project: template
+
+## PROJECT SUMMARY
+- Total Files: 24
+- Total Size: 33266 characters
+- Main Components: 0
+- Routes: 0
+- Priority Documentation: 2
+- Work Files: 0
+- Priority Configs: 0
+
+## PRIORITY DOCUMENTATION (Highest Priority)
+- README.md (Markdown, 7142 chars)
+- app/DesignTokens.styl (Stylus, 5908 chars)
+
+## CURRENT WORK FILES
+No files in this category
+
+## PRIORITY CONFIGURATION FILES
+No files in this category
+
+## FILE TYPE DISTRIBUTION
+- Markdown: 1 files
+- Stylus: 6 files
+- Unknown: 1 files
+- CoffeeScript: 8 files
+- Pug Template: 8 files
+
+## PROJECT STRUCTURE
+### PRIORITY DOCUMENTATION
+#### README.md (Markdown, 7142 chars)
+```markdown
+# Текущее задание (Выполнить)
+
+## Общее задание:
+Разработать веб-приложение [название], используя платформу **s5l.ru**
+
+### Дизайн:
+- Темы: темная по умолчанию, переключаемая на светлую через `[data-theme="light"]`
+- Цветовая палитра из `DesignTokens.styl`
+- Atomic Design + User-Centered подход
+- Полная поддержка WCAG 2.2 (контраст ≥ 4.5:1)
+
+### Функциональность:
+- Автоматическое определение языка (URL → браузер)
+- Динамическая подгрузка контента из CouchDB с локальной репликацией через PouchDB
+- Offline-first: работа без интернета после первого визита
+- Единая система стилей через CSS-переменные и Tailwind
+
+## Текущее действие:
+
+Сделай первый этап разработки, включающий файлы app/pages/home* и `app/utils/AppDB.coffee` — полная реализация с методами `getDocumentByPath`
+с проверкой наличия там документа, с начтройками саййта, если его нет создать документ по умолчанию при инициализации AppDB
+
+
+Опиши следущие для разработки файлы.
+
+---
+
+# Промт для разработки на платформе s5l.ru
+
+Ты — Senior Fullstack-архитектор и UI/UX-прагматик. Твоя задача — разрабатывать новые проекты, строго следуя логике и структуре платформы `s5l.ru`.
+
+## Стек (НЕИЗМЕНЕН)
+- **Frontend**: Vue 3 (Composition API через `render` функции), CoffeeScript, Pug, Stylus, Tailwind CSS, svg, webp, webm, peerjs, websocket, webtorrent
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы, админка)  
+- **Сборка**: все шаблоны → `pug.json`, стили → `styl.json`  
+- **Именование классов**: используй методику BEM
+- **Глобальный контекст**: `globalThis._` — ссылка на корневой Vue-экземпляр из `app/app.coffee`
+
+# Проект: s5l.ru
+
+## Общее описание
+`s5l.ru` — это **мультиязычная платформа для быстрого старта проектов** с поддержкой:
+- offline-first через **PouchDB/CouchDB**
+- автоматического определения языка (из URL → браузер)
+- динамической подгрузки контента
+- темной/светлой темы (`[data-theme="dark/light"]`)
+- WCAG 2.2 (контраст ≥ 4.5:1)
+
+## Стек
+- **Frontend**: Vue 3 (render-функции), CoffeeScript, Pug, Stylus, Tailwind CSS
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы)
+- **Сборка**: `pug.json`, `styl.json`
+
+## Запуск нового проекта
+1. Создать дизайн-документы в CouchDB
+2. Положить стартовые документы с `type: 'page'`, `path: '/'`, и `translations`
+3. Использовать `AppDB.getDocumentByPath` в `beforeMount`
+4. Стили — только через CSS-переменные из `DesignTokens.styl`
+
+## Доступность
+- Поддержка тем: `:root` → `[data-theme="light"]`
+- Контраст ≥ 4.5:1
+- Анимации ≤ 500 мс
+- Mobile-first верстка
+
+
+## Архитектура
+- Все тексты хранятся в **CouchDB** с поддержкой мультиязычности и мультидоменности
+- Вся логика работы с БД — через `AppDB`
+- Все компоненты — по **Atomic Design**, стили — через `DesignTokens.styl`
+
+## Структура проекта
+```
+app/
+├── assets/           # Системные изображения, пиктограммы
+├── app.coffee        # инициализация Vue, AppDB, глобальный _ 
+├── app.pug           # Основной шаблон с Хедером, <router-view>, Футером
+├── app.styl          # Глобальные стили
+├── DesignTokens.styl # дизайн-система
+├── utils/
+|    └── AppDB.coffee # доступ к данным
+├── pages/            # Страницы проекта
+|    ├── Home.coffee
+|    ├── Home.pug
+|    └── Home.styl
+└── shared/
+     ├── AppLink.*     # компонент ссылок
+     └── ...
+```
+
+## Правила
+
+### 1. Vue-компоненты
+- **Имя файла**: PascalCase (`NewsList.coffee`, `NewsList.pug`, `NewsList.styl`)  
+- **Экспорт**: `module.exports = { name: '...', render: ..., data: -> {}, ... }`  
+- **Стили**: подключать через  
+  ```coffee
+  document.head.insertAdjacentHTML 'beforeend', '<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+  ```
+- **Шаблон**: рендерить через  
+  ```coffee
+  render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+  ```
+- **Жизненный цикл**:  
+  ❌ НЕПРАВИЛЬНО:  
+  ```coffeescript
+  async beforeMount: ->
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```coffeescript
+  beforeMount: ->
+  ```  
+  *(асинхронность обрабатывается внутри метода через `await`, но сигнатура — без `async`)*
+
+### 2. Роутинг
+- Все маршруты — в `temp.coffee` → `VueRouter.createRouter({ routes: [...] })`  
+- Компонент страницы должен быть `require`'нут без `.default` только если не экспортирует как `default`
+
+### 3. Ссылки
+- **ЗАПРЕЩЕНО**: `a(href="...")`, `router-link(to="...")`  
+- **ТОЛЬКО**: `app-link(to="...")` с подключением компонента `'app-link': require 'app/shared/AppLink'`
+
+### 4. Стили
+- **Цвета, отступы, шрифты** — ТОЛЬКО из `DesignTokens.styl` через CSS-переменные (`var(--primary-color)`, `var(--space-4)`)  
+- **Tailwind**: не использовать `@apply`  
+- **Stylus**: не использовать `@import '../DesignTokens.styl'` — он уже подключен глобально
+
+### 5. Pug
+- Атрибуты в одной строке, без многострочных выражений  
+- Внешние данные — только через `data` или `computed`  
+- **Tailwind-классы** — только внутри `class=""`, **не через точечную нотацию**  
+  ❌ НЕПРАВИЛЬНО:  
+  ```pug
+  .max-w-4xl.mx-auto.px-4
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```pug
+  div(class="max-w-4xl mx-auto px-4")
+  ```  
+- Пример правильно:
+  ```pug
+  div(v-for="item in items" :key="item.id")
+  div(:class="isActive ? 'active' : 'inactive'" class="w-full")
+  ```
+
+### 6. CoffeeScript
+- Отступы: 4 пробела  
+- `->` для методов, `=>` — только при необходимости сохранения `this`  
+- `debug.log "сообщение"` вместо `console.log`  
+- Строки: `"строка="+переменная`, без интерполяции
+
+### 7. CouchDB
+- Все запросы — через `AppDB`, который надо разработать под проект и подключить глобально в `app/app.coffee`
+- Дизайн-документы: создавать функции `.toString()`
+
+### 8. Доступность и дизайн
+- WCAG 2.2 (контраст ≥ 4.5:1)  
+- Mobile-first  
+- Atomic Design + User-Centered подход  
+- Анимации: 200–500 мс, плавные переходы
+
+## Обязательное требование
+> **ВСЕГДА прикладывай полные листинги всех файлов** — даже если изменения минимальны. Частичные или сокращённые фрагменты недопустимы. Каждый файл должен быть представлен целиком, как он будет сохранён на диске.
+
+## Шаблон компонента (полный пример)
+**Файл**: `app/shared/NewsList.coffee`
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend','<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+module.exports =
+    name: 'NewsList'
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+    data: ->
+        return {
+            _: _
+            posts: []
+        }
+    beforeMount: ->
+        @posts = await AppDB.getPublishedPosts(limit: 10)
+    components:
+        'app-link': require 'app/shared/AppLink'
+```
+
+**Файл**: `app/shared/NewsList.pug`
+```pug
+div(class="space-y-4")
+    app-link(v-for="post in posts" :key="post.id" :to="'/pages/'+post.id")
+        h3(class="text-xl") {{ post.doc.h }}
+```
+
+**Файл**: `app/shared/NewsList.styl`
+```stylus
+// Только стили компонента. DesignTokens — через var()
+.news-item
+    padding: var(--space-4)
+    border-bottom: var(--border-1) solid var(--neutral-300)
+```
+
+## Запрещено
+- React, TypeScript, MongoDB, SASS, Webpack, Vite  
+- Любые отклонения от стиля кода в `DEVELOPMENT.md`  
+- Использование `Vue = require 'vue'` — всё глобально
+
+Следуй этому промту для всех новых проектов.
+
+---
+
+```
+
+#### app/DesignTokens.styl (Stylus, 5908 chars)
+```stylus
+:root 
+    // Цветовая система для темной темы по умолчанию
+    --primary-color: #f87171
+    --primary-dark: #ef4444
+    --primary-light: #fca5a5
+
+    --secondary-color: #1e293b
+    --secondary-dark: #0f172a
+    --secondary-light: #334155
+
+    --accent-color: #22d3ee
+    --accent-dark: #06b6d4
+    --accent-light: #67e8f9
+
+    // Нейтральные цвета для темной темы
+    --neutral-50: #0f172a
+    --neutral-100: #1e293b
+    --neutral-200: #334155
+    --neutral-300: #475569
+    --neutral-400: #64748b
+    --neutral-500: #94a3b8
+    --neutral-600: #cbd5e1
+    --neutral-700: #e2e8f0
+    --neutral-800: #f1f5f9
+    --neutral-900: #f8fafc
+
+    // Цвета текста для темной темы
+    --text-primary: #f8fafc
+    --text-secondary: #e2e8f0
+    --text-muted: #94a3b8
+
+    // Цвета фона для темной темы
+    --bg-primary: #0f172a
+    --bg-secondary: #1e293b
+    --bg-card: #1e293b
+    --bg-overlay: rgba(15, 23, 42, 0.8)
+
+    // Градиенты для темной темы
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--secondary-dark) 0%, var(--secondary-color) 100%)
+
+    // Типографическая система
+    --font-family-sans: 'Inter', 'Segoe UI', system-ui, sans-serif
+    --font-family-serif: 'Georgia', 'Times New Roman', serif
+
+    --text-xs: 0.75rem
+    --text-sm: 0.875rem
+    --text-base: 1rem
+    --text-lg: 1.125rem
+    --text-xl: 1.25rem
+    --text-2xl: 1.5rem
+    --text-3xl: 1.875rem
+    --text-4xl: 2.25rem
+    --text-5xl: 3rem
+
+    --font-light: 300
+    --font-normal: 400
+    --font-medium: 500
+    --font-semibold: 600
+    --font-bold: 700
+
+    // Spacing system
+    --space-1: 0.25rem
+    --space-2: 0.5rem
+    --space-3: 0.75rem
+    --space-4: 1rem
+    --space-5: 1.25rem
+    --space-6: 1.5rem
+    --space-8: 2rem
+    --space-10: 2.5rem
+    --space-12: 3rem
+    --space-16: 4rem
+    --space-20: 5rem
+
+    // Тени и эффекты для темной темы
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6), 0 2px 4px -1px rgba(0, 0, 0, 0.4)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7), 0 4px 6px -2px rgba(0, 0, 0, 0.5)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8), 0 10px 10px -5px rgba(0, 0, 0, 0.6)
+
+    // Анимации
+    --transition-fast: 0.15s ease-in-out
+    --transition-normal: 0.3s ease-in-out
+    --transition-slow: 0.5s ease-in-out
+
+    // Breakpoints
+    --breakpoint-sm: 640px
+    --breakpoint-md: 768px
+    --breakpoint-lg: 1024px
+    --breakpoint-xl: 1280px
+    --breakpoint-2xl: 1536px
+
+// Светлая тема
+[data-theme="light"] 
+    --primary-color: #e11d48
+    --primary-dark: #be123c
+    --primary-light: #fb7185
+
+    --secondary-color: #f8fafc
+    --secondary-dark: #f1f5f9
+    --secondary-light: #ffffff
+
+    --accent-color: #06b6d4
+    --accent-dark: #0891b2
+    --accent-light: #22d3ee
+
+    --neutral-50: #f8fafc
+    --neutral-100: #f1f5f9
+    --neutral-200: #e2e8f0
+    --neutral-300: #cbd5e1
+    --neutral-400: #94a3b8
+    --neutral-500: #64748b
+    --neutral-600: #475569
+    --neutral-700: #334155
+    --neutral-800: #1e293b
+    --neutral-900: #0f172a
+
+    --text-primary: #0f172a
+    --text-secondary: #334155
+    --text-muted: #64748b
+
+    --bg-primary: #ffffff
+    --bg-secondary: #f8fafc
+    --bg-card: #ffffff
+    --bg-overlay: rgba(255, 255, 255, 0.8)
+
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--neutral-100) 0%, var(--neutral-50) 100%)
+
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)
+
+// Утилитарные классы для кастомных свойств
+.bg-primary 
+    background-color: var(--primary-color)
+
+.text-primary 
+    color: var(--primary-color)
+
+.border-primary 
+    border-color: var(--primary-color)
+
+.bg-accent 
+    background-color: var(--accent-color)
+
+.text-accent 
+    color: var(--accent-color)
+
+.bg-neutral 
+    background-color: var(--neutral-500)
+
+.text-neutral 
+    color: var(--neutral-500)
+
+.bg-dark 
+    background-color: var(--bg-primary)
+
+.text-dark 
+    color: var(--text-primary)
+
+.bg-card 
+    background-color: var(--bg-card)
+
+.text-card 
+    color: var(--text-primary)
+
+// Анимации
+.transition-fast 
+    transition: var(--transition-fast)
+
+.transition-normal 
+    transition: var(--transition-normal)
+
+.transition-slow 
+    transition: var(--transition-slow)
+
+// Тени
+.shadow-custom-sm 
+    box-shadow: var(--shadow-sm)
+
+.shadow-custom-md 
+    box-shadow: var(--shadow-md)
+
+.shadow-custom-lg 
+    box-shadow: var(--shadow-lg)
+
+.shadow-custom-xl 
+    box-shadow: var(--shadow-xl)
+// Добавляем дополнительные утилитарные классы для лучшей поддержки компонентов
+.card-primary 
+    background-color: var(--bg-card)
+    border: 1px solid var(--neutral-300)
+    border-radius: 8px
+    box-shadow: var(--shadow-sm)
+    transition: all var(--transition-normal)
+
+.card-primary:hover 
+    border-color: var(--primary-color)
+    box-shadow: var(--shadow-md)
+
+.text-icon 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .text-icon 
+    filter: brightness(0) invert(1)
+
+.icon-primary 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .icon-primary 
+    filter: brightness(0) invert(1)
+
+// Утилиты для контрастного текста
+.text-contrast-high 
+    color: var(--text-primary)
+
+.text-contrast-medium 
+    color: var(--text-secondary)
+
+.text-contrast-low 
+    color: var(--text-muted)
+
+// Утилиты для фонов
+.bg-surface 
+    background-color: var(--bg-card)
+
+.bg-surface-alt 
+    background-color: var(--bg-secondary)
+
+```
+
+### OTHER FILES
+#### .gitignore (Unknown, 29 chars)
+```text
+html.json
+pug.json
+styl.json
+
+```
+
+#### app/app.coffee (CoffeeScript, 3584 chars)
+```coffeescript
+# Подключение мета информации
+document.head.insertAdjacentHTML 'beforeend', '<meta charset="UTF-8">'
+document.head.insertAdjacentHTML 'beforeend', '<meta name="viewport" content="width=device-width, initial-scale=1.0">'
+
+# Настройка tailwind
+#tailwind.config = require 'tailwind.config.js'
+
+# Подключение основных стилей
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="main.css">' + stylFns['main.css'] + '</style>')
+
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="app/DesignTokens.styl">' + stylFns['app/DesignTokens.styl'] + '</style>')
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="app/app.styl">' + stylFns['app/app.styl'] + '</style>')
+
+
+
+# Маршруты
+routes = [
+    { path: '/', component: require 'app/pages/Home' }
+    { path: '/:path*', component: require 'app/pages/DocumentPage' }
+]
+globalThis._ = {}
+# Глобальное определение vuejs приложения
+globalThis.app = Vue.createApp
+    name: 'app'
+    data: () ->
+        return {
+            appState:
+                currentDocument: null
+                currentLanguage: 'ru'
+                availableLanguages: ['ru', 'en', 'tj']
+                loading: true
+                error: null
+            dbService: new (require('app/core/DB'))()
+        }
+    
+    beforeMount: ->
+        globalThis.AppDB = new (require 'app/utils/AppDB')()
+        await globalThis.AppDB.init()
+        globalThis._ = @
+    computed:
+        currentLanguage: ->
+            @appState.currentLanguage
+    watch:
+        currentLanguage:
+            handler: (newDoc) ->
+                debug.dir newDoc
+                @loadDocumentForPath(window.location.pathname)
+            immediate: true
+    methods:
+        initializeApp: ->
+            # Определяем язык из URL или браузера
+            @detectLanguage()
+            # Загружаем документ для текущего пути
+            @loadDocumentForPath(window.location.pathname)
+        
+        detectLanguage: ->
+            # Простая логика определения языка
+            pathLang = window.location.pathname.split('/')[1]
+            if pathLang in @appState.availableLanguages
+                @appState.currentLanguage = pathLang
+            else
+                browserLang = navigator.language.split('-')[0]
+                if browserLang in @appState.availableLanguages
+                    @appState.currentLanguage = browserLang
+        
+        loadDocumentForPath: (path) ->
+            try
+                @appState.loading = true
+                doc = await AppDB.getDocumentByPath(path, AppDB.currentLanguage)
+                @appState.currentDocument = doc
+                @appState.loading = false
+                
+                # Устанавливаем заголовок страницы
+                if doc?.title
+                    document.head.insertAdjacentHTML('beforeend', '<title>' + doc.title + '</title>')
+            catch error
+                @appState.error = "Ошибка загрузки документа: " + error
+                @appState.loading = false
+        
+    
+    render: (new Function '_ctx', '_cache', renderFns['app/app.pug'])()
+
+    
+    components: {
+        'hero-section': require('shared/HeroSection')
+        'image-gallery': require('shared/ImageGallery')
+    }
+# Создаем и настраиваем роутер
+router = VueRouter.createRouter({
+    routes: routes
+    history: VueRouter.createWebHistory()
+    scrollBehavior: (to, from, savedPosition) ->
+        if savedPosition
+            return savedPosition
+        else
+            return { x: 0, y: 0 }
+})
+
+app.use(router)
+app.mount('body')
+
+```
+
+#### app/app.pug (Pug Template, 699 chars)
+```pug
+include ../pug/base.pug
+include ../pug/bem.pug
+
+div(class="min-h-screen bg-white dark:bg-gray-900 transition-colors duration-300")
+    div(v-if="appState.loading" class="flex items-center justify-center min-h-screen")
+        div(class="text-center")
+            div(class="animate-spin rounded-full h-32 w-32 border-b-2 border-blue-600")
+            p(class="mt-4 text-gray-600 dark:text-gray-400") Загрузка...
+    
+    div(v-else-if="appState.error" class="flex items-center justify-center min-h-screen")
+        div(class="text-center")
+            div(class="text-red-600 text-xl") Ошибка
+            p(class="text-gray-600 dark:text-gray-400") {{ appState.error }}
+    
+    router-view(v-else)
+
+```
+
+#### app/app.styl (Stylus, 1013 chars)
+```stylus
+// Переменные темы
+:root 
+    --primary-color: #3b82f6
+    --secondary-color: #1e40af
+    --text-primary: #1f2937
+    --text-secondary: #6b7280
+    --bg-primary: #ffffff
+    --bg-secondary: #f9fafb
+
+[data-theme="dark"]
+    --primary-color: #60a5fa
+    --secondary-color: #3b82f6
+    --text-primary: #f9fafb
+    --text-secondary: #d1d5db
+    --bg-primary: #111827
+    --bg-secondary: #1f2937
+
+// Базовые стили
+body 
+    font-family: 'Inter', system-ui, -apple-system, sans-serif
+    color: var(--text-primary)
+    background-color: var(--bg-primary)
+    transition: all 0.3s ease
+
+// Стили для Markdown контента
+.prose 
+    h1, h2, h3, h4, h5, h6 
+        color: var(--text-primary)
+        font-weight: 600
+    
+    p 
+        color: var(--text-secondary)
+        line-height: 1.7
+    
+    a 
+        color: var(--primary-color)
+        text-decoration: none
+        &:hover 
+            text-decoration: underline
+    
+    img 
+        border-radius: 0.5rem
+        box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1)
+
+```
+
+#### app/layout.pug (Pug Template, 324 chars)
+```pug
+include ../pug/base.pug
+include ../pug/bem.pug
+
++mbh
+    header(class="sticky top-0 z-50 glass border-b border-neutral-300/60 transition-all duration-300")
+        div(class="navbar max-w-7xl mx-auto px-4 sm:px-6 lg:px-8")
+    block top-content
+    
++mbl(class="py-8 md:py-12 lg:py-16")
+    .container
+        block content
+
+```
+
+#### app/pages/Home.coffee (CoffeeScript, 697 chars)
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/pages/Home.styl">'+stylFns['app/pages/Home.styl']+'</style>'
+module.exports =
+    name: 'Home'
+    render: (new Function '_ctx', '_cache', renderFns['app/pages/Home.pug'])()
+    data: ->
+        return {
+            _: _
+            document: null
+        }
+    beforeMount: ->
+        try
+            @document = await AppDB.getDocumentByPath('/', AppDB.currentLanguage)
+        catch e
+            debug.log "Document load error:", e
+    components:
+        'app-link': require 'app/shared/AppLink'
+        'hero-section': require 'app/shared/HeroSection'
+        'image-gallery': require 'app/shared/ImageGallery'
+
+```
+
+#### app/pages/Home.pug (Pug Template, 845 chars)
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+extends ../layout.pug
+
+block top-content
+    hero-section(:document="document")
+
+block content
+    div(class="max-w-4xl mx-auto px-4" v-if="document")
+        h1(class="text-3xl font-bold text-contrast-high animate-fade-in-up") {{ document.translations[_.currentLanguage]?.title || document.translations.en.title }}
+        p(class="text-xl text-contrast-medium mb-8 animate-fade-in-up") {{ document.translations[_.currentLanguage]?.subtitle || document.translations.en.subtitle }}
+        div(class="prose mt-6 animate-fade-in-up" v-html="marked.parse(document.translations[_.currentLanguage]?.content || document.translations.en.content)")
+        div(class="mt-12")
+            image-gallery(:images="document.translations[_.currentLanguage]?.gallery || document.translations.en.gallery")
+
+```
+
+#### app/pages/Home.styl (Stylus, 281 chars)
+```stylus
+// Используем только утилиты из DesignTokens
+.animate-fade-in-up
+    animation: fadeInUp var(--transition-slow) ease-out
+
+@keyframes fadeInUp
+    from
+        opacity: 0
+        transform: translateY(var(--transition-px))
+    to
+        opacity: 1
+        transform: translateY(0)
+
+```
+
+#### app/shared/AppLink.coffee (CoffeeScript, 633 chars)
+```coffeescript
+document.head.insertAdjacentHTML('beforeend','<style type="text/css" file="app/shared/AppLink.styl">'+stylFns['app/shared/AppLink.styl']+'</style>')
+module.exports =
+    default:
+        render: (new Function '_ctx', '_cache', renderFns['app/shared/AppLink.pug'])()
+        name: 'AppLink'
+        props:
+            to:
+                type: [String, Object]
+                required: true
+        computed:
+            isExternal: ->
+                if typeof @.to == 'string'
+                    return @.to.startsWith('http')
+                return false
+        data: -> 
+            return {
+                _: _
+            }
+
+```
+
+#### app/shared/AppLink.pug (Pug Template, 214 chars)
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+
+a.app-link(v-if="isExternal" v-bind="$attrs" :href="to" target="_blank" rel="noopener")
+    slot
+router-link.app-link(v-else v-bind="$attrs" :to="to")
+    slot
+
+```
+
+#### app/shared/AppLink.styl (Stylus, 1264 chars)
+```stylus
+@import '../DesignTokens.styl'
+
+// Базовые стили для AppLink компонента
+.app-link 
+    color: var(--primary-color)
+    text-decoration: none
+    transition: color var(--transition-fast)
+
+.app-link:hover 
+    color: var(--primary-dark)
+    text-decoration: underline
+
+.app-link.router-link-active 
+    font-weight: var(--font-semibold)
+    color: var(--primary-dark)
+
+// Стили для внешних ссылок
+.app-link-external::after 
+    content: " ↗"
+    font-size: 0.875em
+    opacity: 0.7
+
+// Стили для кнопко-подобных ссылок
+.app-link-button 
+    display: inline-flex
+    align-items: center
+    gap: var(--space-2)
+    padding: var(--space-2) var(--space-4)
+    background: var(--primary-color)
+    color: white
+    border-radius: 6px
+    font-weight: var(--font-medium)
+    transition: all var(--transition-fast)
+
+.app-link-button:hover 
+    background: var(--primary-dark)
+    transform: translateY(-1px)
+    text-decoration: none
+    color: white
+    box-shadow: var(--shadow-md)
+
+// Стили для иконок в ссылках
+.app-link-with-icon 
+    display: inline-flex
+    align-items: center
+    gap: var(--space-2)
+
+.app-link-icon 
+    width: 16px
+    height: 16px
+    transition: transform var(--transition-fast)
+
+.app-link:hover .app-link-icon 
+    transform: translateX(2px)
+
+```
+
+#### app/shared/HeroSection.coffee (CoffeeScript, 311 chars)
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/shared/HeroSection.styl">'+stylFns['app/shared/HeroSection.styl']+'</style>'
+module.exports =
+    name: 'HeroSection'
+    props: [ 'document' ]
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/HeroSection.pug'])()
+
+```
+
+#### app/shared/HeroSection.pug (Pug Template, 574 chars)
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+section(v-if="document" class="hero-section bg-gradient")
+    div(class="max-w-7xl mx-auto px-4 py-24 text-center text-white")
+        h1(v-if="document.translations[_.appState.currentLanguage]" class="text-5xl font-bold mb-6") {{ document.translations[_.appState.currentLanguage].title || document.translations.en.title }}
+        p(v-if="document.translations[_.appState.currentLanguage]" class="text-xl opacity-90") {{ document.translations[_.appState.currentLanguage].subtitle || document.translations.en.subtitle }}
+
+```
+
+#### app/shared/HeroSection.styl (Stylus, 125 chars)
+```stylus
+.hero-section
+    background: var(--gradient-primary)
+    color: white
+    padding: var(--space-16) 0
+    text-align: center
+
+```
+
+#### app/shared/ImageGallery.coffee (CoffeeScript, 367 chars)
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/shared/ImageGallery.styl">'+stylFns['app/shared/ImageGallery.styl']+'</style>'
+module.exports =
+    name: 'ImageGallery'
+    props:
+        images:
+            type: Array
+            default: -> []
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/ImageGallery.pug'])()
+
+```
+
+#### app/shared/ImageGallery.pug (Pug Template, 414 chars)
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+div(v-if="images && images.length > 0" class="image-gallery grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6")
+    div(v-for="(img, idx) in images" :key="idx" class="overflow-hidden rounded-lg shadow-custom-md bg-surface")
+        img(:src="img.src" :alt="img.alt || ''" class="w-full h-auto object-cover transition-transform duration-300 hover:scale-105")
+
+```
+
+#### app/shared/ImageGallery.styl (Stylus, 324 chars)
+```stylus
+.image-gallery
+    display: grid
+    gap: var(--space-6)
+    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))
+
+.image-gallery img
+    width: 100%
+    height: auto
+    object-fit: cover
+    border-radius: 8px
+    transition: transform var(--transition-normal)
+
+.image-gallery img:hover
+    transform: scale(1.05)
+
+```
+
+#### app/utils/AppDB.coffee (CoffeeScript, 4684 chars)
+```coffeescript
+# FILE: app/utils/AppDB.coffee
+class AppDB
+    currentLanguage: 'ru'
+    currentProject: 's5l.ru'
+    designDocVersion: '1.1' # управление версией дизайна
+
+    constructor: ->
+        @localDB = new PouchDB('s5l_local')
+        @remoteDB = new PouchDB('https://oleg:631074@couchdb.favt.ru.net/s5lru/')
+        @syncHandler = null
+
+    init: ->
+        try
+            await @remoteDB.info()
+            debug.log "Remote DB connected"
+            await @ensureDesignDocs()
+            await @ensureDefaultContent()
+            @startSync()
+            AppDB.currentLanguage = globalThis._?.appState?.currentLanguage or 'ru'
+        catch e
+            debug.log "DB init failed:", e
+
+    startSync: ->
+        @syncHandler = @localDB.sync(@remoteDB, { live: true, retry: true })
+            .on 'error', (err) -> debug.log "Sync error:", err
+
+    ensureDesignDocs: ->
+        adminDoc =
+            _id: '_design/admin'
+            version: @designDocVersion
+            views:
+                byPath:
+                    map: (doc) ->
+                        if doc.type == 'page'
+                            emit [doc.domain, doc.path], doc
+                    .toString()
+                byType:
+                    map: (doc) ->
+                        emit doc.type, doc
+                    .toString()
+
+        try
+            existing = await @remoteDB.get('_design/admin')
+            if existing.version != @designDocVersion
+                adminDoc._rev = existing._rev
+                await @remoteDB.put(adminDoc)
+                debug.log "Design doc updated to v#{@designDocVersion}"
+        catch
+            await @remoteDB.put(adminDoc)
+            debug.log "Design doc created v#{@designDocVersion}"
+
+    ensureDefaultContent: ->
+        defaultHome =
+            _id: 'page::s5l.ru::/'
+            type: 'page'
+            domain: 's5l.ru'
+            path: '/'
+            translations:
+                ru:
+                    title: "s5l.ru — мультиязычная offline-first платформа"
+                    subtitle: "Разрабатывайте быстро, работайте везде"
+                    content: '''
+# Добро пожаловать на s5l.ru
+
+**s5l.ru** — это платформа для быстрого запуска веб-проектов с поддержкой:
+- offline-first через PouchDB/CouchDB
+- автоматического переключения языка
+- динамической подгрузки контента
+- полной WCAG 2.2-совместимости
+
+Все тексты хранятся в базе и легко редактируются через админку.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+                en:
+                    title: "s5l.ru — multilingual offline-first platform"
+                    subtitle: "Build fast, work anywhere"
+                    content: '''
+# Welcome to s5l.ru
+
+**s5l.ru** is a platform for rapid web project launches with:
+- offline-first via PouchDB/CouchDB
+- automatic language switching
+- dynamic content loading
+- full WCAG 2.2 compliance
+
+All text is stored in the database and editable via admin panel.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+                tj:
+                    title: "s5l.ru — платформаи бисёрзабон ва аввал офлайн"
+                    subtitle: "Бисёр тез бунёд кунед, дар ҳама ҷо кор кунед"
+                    content: '''
+# Ба s5l.ru хуш омадед
+
+**s5l.ru** — ин платформа барои оғози тези лоиҳаҳои веб аст бо:
+- офлайн-аввал аз рӯи PouchDB/CouchDB
+- ивази худкори забон
+- боркунии динамикӣ
+- мутобиқати пурраи WCAG 2.2
+
+Ҳамаи матнҳо дар база нигоҳ дошта мешаванд ва аз ҷониби панели маъмури озодона таҳрир карда мешаванд.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+
+        try
+            await @remoteDB.get('page::s5l.ru::/')
+        catch
+            await @remoteDB.put(defaultHome)
+            debug.log "Default home page created"
+
+    getDocumentByPath: (path, lang = @currentLanguage) ->
+        path = path or '/'
+        try
+            result = await @localDB.query('admin/byPath', { key: [@currentProject, path], include_docs: true })
+            if result.rows.length > 0
+                doc = result.rows[0].doc
+                return doc
+            else
+                throw new Error "Document not found"
+        catch e
+            debug.log "Fallback for path:", path, "lang:", lang
+            # fallback to English if not found
+            if lang != 'en'
+                return await @getDocumentByPath(path, 'en')
+            else
+                throw new Error "Document not available even in English"
+
+module.exports = AppDB
+
+```
+
+#### doc.coffee (CoffeeScript, 1285 chars)
+```coffeescript
+module.exports = 
+     version: "0.0.1"
+     adres: [
+        {
+          "adr": "https://cdn.tailwindcss.com/3.4.17"
+          "eventName": "tailwindReady"
+          "obj": "tailwind"
+        }
+        {
+          "adr": "https://unpkg.com/pouchdb/dist/pouchdb.min.js"
+          "eventName": "puochReady"
+          "obj": "PouchDB"
+        }
+        {
+          "adr": "https://unpkg.com/vue@3/dist/vue.runtime.global.prod.js"
+          "eventName": "vueReady"
+          "obj": "Vue"
+        }
+        {
+          "adr": "https://unpkg.com/vue-router@4/dist/vue-router.global.js"
+          "eventName": "VueRouterReady"
+          "obj": "VueRouter"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/@vue/compiler-sfc@3.5.22/dist/compiler-sfc.esm-browser.min.js"
+          "eventName": "compileTemplateReady"
+          "obj": "compileTemplate"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/marked@16.4.1/lib/marked.umd.min.js"
+          "eventName": "markedReady"
+          "obj": "marked"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/openlayers@4.6.5/dist/ol.min.js"
+          "css": "https://cdn.jsdelivr.net/npm/openlayers@4.6.5/dist/ol.min.css"
+          "eventName": "leafletReady"
+          "obj": "ol"
+        }
+    ]
+
+```
+
+#### lzma.coffee (CoffeeScript, 1010 chars)
+```coffeescript
+globalThis.debug = require('debug.coffee').default
+require('headVue.coffee')
+
+
+document.documentElement.classList.add('dark')
+
+globalThis.initCount = 0
+ic = ()->
+    if initCount > 5
+       window.location.reload()
+    else if  not globalThis['appReady']
+       initCount++
+       #setTimeout ic, 200
+ic()
+# обязательно подключение глобальных массивов
+globalThis.renderFns = require 'pug.json'
+globalThis.stylFns   = require 'styl.json'
+
+try
+    init =  (event={})->
+        debug.dir   globalThis['vueReady']
+        debug.log "Init Start"
+        if  not globalThis['appReady'] and globalThis['vueReady'] and globalThis['puochReady']
+            debug.log 'init start ok'
+            try
+                require('app/app.coffee')
+                globalThis['appReady'] = true
+                debug.log "init is ok"
+            catch err
+                debug.dir err
+        else if  not globalThis['appReady']
+                debug.log 'pausedEvent appReady'
+                setTimeout init, 200
+    init()
+
+```
+
+#### pug/base.pug (Pug Template, 504 chars)
+```pug
+include ./bem.pug
+
+
+mixin mbh
+    - var otherClasses = attributes.class || ''
+    +b('hfn')(class="h-max overflow-hidden relative")
+        +e('hfn','fon')
+
+mixin mbl
+    - var otherClasses = attributes.class || ''
+    +b('hfn')(class="h-max overflow-hidden relative")
+        +e('hfn','fon')(class="[background:url('https://jahonnamo.s5l.ru/assets/jahonnamo.s5l.ru/bkg00.webp')_0_0_/_cover_no-repeat] bg-[#ffffff] absolute h-full w-full z-[-1]")
+                  if block
+                        block
+
+```
+
+#### pug/bem.pug (Pug Template, 1035 chars)
+```pug
+//- bem.pug
+
+//- Базовый миксин для блоков и элементов
+mixin b(blockName, elemName)
+  - var className = blockName
+  - var twClasses = attributes.tw || ''
+  - var otherClasses = attributes.class || ''
+
+  if elemName
+    - className += '__' + elemName
+
+  //- Обработка модификаторов
+  if attributes.mod
+    - className += ' ' + blockName + '--' + attributes.mod
+  if attributes.mods
+    each mod in attributes.mods.split(',')
+      - className += ' ' + blockName + '--' + mod.trim()
+
+  //- Собираем финальный класс
+  - var finalClass = [className, twClasses, otherClasses].filter(Boolean).join(' ')
+
+  //- Удаляем обработанные атрибуты
+  - attributes.tw = null
+  - attributes.mod = null
+  - attributes.mods = null
+  - attributes.class = null
+
+  //- Генерация элемента
+  if block
+    div(class=finalClass)&attributes(attributes)
+      block
+  else
+    div(class=finalClass)&attributes(attributes)
+
+//- Миксин для элементов (альтернативный синтаксис)
+mixin e(blockName, elemName)
+  +b(blockName, elemName)&attributes(attributes)
+    block
+
+```
+
+
+## MAIN COMPONENTS
+
+
+## ROUTES
+
+
+## DEPENDENCIES
+
+
+## FULL SOURCE CODE
+## PRIORITY DOCUMENTATION SOURCE CODE
+// FILE: README.md
+// TYPE: Markdown
+// SIZE: 7142 characters
+// CATEGORY: PRIORITY DOCUMENTATION
+```markdown
+# Текущее задание (Выполнить)
+
+## Общее задание:
+Разработать веб-приложение [название], используя платформу **s5l.ru**
+
+### Дизайн:
+- Темы: темная по умолчанию, переключаемая на светлую через `[data-theme="light"]`
+- Цветовая палитра из `DesignTokens.styl`
+- Atomic Design + User-Centered подход
+- Полная поддержка WCAG 2.2 (контраст ≥ 4.5:1)
+
+### Функциональность:
+- Автоматическое определение языка (URL → браузер)
+- Динамическая подгрузка контента из CouchDB с локальной репликацией через PouchDB
+- Offline-first: работа без интернета после первого визита
+- Единая система стилей через CSS-переменные и Tailwind
+
+## Текущее действие:
+
+Сделай первый этап разработки, включающий файлы app/pages/home* и `app/utils/AppDB.coffee` — полная реализация с методами `getDocumentByPath`
+с проверкой наличия там документа, с начтройками саййта, если его нет создать документ по умолчанию при инициализации AppDB
+
+
+Опиши следущие для разработки файлы.
+
+---
+
+# Промт для разработки на платформе s5l.ru
+
+Ты — Senior Fullstack-архитектор и UI/UX-прагматик. Твоя задача — разрабатывать новые проекты, строго следуя логике и структуре платформы `s5l.ru`.
+
+## Стек (НЕИЗМЕНЕН)
+- **Frontend**: Vue 3 (Composition API через `render` функции), CoffeeScript, Pug, Stylus, Tailwind CSS, svg, webp, webm, peerjs, websocket, webtorrent
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы, админка)  
+- **Сборка**: все шаблоны → `pug.json`, стили → `styl.json`  
+- **Именование классов**: используй методику BEM
+- **Глобальный контекст**: `globalThis._` — ссылка на корневой Vue-экземпляр из `app/app.coffee`
+
+# Проект: s5l.ru
+
+## Общее описание
+`s5l.ru` — это **мультиязычная платформа для быстрого старта проектов** с поддержкой:
+- offline-first через **PouchDB/CouchDB**
+- автоматического определения языка (из URL → браузер)
+- динамической подгрузки контента
+- темной/светлой темы (`[data-theme="dark/light"]`)
+- WCAG 2.2 (контраст ≥ 4.5:1)
+
+## Стек
+- **Frontend**: Vue 3 (render-функции), CoffeeScript, Pug, Stylus, Tailwind CSS
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы)
+- **Сборка**: `pug.json`, `styl.json`
+
+## Запуск нового проекта
+1. Создать дизайн-документы в CouchDB
+2. Положить стартовые документы с `type: 'page'`, `path: '/'`, и `translations`
+3. Использовать `AppDB.getDocumentByPath` в `beforeMount`
+4. Стили — только через CSS-переменные из `DesignTokens.styl`
+
+## Доступность
+- Поддержка тем: `:root` → `[data-theme="light"]`
+- Контраст ≥ 4.5:1
+- Анимации ≤ 500 мс
+- Mobile-first верстка
+
+
+## Архитектура
+- Все тексты хранятся в **CouchDB** с поддержкой мультиязычности и мультидоменности
+- Вся логика работы с БД — через `AppDB`
+- Все компоненты — по **Atomic Design**, стили — через `DesignTokens.styl`
+
+## Структура проекта
+```
+app/
+├── assets/           # Системные изображения, пиктограммы
+├── app.coffee        # инициализация Vue, AppDB, глобальный _ 
+├── app.pug           # Основной шаблон с Хедером, <router-view>, Футером
+├── app.styl          # Глобальные стили
+├── DesignTokens.styl # дизайн-система
+├── utils/
+|    └── AppDB.coffee # доступ к данным
+├── pages/            # Страницы проекта
+|    ├── Home.coffee
+|    ├── Home.pug
+|    └── Home.styl
+└── shared/
+     ├── AppLink.*     # компонент ссылок
+     └── ...
+```
+
+## Правила
+
+### 1. Vue-компоненты
+- **Имя файла**: PascalCase (`NewsList.coffee`, `NewsList.pug`, `NewsList.styl`)  
+- **Экспорт**: `module.exports = { name: '...', render: ..., data: -> {}, ... }`  
+- **Стили**: подключать через  
+  ```coffee
+  document.head.insertAdjacentHTML 'beforeend', '<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+  ```
+- **Шаблон**: рендерить через  
+  ```coffee
+  render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+  ```
+- **Жизненный цикл**:  
+  ❌ НЕПРАВИЛЬНО:  
+  ```coffeescript
+  async beforeMount: ->
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```coffeescript
+  beforeMount: ->
+  ```  
+  *(асинхронность обрабатывается внутри метода через `await`, но сигнатура — без `async`)*
+
+### 2. Роутинг
+- Все маршруты — в `temp.coffee` → `VueRouter.createRouter({ routes: [...] })`  
+- Компонент страницы должен быть `require`'нут без `.default` только если не экспортирует как `default`
+
+### 3. Ссылки
+- **ЗАПРЕЩЕНО**: `a(href="...")`, `router-link(to="...")`  
+- **ТОЛЬКО**: `app-link(to="...")` с подключением компонента `'app-link': require 'app/shared/AppLink'`
+
+### 4. Стили
+- **Цвета, отступы, шрифты** — ТОЛЬКО из `DesignTokens.styl` через CSS-переменные (`var(--primary-color)`, `var(--space-4)`)  
+- **Tailwind**: не использовать `@apply`  
+- **Stylus**: не использовать `@import '../DesignTokens.styl'` — он уже подключен глобально
+
+### 5. Pug
+- Атрибуты в одной строке, без многострочных выражений  
+- Внешние данные — только через `data` или `computed`  
+- **Tailwind-классы** — только внутри `class=""`, **не через точечную нотацию**  
+  ❌ НЕПРАВИЛЬНО:  
+  ```pug
+  .max-w-4xl.mx-auto.px-4
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```pug
+  div(class="max-w-4xl mx-auto px-4")
+  ```  
+- Пример правильно:
+  ```pug
+  div(v-for="item in items" :key="item.id")
+  div(:class="isActive ? 'active' : 'inactive'" class="w-full")
+  ```
+
+### 6. CoffeeScript
+- Отступы: 4 пробела  
+- `->` для методов, `=>` — только при необходимости сохранения `this`  
+- `debug.log "сообщение"` вместо `console.log`  
+- Строки: `"строка="+переменная`, без интерполяции
+
+### 7. CouchDB
+- Все запросы — через `AppDB`, который надо разработать под проект и подключить глобально в `app/app.coffee`
+- Дизайн-документы: создавать функции `.toString()`
+
+### 8. Доступность и дизайн
+- WCAG 2.2 (контраст ≥ 4.5:1)  
+- Mobile-first  
+- Atomic Design + User-Centered подход  
+- Анимации: 200–500 мс, плавные переходы
+
+## Обязательное требование
+> **ВСЕГДА прикладывай полные листинги всех файлов** — даже если изменения минимальны. Частичные или сокращённые фрагменты недопустимы. Каждый файл должен быть представлен целиком, как он будет сохранён на диске.
+
+## Шаблон компонента (полный пример)
+**Файл**: `app/shared/NewsList.coffee`
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend','<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+module.exports =
+    name: 'NewsList'
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+    data: ->
+        return {
+            _: _
+            posts: []
+        }
+    beforeMount: ->
+        @posts = await AppDB.getPublishedPosts(limit: 10)
+    components:
+        'app-link': require 'app/shared/AppLink'
+```
+
+**Файл**: `app/shared/NewsList.pug`
+```pug
+div(class="space-y-4")
+    app-link(v-for="post in posts" :key="post.id" :to="'/pages/'+post.id")
+        h3(class="text-xl") {{ post.doc.h }}
+```
+
+**Файл**: `app/shared/NewsList.styl`
+```stylus
+// Только стили компонента. DesignTokens — через var()
+.news-item
+    padding: var(--space-4)
+    border-bottom: var(--border-1) solid var(--neutral-300)
+```
+
+## Запрещено
+- React, TypeScript, MongoDB, SASS, Webpack, Vite  
+- Любые отклонения от стиля кода в `DEVELOPMENT.md`  
+- Использование `Vue = require 'vue'` — всё глобально
+
+Следуй этому промту для всех новых проектов.
+
+---
+
+```
+
+// FILE: app/DesignTokens.styl
+// TYPE: Stylus
+// SIZE: 5908 characters
+// CATEGORY: PRIORITY DOCUMENTATION
+```stylus
+:root 
+    // Цветовая система для темной темы по умолчанию
+    --primary-color: #f87171
+    --primary-dark: #ef4444
+    --primary-light: #fca5a5
+
+    --secondary-color: #1e293b
+    --secondary-dark: #0f172a
+    --secondary-light: #334155
+
+    --accent-color: #22d3ee
+    --accent-dark: #06b6d4
+    --accent-light: #67e8f9
+
+    // Нейтральные цвета для темной темы
+    --neutral-50: #0f172a
+    --neutral-100: #1e293b
+    --neutral-200: #334155
+    --neutral-300: #475569
+    --neutral-400: #64748b
+    --neutral-500: #94a3b8
+    --neutral-600: #cbd5e1
+    --neutral-700: #e2e8f0
+    --neutral-800: #f1f5f9
+    --neutral-900: #f8fafc
+
+    // Цвета текста для темной темы
+    --text-primary: #f8fafc
+    --text-secondary: #e2e8f0
+    --text-muted: #94a3b8
+
+    // Цвета фона для темной темы
+    --bg-primary: #0f172a
+    --bg-secondary: #1e293b
+    --bg-card: #1e293b
+    --bg-overlay: rgba(15, 23, 42, 0.8)
+
+    // Градиенты для темной темы
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--secondary-dark) 0%, var(--secondary-color) 100%)
+
+    // Типографическая система
+    --font-family-sans: 'Inter', 'Segoe UI', system-ui, sans-serif
+    --font-family-serif: 'Georgia', 'Times New Roman', serif
+
+    --text-xs: 0.75rem
+    --text-sm: 0.875rem
+    --text-base: 1rem
+    --text-lg: 1.125rem
+    --text-xl: 1.25rem
+    --text-2xl: 1.5rem
+    --text-3xl: 1.875rem
+    --text-4xl: 2.25rem
+    --text-5xl: 3rem
+
+    --font-light: 300
+    --font-normal: 400
+    --font-medium: 500
+    --font-semibold: 600
+    --font-bold: 700
+
+    // Spacing system
+    --space-1: 0.25rem
+    --space-2: 0.5rem
+    --space-3: 0.75rem
+    --space-4: 1rem
+    --space-5: 1.25rem
+    --space-6: 1.5rem
+    --space-8: 2rem
+    --space-10: 2.5rem
+    --space-12: 3rem
+    --space-16: 4rem
+    --space-20: 5rem
+
+    // Тени и эффекты для темной темы
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6), 0 2px 4px -1px rgba(0, 0, 0, 0.4)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7), 0 4px 6px -2px rgba(0, 0, 0, 0.5)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8), 0 10px 10px -5px rgba(0, 0, 0, 0.6)
+
+    // Анимации
+    --transition-fast: 0.15s ease-in-out
+    --transition-normal: 0.3s ease-in-out
+    --transition-slow: 0.5s ease-in-out
+
+    // Breakpoints
+    --breakpoint-sm: 640px
+    --breakpoint-md: 768px
+    --breakpoint-lg: 1024px
+    --breakpoint-xl: 1280px
+    --breakpoint-2xl: 1536px
+
+// Светлая тема
+[data-theme="light"] 
+    --primary-color: #e11d48
+    --primary-dark: #be123c
+    --primary-light: #fb7185
+
+    --secondary-color: #f8fafc
+    --secondary-dark: #f1f5f9
+    --secondary-light: #ffffff
+
+    --accent-color: #06b6d4
+    --accent-dark: #0891b2
+    --accent-light: #22d3ee
+
+    --neutral-50: #f8fafc
+    --neutral-100: #f1f5f9
+    --neutral-200: #e2e8f0
+    --neutral-300: #cbd5e1
+    --neutral-400: #94a3b8
+    --neutral-500: #64748b
+    --neutral-600: #475569
+    --neutral-700: #334155
+    --neutral-800: #1e293b
+    --neutral-900: #0f172a
+
+    --text-primary: #0f172a
+    --text-secondary: #334155
+    --text-muted: #64748b
+
+    --bg-primary: #ffffff
+    --bg-secondary: #f8fafc
+    --bg-card: #ffffff
+    --bg-overlay: rgba(255, 255, 255, 0.8)
+
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--neutral-100) 0%, var(--neutral-50) 100%)
+
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)
+
+// Утилитарные классы для кастомных свойств
+.bg-primary 
+    background-color: var(--primary-color)
+
+.text-primary 
+    color: var(--primary-color)
+
+.border-primary 
+    border-color: var(--primary-color)
+
+.bg-accent 
+    background-color: var(--accent-color)
+
+.text-accent 
+    color: var(--accent-color)
+
+.bg-neutral 
+    background-color: var(--neutral-500)
+
+.text-neutral 
+    color: var(--neutral-500)
+
+.bg-dark 
+    background-color: var(--bg-primary)
+
+.text-dark 
+    color: var(--text-primary)
+
+.bg-card 
+    background-color: var(--bg-card)
+
+.text-card 
+    color: var(--text-primary)
+
+// Анимации
+.transition-fast 
+    transition: var(--transition-fast)
+
+.transition-normal 
+    transition: var(--transition-normal)
+
+.transition-slow 
+    transition: var(--transition-slow)
+
+// Тени
+.shadow-custom-sm 
+    box-shadow: var(--shadow-sm)
+
+.shadow-custom-md 
+    box-shadow: var(--shadow-md)
+
+.shadow-custom-lg 
+    box-shadow: var(--shadow-lg)
+
+.shadow-custom-xl 
+    box-shadow: var(--shadow-xl)
+// Добавляем дополнительные утилитарные классы для лучшей поддержки компонентов
+.card-primary 
+    background-color: var(--bg-card)
+    border: 1px solid var(--neutral-300)
+    border-radius: 8px
+    box-shadow: var(--shadow-sm)
+    transition: all var(--transition-normal)
+
+.card-primary:hover 
+    border-color: var(--primary-color)
+    box-shadow: var(--shadow-md)
+
+.text-icon 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .text-icon 
+    filter: brightness(0) invert(1)
+
+.icon-primary 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .icon-primary 
+    filter: brightness(0) invert(1)
+
+// Утилиты для контрастного текста
+.text-contrast-high 
+    color: var(--text-primary)
+
+.text-contrast-medium 
+    color: var(--text-secondary)
+
+.text-contrast-low 
+    color: var(--text-muted)
+
+// Утилиты для фонов
+.bg-surface 
+    background-color: var(--bg-card)
+
+.bg-surface-alt 
+    background-color: var(--bg-secondary)
+
+```
+
+## OTHER FILES SOURCE CODE
+// FILE: .gitignore
+// TYPE: Unknown
+// SIZE: 29 characters
+```text
+html.json
+pug.json
+styl.json
+
+```
+
+// FILE: app/app.coffee
+// TYPE: CoffeeScript
+// SIZE: 3584 characters
+```coffeescript
+# Подключение мета информации
+document.head.insertAdjacentHTML 'beforeend', '<meta charset="UTF-8">'
+document.head.insertAdjacentHTML 'beforeend', '<meta name="viewport" content="width=device-width, initial-scale=1.0">'
+
+# Настройка tailwind
+#tailwind.config = require 'tailwind.config.js'
+
+# Подключение основных стилей
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="main.css">' + stylFns['main.css'] + '</style>')
+
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="app/DesignTokens.styl">' + stylFns['app/DesignTokens.styl'] + '</style>')
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="app/app.styl">' + stylFns['app/app.styl'] + '</style>')
+
+
+
+# Маршруты
+routes = [
+    { path: '/', component: require 'app/pages/Home' }
+    { path: '/:path*', component: require 'app/pages/DocumentPage' }
+]
+globalThis._ = {}
+# Глобальное определение vuejs приложения
+globalThis.app = Vue.createApp
+    name: 'app'
+    data: () ->
+        return {
+            appState:
+                currentDocument: null
+                currentLanguage: 'ru'
+                availableLanguages: ['ru', 'en', 'tj']
+                loading: true
+                error: null
+            dbService: new (require('app/core/DB'))()
+        }
+    
+    beforeMount: ->
+        globalThis.AppDB = new (require 'app/utils/AppDB')()
+        await globalThis.AppDB.init()
+        globalThis._ = @
+    computed:
+        currentLanguage: ->
+            @appState.currentLanguage
+    watch:
+        currentLanguage:
+            handler: (newDoc) ->
+                debug.dir newDoc
+                @loadDocumentForPath(window.location.pathname)
+            immediate: true
+    methods:
+        initializeApp: ->
+            # Определяем язык из URL или браузера
+            @detectLanguage()
+            # Загружаем документ для текущего пути
+            @loadDocumentForPath(window.location.pathname)
+        
+        detectLanguage: ->
+            # Простая логика определения языка
+            pathLang = window.location.pathname.split('/')[1]
+            if pathLang in @appState.availableLanguages
+                @appState.currentLanguage = pathLang
+            else
+                browserLang = navigator.language.split('-')[0]
+                if browserLang in @appState.availableLanguages
+                    @appState.currentLanguage = browserLang
+        
+        loadDocumentForPath: (path) ->
+            try
+                @appState.loading = true
+                doc = await AppDB.getDocumentByPath(path, AppDB.currentLanguage)
+                @appState.currentDocument = doc
+                @appState.loading = false
+                
+                # Устанавливаем заголовок страницы
+                if doc?.title
+                    document.head.insertAdjacentHTML('beforeend', '<title>' + doc.title + '</title>')
+            catch error
+                @appState.error = "Ошибка загрузки документа: " + error
+                @appState.loading = false
+        
+    
+    render: (new Function '_ctx', '_cache', renderFns['app/app.pug'])()
+
+    
+    components: {
+        'hero-section': require('shared/HeroSection')
+        'image-gallery': require('shared/ImageGallery')
+    }
+# Создаем и настраиваем роутер
+router = VueRouter.createRouter({
+    routes: routes
+    history: VueRouter.createWebHistory()
+    scrollBehavior: (to, from, savedPosition) ->
+        if savedPosition
+            return savedPosition
+        else
+            return { x: 0, y: 0 }
+})
+
+app.use(router)
+app.mount('body')
+
+```
+
+// FILE: app/app.pug
+// TYPE: Pug Template
+// SIZE: 699 characters
+```pug
+include ../pug/base.pug
+include ../pug/bem.pug
+
+div(class="min-h-screen bg-white dark:bg-gray-900 transition-colors duration-300")
+    div(v-if="appState.loading" class="flex items-center justify-center min-h-screen")
+        div(class="text-center")
+            div(class="animate-spin rounded-full h-32 w-32 border-b-2 border-blue-600")
+            p(class="mt-4 text-gray-600 dark:text-gray-400") Загрузка...
+    
+    div(v-else-if="appState.error" class="flex items-center justify-center min-h-screen")
+        div(class="text-center")
+            div(class="text-red-600 text-xl") Ошибка
+            p(class="text-gray-600 dark:text-gray-400") {{ appState.error }}
+    
+    router-view(v-else)
+
+```
+
+// FILE: app/app.styl
+// TYPE: Stylus
+// SIZE: 1013 characters
+```stylus
+// Переменные темы
+:root 
+    --primary-color: #3b82f6
+    --secondary-color: #1e40af
+    --text-primary: #1f2937
+    --text-secondary: #6b7280
+    --bg-primary: #ffffff
+    --bg-secondary: #f9fafb
+
+[data-theme="dark"]
+    --primary-color: #60a5fa
+    --secondary-color: #3b82f6
+    --text-primary: #f9fafb
+    --text-secondary: #d1d5db
+    --bg-primary: #111827
+    --bg-secondary: #1f2937
+
+// Базовые стили
+body 
+    font-family: 'Inter', system-ui, -apple-system, sans-serif
+    color: var(--text-primary)
+    background-color: var(--bg-primary)
+    transition: all 0.3s ease
+
+// Стили для Markdown контента
+.prose 
+    h1, h2, h3, h4, h5, h6 
+        color: var(--text-primary)
+        font-weight: 600
+    
+    p 
+        color: var(--text-secondary)
+        line-height: 1.7
+    
+    a 
+        color: var(--primary-color)
+        text-decoration: none
+        &:hover 
+            text-decoration: underline
+    
+    img 
+        border-radius: 0.5rem
+        box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1)
+
+```
+
+// FILE: app/layout.pug
+// TYPE: Pug Template
+// SIZE: 324 characters
+```pug
+include ../pug/base.pug
+include ../pug/bem.pug
+
++mbh
+    header(class="sticky top-0 z-50 glass border-b border-neutral-300/60 transition-all duration-300")
+        div(class="navbar max-w-7xl mx-auto px-4 sm:px-6 lg:px-8")
+    block top-content
+    
++mbl(class="py-8 md:py-12 lg:py-16")
+    .container
+        block content
+
+```
+
+// FILE: app/pages/Home.coffee
+// TYPE: CoffeeScript
+// SIZE: 697 characters
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/pages/Home.styl">'+stylFns['app/pages/Home.styl']+'</style>'
+module.exports =
+    name: 'Home'
+    render: (new Function '_ctx', '_cache', renderFns['app/pages/Home.pug'])()
+    data: ->
+        return {
+            _: _
+            document: null
+        }
+    beforeMount: ->
+        try
+            @document = await AppDB.getDocumentByPath('/', AppDB.currentLanguage)
+        catch e
+            debug.log "Document load error:", e
+    components:
+        'app-link': require 'app/shared/AppLink'
+        'hero-section': require 'app/shared/HeroSection'
+        'image-gallery': require 'app/shared/ImageGallery'
+
+```
+
+// FILE: app/pages/Home.pug
+// TYPE: Pug Template
+// SIZE: 845 characters
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+extends ../layout.pug
+
+block top-content
+    hero-section(:document="document")
+
+block content
+    div(class="max-w-4xl mx-auto px-4" v-if="document")
+        h1(class="text-3xl font-bold text-contrast-high animate-fade-in-up") {{ document.translations[_.currentLanguage]?.title || document.translations.en.title }}
+        p(class="text-xl text-contrast-medium mb-8 animate-fade-in-up") {{ document.translations[_.currentLanguage]?.subtitle || document.translations.en.subtitle }}
+        div(class="prose mt-6 animate-fade-in-up" v-html="marked.parse(document.translations[_.currentLanguage]?.content || document.translations.en.content)")
+        div(class="mt-12")
+            image-gallery(:images="document.translations[_.currentLanguage]?.gallery || document.translations.en.gallery")
+
+```
+
+// FILE: app/pages/Home.styl
+// TYPE: Stylus
+// SIZE: 281 characters
+```stylus
+// Используем только утилиты из DesignTokens
+.animate-fade-in-up
+    animation: fadeInUp var(--transition-slow) ease-out
+
+@keyframes fadeInUp
+    from
+        opacity: 0
+        transform: translateY(var(--transition-px))
+    to
+        opacity: 1
+        transform: translateY(0)
+
+```
+
+// FILE: app/shared/AppLink.coffee
+// TYPE: CoffeeScript
+// SIZE: 633 characters
+```coffeescript
+document.head.insertAdjacentHTML('beforeend','<style type="text/css" file="app/shared/AppLink.styl">'+stylFns['app/shared/AppLink.styl']+'</style>')
+module.exports =
+    default:
+        render: (new Function '_ctx', '_cache', renderFns['app/shared/AppLink.pug'])()
+        name: 'AppLink'
+        props:
+            to:
+                type: [String, Object]
+                required: true
+        computed:
+            isExternal: ->
+                if typeof @.to == 'string'
+                    return @.to.startsWith('http')
+                return false
+        data: -> 
+            return {
+                _: _
+            }
+
+```
+
+// FILE: app/shared/AppLink.pug
+// TYPE: Pug Template
+// SIZE: 214 characters
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+
+a.app-link(v-if="isExternal" v-bind="$attrs" :href="to" target="_blank" rel="noopener")
+    slot
+router-link.app-link(v-else v-bind="$attrs" :to="to")
+    slot
+
+```
+
+// FILE: app/shared/AppLink.styl
+// TYPE: Stylus
+// SIZE: 1264 characters
+```stylus
+@import '../DesignTokens.styl'
+
+// Базовые стили для AppLink компонента
+.app-link 
+    color: var(--primary-color)
+    text-decoration: none
+    transition: color var(--transition-fast)
+
+.app-link:hover 
+    color: var(--primary-dark)
+    text-decoration: underline
+
+.app-link.router-link-active 
+    font-weight: var(--font-semibold)
+    color: var(--primary-dark)
+
+// Стили для внешних ссылок
+.app-link-external::after 
+    content: " ↗"
+    font-size: 0.875em
+    opacity: 0.7
+
+// Стили для кнопко-подобных ссылок
+.app-link-button 
+    display: inline-flex
+    align-items: center
+    gap: var(--space-2)
+    padding: var(--space-2) var(--space-4)
+    background: var(--primary-color)
+    color: white
+    border-radius: 6px
+    font-weight: var(--font-medium)
+    transition: all var(--transition-fast)
+
+.app-link-button:hover 
+    background: var(--primary-dark)
+    transform: translateY(-1px)
+    text-decoration: none
+    color: white
+    box-shadow: var(--shadow-md)
+
+// Стили для иконок в ссылках
+.app-link-with-icon 
+    display: inline-flex
+    align-items: center
+    gap: var(--space-2)
+
+.app-link-icon 
+    width: 16px
+    height: 16px
+    transition: transform var(--transition-fast)
+
+.app-link:hover .app-link-icon 
+    transform: translateX(2px)
+
+```
+
+// FILE: app/shared/HeroSection.coffee
+// TYPE: CoffeeScript
+// SIZE: 311 characters
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/shared/HeroSection.styl">'+stylFns['app/shared/HeroSection.styl']+'</style>'
+module.exports =
+    name: 'HeroSection'
+    props: [ 'document' ]
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/HeroSection.pug'])()
+
+```
+
+// FILE: app/shared/HeroSection.pug
+// TYPE: Pug Template
+// SIZE: 574 characters
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+section(v-if="document" class="hero-section bg-gradient")
+    div(class="max-w-7xl mx-auto px-4 py-24 text-center text-white")
+        h1(v-if="document.translations[_.appState.currentLanguage]" class="text-5xl font-bold mb-6") {{ document.translations[_.appState.currentLanguage].title || document.translations.en.title }}
+        p(v-if="document.translations[_.appState.currentLanguage]" class="text-xl opacity-90") {{ document.translations[_.appState.currentLanguage].subtitle || document.translations.en.subtitle }}
+
+```
+
+// FILE: app/shared/HeroSection.styl
+// TYPE: Stylus
+// SIZE: 125 characters
+```stylus
+.hero-section
+    background: var(--gradient-primary)
+    color: white
+    padding: var(--space-16) 0
+    text-align: center
+
+```
+
+// FILE: app/shared/ImageGallery.coffee
+// TYPE: CoffeeScript
+// SIZE: 367 characters
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/shared/ImageGallery.styl">'+stylFns['app/shared/ImageGallery.styl']+'</style>'
+module.exports =
+    name: 'ImageGallery'
+    props:
+        images:
+            type: Array
+            default: -> []
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/ImageGallery.pug'])()
+
+```
+
+// FILE: app/shared/ImageGallery.pug
+// TYPE: Pug Template
+// SIZE: 414 characters
+```pug
+include ../../pug/base.pug
+include ../../pug/bem.pug
+div(v-if="images && images.length > 0" class="image-gallery grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6")
+    div(v-for="(img, idx) in images" :key="idx" class="overflow-hidden rounded-lg shadow-custom-md bg-surface")
+        img(:src="img.src" :alt="img.alt || ''" class="w-full h-auto object-cover transition-transform duration-300 hover:scale-105")
+
+```
+
+// FILE: app/shared/ImageGallery.styl
+// TYPE: Stylus
+// SIZE: 324 characters
+```stylus
+.image-gallery
+    display: grid
+    gap: var(--space-6)
+    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))
+
+.image-gallery img
+    width: 100%
+    height: auto
+    object-fit: cover
+    border-radius: 8px
+    transition: transform var(--transition-normal)
+
+.image-gallery img:hover
+    transform: scale(1.05)
+
+```
+
+// FILE: app/utils/AppDB.coffee
+// TYPE: CoffeeScript
+// SIZE: 4684 characters
+```coffeescript
+# FILE: app/utils/AppDB.coffee
+class AppDB
+    currentLanguage: 'ru'
+    currentProject: 's5l.ru'
+    designDocVersion: '1.1' # управление версией дизайна
+
+    constructor: ->
+        @localDB = new PouchDB('s5l_local')
+        @remoteDB = new PouchDB('https://oleg:631074@couchdb.favt.ru.net/s5lru/')
+        @syncHandler = null
+
+    init: ->
+        try
+            await @remoteDB.info()
+            debug.log "Remote DB connected"
+            await @ensureDesignDocs()
+            await @ensureDefaultContent()
+            @startSync()
+            AppDB.currentLanguage = globalThis._?.appState?.currentLanguage or 'ru'
+        catch e
+            debug.log "DB init failed:", e
+
+    startSync: ->
+        @syncHandler = @localDB.sync(@remoteDB, { live: true, retry: true })
+            .on 'error', (err) -> debug.log "Sync error:", err
+
+    ensureDesignDocs: ->
+        adminDoc =
+            _id: '_design/admin'
+            version: @designDocVersion
+            views:
+                byPath:
+                    map: (doc) ->
+                        if doc.type == 'page'
+                            emit [doc.domain, doc.path], doc
+                    .toString()
+                byType:
+                    map: (doc) ->
+                        emit doc.type, doc
+                    .toString()
+
+        try
+            existing = await @remoteDB.get('_design/admin')
+            if existing.version != @designDocVersion
+                adminDoc._rev = existing._rev
+                await @remoteDB.put(adminDoc)
+                debug.log "Design doc updated to v#{@designDocVersion}"
+        catch
+            await @remoteDB.put(adminDoc)
+            debug.log "Design doc created v#{@designDocVersion}"
+
+    ensureDefaultContent: ->
+        defaultHome =
+            _id: 'page::s5l.ru::/'
+            type: 'page'
+            domain: 's5l.ru'
+            path: '/'
+            translations:
+                ru:
+                    title: "s5l.ru — мультиязычная offline-first платформа"
+                    subtitle: "Разрабатывайте быстро, работайте везде"
+                    content: '''
+# Добро пожаловать на s5l.ru
+
+**s5l.ru** — это платформа для быстрого запуска веб-проектов с поддержкой:
+- offline-first через PouchDB/CouchDB
+- автоматического переключения языка
+- динамической подгрузки контента
+- полной WCAG 2.2-совместимости
+
+Все тексты хранятся в базе и легко редактируются через админку.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+                en:
+                    title: "s5l.ru — multilingual offline-first platform"
+                    subtitle: "Build fast, work anywhere"
+                    content: '''
+# Welcome to s5l.ru
+
+**s5l.ru** is a platform for rapid web project launches with:
+- offline-first via PouchDB/CouchDB
+- automatic language switching
+- dynamic content loading
+- full WCAG 2.2 compliance
+
+All text is stored in the database and editable via admin panel.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+                tj:
+                    title: "s5l.ru — платформаи бисёрзабон ва аввал офлайн"
+                    subtitle: "Бисёр тез бунёд кунед, дар ҳама ҷо кор кунед"
+                    content: '''
+# Ба s5l.ru хуш омадед
+
+**s5l.ru** — ин платформа барои оғози тези лоиҳаҳои веб аст бо:
+- офлайн-аввал аз рӯи PouchDB/CouchDB
+- ивази худкори забон
+- боркунии динамикӣ
+- мутобиқати пурраи WCAG 2.2
+
+Ҳамаи матнҳо дар база нигоҳ дошта мешаванд ва аз ҷониби панели маъмури озодона таҳрир карда мешаванд.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+
+        try
+            await @remoteDB.get('page::s5l.ru::/')
+        catch
+            await @remoteDB.put(defaultHome)
+            debug.log "Default home page created"
+
+    getDocumentByPath: (path, lang = @currentLanguage) ->
+        path = path or '/'
+        try
+            result = await @localDB.query('admin/byPath', { key: [@currentProject, path], include_docs: true })
+            if result.rows.length > 0
+                doc = result.rows[0].doc
+                return doc
+            else
+                throw new Error "Document not found"
+        catch e
+            debug.log "Fallback for path:", path, "lang:", lang
+            # fallback to English if not found
+            if lang != 'en'
+                return await @getDocumentByPath(path, 'en')
+            else
+                throw new Error "Document not available even in English"
+
+module.exports = AppDB
+
+```
+
+// FILE: doc.coffee
+// TYPE: CoffeeScript
+// SIZE: 1285 characters
+```coffeescript
+module.exports = 
+     version: "0.0.1"
+     adres: [
+        {
+          "adr": "https://cdn.tailwindcss.com/3.4.17"
+          "eventName": "tailwindReady"
+          "obj": "tailwind"
+        }
+        {
+          "adr": "https://unpkg.com/pouchdb/dist/pouchdb.min.js"
+          "eventName": "puochReady"
+          "obj": "PouchDB"
+        }
+        {
+          "adr": "https://unpkg.com/vue@3/dist/vue.runtime.global.prod.js"
+          "eventName": "vueReady"
+          "obj": "Vue"
+        }
+        {
+          "adr": "https://unpkg.com/vue-router@4/dist/vue-router.global.js"
+          "eventName": "VueRouterReady"
+          "obj": "VueRouter"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/@vue/compiler-sfc@3.5.22/dist/compiler-sfc.esm-browser.min.js"
+          "eventName": "compileTemplateReady"
+          "obj": "compileTemplate"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/marked@16.4.1/lib/marked.umd.min.js"
+          "eventName": "markedReady"
+          "obj": "marked"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/openlayers@4.6.5/dist/ol.min.js"
+          "css": "https://cdn.jsdelivr.net/npm/openlayers@4.6.5/dist/ol.min.css"
+          "eventName": "leafletReady"
+          "obj": "ol"
+        }
+    ]
+
+```
+
+// FILE: lzma.coffee
+// TYPE: CoffeeScript
+// SIZE: 1010 characters
+```coffeescript
+globalThis.debug = require('debug.coffee').default
+require('headVue.coffee')
+
+
+document.documentElement.classList.add('dark')
+
+globalThis.initCount = 0
+ic = ()->
+    if initCount > 5
+       window.location.reload()
+    else if  not globalThis['appReady']
+       initCount++
+       #setTimeout ic, 200
+ic()
+# обязательно подключение глобальных массивов
+globalThis.renderFns = require 'pug.json'
+globalThis.stylFns   = require 'styl.json'
+
+try
+    init =  (event={})->
+        debug.dir   globalThis['vueReady']
+        debug.log "Init Start"
+        if  not globalThis['appReady'] and globalThis['vueReady'] and globalThis['puochReady']
+            debug.log 'init start ok'
+            try
+                require('app/app.coffee')
+                globalThis['appReady'] = true
+                debug.log "init is ok"
+            catch err
+                debug.dir err
+        else if  not globalThis['appReady']
+                debug.log 'pausedEvent appReady'
+                setTimeout init, 200
+    init()
+
+```
+
+// FILE: pug/base.pug
+// TYPE: Pug Template
+// SIZE: 504 characters
+```pug
+include ./bem.pug
+
+
+mixin mbh
+    - var otherClasses = attributes.class || ''
+    +b('hfn')(class="h-max overflow-hidden relative")
+        +e('hfn','fon')
+
+mixin mbl
+    - var otherClasses = attributes.class || ''
+    +b('hfn')(class="h-max overflow-hidden relative")
+        +e('hfn','fon')(class="[background:url('https://jahonnamo.s5l.ru/assets/jahonnamo.s5l.ru/bkg00.webp')_0_0_/_cover_no-repeat] bg-[#ffffff] absolute h-full w-full z-[-1]")
+                  if block
+                        block
+
+```
+
+// FILE: pug/bem.pug
+// TYPE: Pug Template
+// SIZE: 1035 characters
+```pug
+//- bem.pug
+
+//- Базовый миксин для блоков и элементов
+mixin b(blockName, elemName)
+  - var className = blockName
+  - var twClasses = attributes.tw || ''
+  - var otherClasses = attributes.class || ''
+
+  if elemName
+    - className += '__' + elemName
+
+  //- Обработка модификаторов
+  if attributes.mod
+    - className += ' ' + blockName + '--' + attributes.mod
+  if attributes.mods
+    each mod in attributes.mods.split(',')
+      - className += ' ' + blockName + '--' + mod.trim()
+
+  //- Собираем финальный класс
+  - var finalClass = [className, twClasses, otherClasses].filter(Boolean).join(' ')
+
+  //- Удаляем обработанные атрибуты
+  - attributes.tw = null
+  - attributes.mod = null
+  - attributes.mods = null
+  - attributes.class = null
+
+  //- Генерация элемента
+  if block
+    div(class=finalClass)&attributes(attributes)
+      block
+  else
+    div(class=finalClass)&attributes(attributes)
+
+//- Миксин для элементов (альтернативный синтаксис)
+mixin e(blockName, elemName)
+  +b(blockName, elemName)&attributes(attributes)
+    block
+
+```

+ 36 - 0
PROJECT_FILE_LIST.txt

@@ -0,0 +1,36 @@
+# PROJECT FILE LIST
+# Generated: 2025-11-05T09:26:28.251Z
+
+## Markdown (1 files)
+- README.md (7142 chars)
+
+## Stylus (6 files)
+- app/app.styl (1013 chars)
+- app/DesignTokens.styl (5908 chars)
+- app/pages/Home.styl (281 chars)
+- app/shared/AppLink.styl (1264 chars)
+- app/shared/HeroSection.styl (125 chars)
+- app/shared/ImageGallery.styl (324 chars)
+
+## Unknown (1 files)
+- .gitignore (29 chars)
+
+## CoffeeScript (8 files)
+- app/app.coffee (3584 chars)
+- app/pages/Home.coffee (697 chars)
+- app/shared/AppLink.coffee (633 chars)
+- app/shared/HeroSection.coffee (311 chars)
+- app/shared/ImageGallery.coffee (367 chars)
+- app/utils/AppDB.coffee (4684 chars)
+- doc.coffee (1285 chars)
+- lzma.coffee (1010 chars)
+
+## Pug Template (8 files)
+- app/app.pug (699 chars)
+- app/layout.pug (324 chars)
+- app/pages/Home.pug (845 chars)
+- app/shared/AppLink.pug (214 chars)
+- app/shared/HeroSection.pug (574 chars)
+- app/shared/ImageGallery.pug (414 chars)
+- pug/base.pug (504 chars)
+- pug/bem.pug (1035 chars)

+ 205 - 0
README.md

@@ -0,0 +1,205 @@
+# Текущее задание (Выполнить)
+
+## Общее задание:
+Разработать веб-приложение [название], используя платформу **s5l.ru**
+
+### Дизайн:
+- Темы: темная по умолчанию, переключаемая на светлую через `[data-theme="light"]`
+- Цветовая палитра из `DesignTokens.styl`
+- Atomic Design + User-Centered подход
+- Полная поддержка WCAG 2.2 (контраст ≥ 4.5:1)
+
+### Функциональность:
+- Автоматическое определение языка (URL → браузер)
+- Динамическая подгрузка контента из CouchDB с локальной репликацией через PouchDB
+- Offline-first: работа без интернета после первого визита
+- Единая система стилей через CSS-переменные и Tailwind
+
+## Текущее действие:
+
+Сделай первый этап разработки, включающий файлы app/pages/home* и `app/utils/AppDB.coffee` — полная реализация с методами `getDocumentByPath`
+с проверкой наличия там документа, с начтройками саййта, если его нет создать документ по умолчанию при инициализации AppDB
+
+
+Опиши следущие для разработки файлы.
+
+---
+
+# Промт для разработки на платформе s5l.ru
+
+Ты — Senior Fullstack-архитектор и UI/UX-прагматик. Твоя задача — разрабатывать новые проекты, строго следуя логике и структуре платформы `s5l.ru`.
+
+## Стек (НЕИЗМЕНЕН)
+- **Frontend**: Vue 3 (Composition API через `render` функции), CoffeeScript, Pug, Stylus, Tailwind CSS, svg, webp, webm, peerjs, websocket, webtorrent
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы, админка)  
+- **Сборка**: все шаблоны → `pug.json`, стили → `styl.json`  
+- **Именование классов**: используй методику BEM
+- **Глобальный контекст**: `globalThis._` — ссылка на корневой Vue-экземпляр из `app/app.coffee`
+
+# Проект: s5l.ru
+
+## Общее описание
+`s5l.ru` — это **мультиязычная платформа для быстрого старта проектов** с поддержкой:
+- offline-first через **PouchDB/CouchDB**
+- автоматического определения языка (из URL → браузер)
+- динамической подгрузки контента
+- темной/светлой темы (`[data-theme="dark/light"]`)
+- WCAG 2.2 (контраст ≥ 4.5:1)
+
+## Стек
+- **Frontend**: Vue 3 (render-функции), CoffeeScript, Pug, Stylus, Tailwind CSS
+- **Backend**: CouchDB + PouchDB (репликация, дизайн-документы)
+- **Сборка**: `pug.json`, `styl.json`
+
+## Запуск нового проекта
+1. Создать дизайн-документы в CouchDB
+2. Положить стартовые документы с `type: 'page'`, `path: '/'`, и `translations`
+3. Использовать `AppDB.getDocumentByPath` в `beforeMount`
+4. Стили — только через CSS-переменные из `DesignTokens.styl`
+
+## Доступность
+- Поддержка тем: `:root` → `[data-theme="light"]`
+- Контраст ≥ 4.5:1
+- Анимации ≤ 500 мс
+- Mobile-first верстка
+
+
+## Архитектура
+- Все тексты хранятся в **CouchDB** с поддержкой мультиязычности и мультидоменности
+- Вся логика работы с БД — через `AppDB`
+- Все компоненты — по **Atomic Design**, стили — через `DesignTokens.styl`
+
+## Структура проекта
+```
+app/
+├── assets/           # Системные изображения, пиктограммы
+├── app.coffee        # инициализация Vue, AppDB, глобальный _ 
+├── app.pug           # Основной шаблон с Хедером, <router-view>, Футером
+├── app.styl          # Глобальные стили
+├── DesignTokens.styl # дизайн-система
+├── utils/
+|    └── AppDB.coffee # доступ к данным
+├── pages/            # Страницы проекта
+|    ├── Home.coffee
+|    ├── Home.pug
+|    └── Home.styl
+└── shared/
+     ├── AppLink.*     # компонент ссылок
+     └── ...
+```
+
+## Правила
+
+### 1. Vue-компоненты
+- **Имя файла**: PascalCase (`NewsList.coffee`, `NewsList.pug`, `NewsList.styl`)  
+- **Экспорт**: `module.exports = { name: '...', render: ..., data: -> {}, ... }`  
+- **Стили**: подключать через  
+  ```coffee
+  document.head.insertAdjacentHTML 'beforeend', '<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+  ```
+- **Шаблон**: рендерить через  
+  ```coffee
+  render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+  ```
+- **Жизненный цикл**:  
+  ❌ НЕПРАВИЛЬНО:  
+  ```coffeescript
+  async beforeMount: ->
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```coffeescript
+  beforeMount: ->
+  ```  
+  *(асинхронность обрабатывается внутри метода через `await`, но сигнатура — без `async`)*
+
+### 2. Роутинг
+- Все маршруты — в `temp.coffee` → `VueRouter.createRouter({ routes: [...] })`  
+- Компонент страницы должен быть `require`'нут без `.default` только если не экспортирует как `default`
+
+### 3. Ссылки
+- **ЗАПРЕЩЕНО**: `a(href="...")`, `router-link(to="...")`  
+- **ТОЛЬКО**: `app-link(to="...")` с подключением компонента `'app-link': require 'app/shared/AppLink'`
+
+### 4. Стили
+- **Цвета, отступы, шрифты** — ТОЛЬКО из `DesignTokens.styl` через CSS-переменные (`var(--primary-color)`, `var(--space-4)`)  
+- **Tailwind**: не использовать `@apply`  
+- **Stylus**: не использовать `@import '../DesignTokens.styl'` — он уже подключен глобально
+
+### 5. Pug
+- Атрибуты в одной строке, без многострочных выражений  
+- Внешние данные — только через `data` или `computed`  
+- **Tailwind-классы** — только внутри `class=""`, **не через точечную нотацию**  
+  ❌ НЕПРАВИЛЬНО:  
+  ```pug
+  .max-w-4xl.mx-auto.px-4
+  ```  
+  ✅ ПРАВИЛЬНО:  
+  ```pug
+  div(class="max-w-4xl mx-auto px-4")
+  ```  
+- Пример правильно:
+  ```pug
+  div(v-for="item in items" :key="item.id")
+  div(:class="isActive ? 'active' : 'inactive'" class="w-full")
+  ```
+
+### 6. CoffeeScript
+- Отступы: 4 пробела  
+- `->` для методов, `=>` — только при необходимости сохранения `this`  
+- `debug.log "сообщение"` вместо `console.log`  
+- Строки: `"строка="+переменная`, без интерполяции
+
+### 7. CouchDB
+- Все запросы — через `AppDB`, который надо разработать под проект и подключить глобально в `app/app.coffee`
+- Дизайн-документы: создавать функции `.toString()`
+
+### 8. Доступность и дизайн
+- WCAG 2.2 (контраст ≥ 4.5:1)  
+- Mobile-first  
+- Atomic Design + User-Centered подход  
+- Анимации: 200–500 мс, плавные переходы
+
+## Обязательное требование
+> **ВСЕГДА прикладывай полные листинги всех файлов** — даже если изменения минимальны. Частичные или сокращённые фрагменты недопустимы. Каждый файл должен быть представлен целиком, как он будет сохранён на диске.
+
+## Шаблон компонента (полный пример)
+**Файл**: `app/shared/NewsList.coffee`
+```coffeescript
+document.head.insertAdjacentHTML 'beforeend','<style type="text/tailwindcss">'+stylFns['app/shared/NewsList.styl']+'</style>'
+module.exports =
+    name: 'NewsList'
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/NewsList.pug'])()
+    data: ->
+        return {
+            _: _
+            posts: []
+        }
+    beforeMount: ->
+        @posts = await AppDB.getPublishedPosts(limit: 10)
+    components:
+        'app-link': require 'app/shared/AppLink'
+```
+
+**Файл**: `app/shared/NewsList.pug`
+```pug
+div(class="space-y-4")
+    app-link(v-for="post in posts" :key="post.id" :to="'/pages/'+post.id")
+        h3(class="text-xl") {{ post.doc.h }}
+```
+
+**Файл**: `app/shared/NewsList.styl`
+```stylus
+// Только стили компонента. DesignTokens — через var()
+.news-item
+    padding: var(--space-4)
+    border-bottom: var(--border-1) solid var(--neutral-300)
+```
+
+## Запрещено
+- React, TypeScript, MongoDB, SASS, Webpack, Vite  
+- Любые отклонения от стиля кода в `DEVELOPMENT.md`  
+- Использование `Vue = require 'vue'` — всё глобально
+
+Следуй этому промту для всех новых проектов.
+
+---

+ 5 - 0
WORKFILES

@@ -0,0 +1,5 @@
+# WORKFILES - Current Active Development Files
+# Files listed here will be prioritized in AI prompts and analysis
+# Format: one file path per line, comments start with #
+
+

+ 232 - 0
app/DesignTokens.styl

@@ -0,0 +1,232 @@
+:root 
+    // Цветовая система для темной темы по умолчанию
+    --primary-color: #f87171
+    --primary-dark: #ef4444
+    --primary-light: #fca5a5
+
+    --secondary-color: #1e293b
+    --secondary-dark: #0f172a
+    --secondary-light: #334155
+
+    --accent-color: #22d3ee
+    --accent-dark: #06b6d4
+    --accent-light: #67e8f9
+
+    // Нейтральные цвета для темной темы
+    --neutral-50: #0f172a
+    --neutral-100: #1e293b
+    --neutral-200: #334155
+    --neutral-300: #475569
+    --neutral-400: #64748b
+    --neutral-500: #94a3b8
+    --neutral-600: #cbd5e1
+    --neutral-700: #e2e8f0
+    --neutral-800: #f1f5f9
+    --neutral-900: #f8fafc
+
+    // Цвета текста для темной темы
+    --text-primary: #f8fafc
+    --text-secondary: #e2e8f0
+    --text-muted: #94a3b8
+
+    // Цвета фона для темной темы
+    --bg-primary: #0f172a
+    --bg-secondary: #1e293b
+    --bg-card: #1e293b
+    --bg-overlay: rgba(15, 23, 42, 0.8)
+
+    // Градиенты для темной темы
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--secondary-dark) 0%, var(--secondary-color) 100%)
+
+    // Типографическая система
+    --font-family-sans: 'Inter', 'Segoe UI', system-ui, sans-serif
+    --font-family-serif: 'Georgia', 'Times New Roman', serif
+
+    --text-xs: 0.75rem
+    --text-sm: 0.875rem
+    --text-base: 1rem
+    --text-lg: 1.125rem
+    --text-xl: 1.25rem
+    --text-2xl: 1.5rem
+    --text-3xl: 1.875rem
+    --text-4xl: 2.25rem
+    --text-5xl: 3rem
+
+    --font-light: 300
+    --font-normal: 400
+    --font-medium: 500
+    --font-semibold: 600
+    --font-bold: 700
+
+    // Spacing system
+    --space-1: 0.25rem
+    --space-2: 0.5rem
+    --space-3: 0.75rem
+    --space-4: 1rem
+    --space-5: 1.25rem
+    --space-6: 1.5rem
+    --space-8: 2rem
+    --space-10: 2.5rem
+    --space-12: 3rem
+    --space-16: 4rem
+    --space-20: 5rem
+
+    // Тени и эффекты для темной темы
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.6), 0 2px 4px -1px rgba(0, 0, 0, 0.4)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.7), 0 4px 6px -2px rgba(0, 0, 0, 0.5)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.8), 0 10px 10px -5px rgba(0, 0, 0, 0.6)
+
+    // Анимации
+    --transition-fast: 0.15s ease-in-out
+    --transition-normal: 0.3s ease-in-out
+    --transition-slow: 0.5s ease-in-out
+
+    // Breakpoints
+    --breakpoint-sm: 640px
+    --breakpoint-md: 768px
+    --breakpoint-lg: 1024px
+    --breakpoint-xl: 1280px
+    --breakpoint-2xl: 1536px
+
+// Светлая тема
+[data-theme="light"] 
+    --primary-color: #e11d48
+    --primary-dark: #be123c
+    --primary-light: #fb7185
+
+    --secondary-color: #f8fafc
+    --secondary-dark: #f1f5f9
+    --secondary-light: #ffffff
+
+    --accent-color: #06b6d4
+    --accent-dark: #0891b2
+    --accent-light: #22d3ee
+
+    --neutral-50: #f8fafc
+    --neutral-100: #f1f5f9
+    --neutral-200: #e2e8f0
+    --neutral-300: #cbd5e1
+    --neutral-400: #94a3b8
+    --neutral-500: #64748b
+    --neutral-600: #475569
+    --neutral-700: #334155
+    --neutral-800: #1e293b
+    --neutral-900: #0f172a
+
+    --text-primary: #0f172a
+    --text-secondary: #334155
+    --text-muted: #64748b
+
+    --bg-primary: #ffffff
+    --bg-secondary: #f8fafc
+    --bg-card: #ffffff
+    --bg-overlay: rgba(255, 255, 255, 0.8)
+
+    --gradient-primary: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 50%, var(--accent-color) 100%)
+    --gradient-dark: linear-gradient(135deg, var(--neutral-100) 0%, var(--neutral-50) 100%)
+
+    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05)
+    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)
+    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)
+    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)
+
+// Утилитарные классы для кастомных свойств
+.bg-primary 
+    background-color: var(--primary-color)
+
+.text-primary 
+    color: var(--primary-color)
+
+.border-primary 
+    border-color: var(--primary-color)
+
+.bg-accent 
+    background-color: var(--accent-color)
+
+.text-accent 
+    color: var(--accent-color)
+
+.bg-neutral 
+    background-color: var(--neutral-500)
+
+.text-neutral 
+    color: var(--neutral-500)
+
+.bg-dark 
+    background-color: var(--bg-primary)
+
+.text-dark 
+    color: var(--text-primary)
+
+.bg-card 
+    background-color: var(--bg-card)
+
+.text-card 
+    color: var(--text-primary)
+
+// Анимации
+.transition-fast 
+    transition: var(--transition-fast)
+
+.transition-normal 
+    transition: var(--transition-normal)
+
+.transition-slow 
+    transition: var(--transition-slow)
+
+// Тени
+.shadow-custom-sm 
+    box-shadow: var(--shadow-sm)
+
+.shadow-custom-md 
+    box-shadow: var(--shadow-md)
+
+.shadow-custom-lg 
+    box-shadow: var(--shadow-lg)
+
+.shadow-custom-xl 
+    box-shadow: var(--shadow-xl)
+// Добавляем дополнительные утилитарные классы для лучшей поддержки компонентов
+.card-primary 
+    background-color: var(--bg-card)
+    border: 1px solid var(--neutral-300)
+    border-radius: 8px
+    box-shadow: var(--shadow-sm)
+    transition: all var(--transition-normal)
+
+.card-primary:hover 
+    border-color: var(--primary-color)
+    box-shadow: var(--shadow-md)
+
+.text-icon 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .text-icon 
+    filter: brightness(0) invert(1)
+
+.icon-primary 
+    filter: brightness(0) invert(0)
+    transition: filter var(--transition-fast)
+
+[data-theme="dark"] .icon-primary 
+    filter: brightness(0) invert(1)
+
+// Утилиты для контрастного текста
+.text-contrast-high 
+    color: var(--text-primary)
+
+.text-contrast-medium 
+    color: var(--text-secondary)
+
+.text-contrast-low 
+    color: var(--text-muted)
+
+// Утилиты для фонов
+.bg-surface 
+    background-color: var(--bg-card)
+
+.bg-surface-alt 
+    background-color: var(--bg-secondary)

+ 100 - 0
app/app.coffee

@@ -0,0 +1,100 @@
+# Подключение мета информации
+document.head.insertAdjacentHTML 'beforeend', '<meta charset="UTF-8">'
+document.head.insertAdjacentHTML 'beforeend', '<meta name="viewport" content="width=device-width, initial-scale=1.0">'
+
+# Настройка tailwind
+#tailwind.config = require 'tailwind.config.js'
+
+# Подключение основных стилей
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="main.css">' + stylFns['main.css'] + '</style>')
+
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="app/DesignTokens.styl">' + stylFns['app/DesignTokens.styl'] + '</style>')
+document.head.insertAdjacentHTML('beforeend', '<style type="text/tailwindcss" file="app/app.styl">' + stylFns['app/app.styl'] + '</style>')
+
+
+
+# Маршруты
+routes = [
+    { path: '/', component: require 'app/pages/Home' }
+    { path: '/:path*', component: require 'app/pages/DocumentPage' }
+]
+globalThis._ = {}
+# Глобальное определение vuejs приложения
+globalThis.app = Vue.createApp
+    name: 'app'
+    data: () ->
+        return {
+            appState:
+                currentDocument: null
+                currentLanguage: 'ru'
+                availableLanguages: ['ru', 'en', 'tj']
+                loading: true
+                error: null
+            dbService: new (require('app/core/DB'))()
+        }
+    
+    beforeMount: ->
+        globalThis.AppDB = new (require 'app/utils/AppDB')()
+        await globalThis.AppDB.init()
+        globalThis._ = @
+    computed:
+        currentLanguage: ->
+            @appState.currentLanguage
+    watch:
+        currentLanguage:
+            handler: (newDoc) ->
+                debug.dir newDoc
+                @loadDocumentForPath(window.location.pathname)
+            immediate: true
+    methods:
+        initializeApp: ->
+            # Определяем язык из URL или браузера
+            @detectLanguage()
+            # Загружаем документ для текущего пути
+            @loadDocumentForPath(window.location.pathname)
+        
+        detectLanguage: ->
+            # Простая логика определения языка
+            pathLang = window.location.pathname.split('/')[1]
+            if pathLang in @appState.availableLanguages
+                @appState.currentLanguage = pathLang
+            else
+                browserLang = navigator.language.split('-')[0]
+                if browserLang in @appState.availableLanguages
+                    @appState.currentLanguage = browserLang
+        
+        loadDocumentForPath: (path) ->
+            try
+                @appState.loading = true
+                doc = await AppDB.getDocumentByPath(path, AppDB.currentLanguage)
+                @appState.currentDocument = doc
+                @appState.loading = false
+                
+                # Устанавливаем заголовок страницы
+                if doc?.title
+                    document.head.insertAdjacentHTML('beforeend', '<title>' + doc.title + '</title>')
+            catch error
+                @appState.error = "Ошибка загрузки документа: " + error
+                @appState.loading = false
+        
+    
+    render: (new Function '_ctx', '_cache', renderFns['app/app.pug'])()
+
+    
+    components: {
+        'hero-section': require('shared/HeroSection')
+        'image-gallery': require('shared/ImageGallery')
+    }
+# Создаем и настраиваем роутер
+router = VueRouter.createRouter({
+    routes: routes
+    history: VueRouter.createWebHistory()
+    scrollBehavior: (to, from, savedPosition) ->
+        if savedPosition
+            return savedPosition
+        else
+            return { x: 0, y: 0 }
+})
+
+app.use(router)
+app.mount('body')

+ 15 - 0
app/app.pug

@@ -0,0 +1,15 @@
+include ../pug/base.pug
+include ../pug/bem.pug
+
+div(class="min-h-screen bg-white dark:bg-gray-900 transition-colors duration-300")
+    div(v-if="appState.loading" class="flex items-center justify-center min-h-screen")
+        div(class="text-center")
+            div(class="animate-spin rounded-full h-32 w-32 border-b-2 border-blue-600")
+            p(class="mt-4 text-gray-600 dark:text-gray-400") Загрузка...
+    
+    div(v-else-if="appState.error" class="flex items-center justify-center min-h-screen")
+        div(class="text-center")
+            div(class="text-red-600 text-xl") Ошибка
+            p(class="text-gray-600 dark:text-gray-400") {{ appState.error }}
+    
+    router-view(v-else)

+ 43 - 0
app/app.styl

@@ -0,0 +1,43 @@
+// Переменные темы
+:root 
+    --primary-color: #3b82f6
+    --secondary-color: #1e40af
+    --text-primary: #1f2937
+    --text-secondary: #6b7280
+    --bg-primary: #ffffff
+    --bg-secondary: #f9fafb
+
+[data-theme="dark"]
+    --primary-color: #60a5fa
+    --secondary-color: #3b82f6
+    --text-primary: #f9fafb
+    --text-secondary: #d1d5db
+    --bg-primary: #111827
+    --bg-secondary: #1f2937
+
+// Базовые стили
+body 
+    font-family: 'Inter', system-ui, -apple-system, sans-serif
+    color: var(--text-primary)
+    background-color: var(--bg-primary)
+    transition: all 0.3s ease
+
+// Стили для Markdown контента
+.prose 
+    h1, h2, h3, h4, h5, h6 
+        color: var(--text-primary)
+        font-weight: 600
+    
+    p 
+        color: var(--text-secondary)
+        line-height: 1.7
+    
+    a 
+        color: var(--primary-color)
+        text-decoration: none
+        &:hover 
+            text-decoration: underline
+    
+    img 
+        border-radius: 0.5rem
+        box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1)

+ 11 - 0
app/layout.pug

@@ -0,0 +1,11 @@
+include ../pug/base.pug
+include ../pug/bem.pug
+
++mbh
+    header(class="sticky top-0 z-50 glass border-b border-neutral-300/60 transition-all duration-300")
+        div(class="navbar max-w-7xl mx-auto px-4 sm:px-6 lg:px-8")
+    block top-content
+    
++mbl(class="py-8 md:py-12 lg:py-16")
+    .container
+        block content

+ 18 - 0
app/pages/Home.coffee

@@ -0,0 +1,18 @@
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/pages/Home.styl">'+stylFns['app/pages/Home.styl']+'</style>'
+module.exports =
+    name: 'Home'
+    render: (new Function '_ctx', '_cache', renderFns['app/pages/Home.pug'])()
+    data: ->
+        return {
+            _: _
+            document: null
+        }
+    beforeMount: ->
+        try
+            @document = await AppDB.getDocumentByPath('/', AppDB.currentLanguage)
+        catch e
+            debug.log "Document load error:", e
+    components:
+        'app-link': require 'app/shared/AppLink'
+        'hero-section': require 'app/shared/HeroSection'
+        'image-gallery': require 'app/shared/ImageGallery'

+ 14 - 0
app/pages/Home.pug

@@ -0,0 +1,14 @@
+include ../../pug/base.pug
+include ../../pug/bem.pug
+extends ../layout.pug
+
+block top-content
+    hero-section(:document="document")
+
+block content
+    div(class="max-w-4xl mx-auto px-4" v-if="document")
+        h1(class="text-3xl font-bold text-contrast-high animate-fade-in-up") {{ document.translations[_.currentLanguage]?.title || document.translations.en.title }}
+        p(class="text-xl text-contrast-medium mb-8 animate-fade-in-up") {{ document.translations[_.currentLanguage]?.subtitle || document.translations.en.subtitle }}
+        div(class="prose mt-6 animate-fade-in-up" v-html="marked.parse(document.translations[_.currentLanguage]?.content || document.translations.en.content)")
+        div(class="mt-12")
+            image-gallery(:images="document.translations[_.currentLanguage]?.gallery || document.translations.en.gallery")

+ 11 - 0
app/pages/Home.styl

@@ -0,0 +1,11 @@
+// Используем только утилиты из DesignTokens
+.animate-fade-in-up
+    animation: fadeInUp var(--transition-slow) ease-out
+
+@keyframes fadeInUp
+    from
+        opacity: 0
+        transform: translateY(var(--transition-px))
+    to
+        opacity: 1
+        transform: translateY(0)

+ 18 - 0
app/shared/AppLink.coffee

@@ -0,0 +1,18 @@
+document.head.insertAdjacentHTML('beforeend','<style type="text/css" file="app/shared/AppLink.styl">'+stylFns['app/shared/AppLink.styl']+'</style>')
+module.exports =
+    default:
+        render: (new Function '_ctx', '_cache', renderFns['app/shared/AppLink.pug'])()
+        name: 'AppLink'
+        props:
+            to:
+                type: [String, Object]
+                required: true
+        computed:
+            isExternal: ->
+                if typeof @.to == 'string'
+                    return @.to.startsWith('http')
+                return false
+        data: -> 
+            return {
+                _: _
+            }

+ 7 - 0
app/shared/AppLink.pug

@@ -0,0 +1,7 @@
+include ../../pug/base.pug
+include ../../pug/bem.pug
+
+a.app-link(v-if="isExternal" v-bind="$attrs" :href="to" target="_blank" rel="noopener")
+    slot
+router-link.app-link(v-else v-bind="$attrs" :to="to")
+    slot

+ 54 - 0
app/shared/AppLink.styl

@@ -0,0 +1,54 @@
+@import '../DesignTokens.styl'
+
+// Базовые стили для AppLink компонента
+.app-link 
+    color: var(--primary-color)
+    text-decoration: none
+    transition: color var(--transition-fast)
+
+.app-link:hover 
+    color: var(--primary-dark)
+    text-decoration: underline
+
+.app-link.router-link-active 
+    font-weight: var(--font-semibold)
+    color: var(--primary-dark)
+
+// Стили для внешних ссылок
+.app-link-external::after 
+    content: " ↗"
+    font-size: 0.875em
+    opacity: 0.7
+
+// Стили для кнопко-подобных ссылок
+.app-link-button 
+    display: inline-flex
+    align-items: center
+    gap: var(--space-2)
+    padding: var(--space-2) var(--space-4)
+    background: var(--primary-color)
+    color: white
+    border-radius: 6px
+    font-weight: var(--font-medium)
+    transition: all var(--transition-fast)
+
+.app-link-button:hover 
+    background: var(--primary-dark)
+    transform: translateY(-1px)
+    text-decoration: none
+    color: white
+    box-shadow: var(--shadow-md)
+
+// Стили для иконок в ссылках
+.app-link-with-icon 
+    display: inline-flex
+    align-items: center
+    gap: var(--space-2)
+
+.app-link-icon 
+    width: 16px
+    height: 16px
+    transition: transform var(--transition-fast)
+
+.app-link:hover .app-link-icon 
+    transform: translateX(2px)

+ 5 - 0
app/shared/HeroSection.coffee

@@ -0,0 +1,5 @@
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/shared/HeroSection.styl">'+stylFns['app/shared/HeroSection.styl']+'</style>'
+module.exports =
+    name: 'HeroSection'
+    props: [ 'document' ]
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/HeroSection.pug'])()

+ 6 - 0
app/shared/HeroSection.pug

@@ -0,0 +1,6 @@
+include ../../pug/base.pug
+include ../../pug/bem.pug
+section(v-if="document" class="hero-section bg-gradient")
+    div(class="max-w-7xl mx-auto px-4 py-24 text-center text-white")
+        h1(v-if="document.translations[_.appState.currentLanguage]" class="text-5xl font-bold mb-6") {{ document.translations[_.appState.currentLanguage].title || document.translations.en.title }}
+        p(v-if="document.translations[_.appState.currentLanguage]" class="text-xl opacity-90") {{ document.translations[_.appState.currentLanguage].subtitle || document.translations.en.subtitle }}

+ 5 - 0
app/shared/HeroSection.styl

@@ -0,0 +1,5 @@
+.hero-section
+    background: var(--gradient-primary)
+    color: white
+    padding: var(--space-16) 0
+    text-align: center

+ 8 - 0
app/shared/ImageGallery.coffee

@@ -0,0 +1,8 @@
+document.head.insertAdjacentHTML 'beforeend', '<style type="text/css" file="app/shared/ImageGallery.styl">'+stylFns['app/shared/ImageGallery.styl']+'</style>'
+module.exports =
+    name: 'ImageGallery'
+    props:
+        images:
+            type: Array
+            default: -> []
+    render: (new Function '_ctx', '_cache', renderFns['app/shared/ImageGallery.pug'])()

+ 5 - 0
app/shared/ImageGallery.pug

@@ -0,0 +1,5 @@
+include ../../pug/base.pug
+include ../../pug/bem.pug
+div(v-if="images && images.length > 0" class="image-gallery grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6")
+    div(v-for="(img, idx) in images" :key="idx" class="overflow-hidden rounded-lg shadow-custom-md bg-surface")
+        img(:src="img.src" :alt="img.alt || ''" class="w-full h-auto object-cover transition-transform duration-300 hover:scale-105")

+ 14 - 0
app/shared/ImageGallery.styl

@@ -0,0 +1,14 @@
+.image-gallery
+    display: grid
+    gap: var(--space-6)
+    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))
+
+.image-gallery img
+    width: 100%
+    height: auto
+    object-fit: cover
+    border-radius: 8px
+    transition: transform var(--transition-normal)
+
+.image-gallery img:hover
+    transform: scale(1.05)

+ 134 - 0
app/utils/AppDB.coffee

@@ -0,0 +1,134 @@
+# FILE: app/utils/AppDB.coffee
+class AppDB
+    currentLanguage: 'ru'
+    currentProject: 's5l.ru'
+    designDocVersion: '1.1' # управление версией дизайна
+
+    constructor: ->
+        @localDB = new PouchDB('s5l_local')
+        @remoteDB = new PouchDB('https://oleg:631074@couchdb.favt.ru.net/s5lru/')
+        @syncHandler = null
+
+    init: ->
+        try
+            await @remoteDB.info()
+            debug.log "Remote DB connected"
+            await @ensureDesignDocs()
+            await @ensureDefaultContent()
+            @startSync()
+            AppDB.currentLanguage = globalThis._?.appState?.currentLanguage or 'ru'
+        catch e
+            debug.log "DB init failed:", e
+
+    startSync: ->
+        @syncHandler = @localDB.sync(@remoteDB, { live: true, retry: true })
+            .on 'error', (err) -> debug.log "Sync error:", err
+
+    ensureDesignDocs: ->
+        adminDoc =
+            _id: '_design/admin'
+            version: @designDocVersion
+            views:
+                byPath:
+                    map: (doc) ->
+                        if doc.type == 'page'
+                            emit [doc.domain, doc.path], doc
+                    .toString()
+                byType:
+                    map: (doc) ->
+                        emit doc.type, doc
+                    .toString()
+
+        try
+            existing = await @remoteDB.get('_design/admin')
+            if existing.version != @designDocVersion
+                adminDoc._rev = existing._rev
+                await @remoteDB.put(adminDoc)
+                debug.log "Design doc updated to v#{@designDocVersion}"
+        catch
+            await @remoteDB.put(adminDoc)
+            debug.log "Design doc created v#{@designDocVersion}"
+
+    ensureDefaultContent: ->
+        defaultHome =
+            _id: 'page::s5l.ru::/'
+            type: 'page'
+            domain: 's5l.ru'
+            path: '/'
+            translations:
+                ru:
+                    title: "s5l.ru — мультиязычная offline-first платформа"
+                    subtitle: "Разрабатывайте быстро, работайте везде"
+                    content: '''
+# Добро пожаловать на s5l.ru
+
+**s5l.ru** — это платформа для быстрого запуска веб-проектов с поддержкой:
+- offline-first через PouchDB/CouchDB
+- автоматического переключения языка
+- динамической подгрузки контента
+- полной WCAG 2.2-совместимости
+
+Все тексты хранятся в базе и легко редактируются через админку.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+                en:
+                    title: "s5l.ru — multilingual offline-first platform"
+                    subtitle: "Build fast, work anywhere"
+                    content: '''
+# Welcome to s5l.ru
+
+**s5l.ru** is a platform for rapid web project launches with:
+- offline-first via PouchDB/CouchDB
+- automatic language switching
+- dynamic content loading
+- full WCAG 2.2 compliance
+
+All text is stored in the database and editable via admin panel.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+                tj:
+                    title: "s5l.ru — платформаи бисёрзабон ва аввал офлайн"
+                    subtitle: "Бисёр тез бунёд кунед, дар ҳама ҷо кор кунед"
+                    content: '''
+# Ба s5l.ru хуш омадед
+
+**s5l.ru** — ин платформа барои оғози тези лоиҳаҳои веб аст бо:
+- офлайн-аввал аз рӯи PouchDB/CouchDB
+- ивази худкори забон
+- боркунии динамикӣ
+- мутобиқати пурраи WCAG 2.2
+
+Ҳамаи матнҳо дар база нигоҳ дошта мешаванд ва аз ҷониби панели маъмури озодона таҳрир карда мешаванд.
+'''
+                    gallery: [
+                        { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
+                    ]
+
+        try
+            await @remoteDB.get('page::s5l.ru::/')
+        catch
+            await @remoteDB.put(defaultHome)
+            debug.log "Default home page created"
+
+    getDocumentByPath: (path, lang = @currentLanguage) ->
+        path = path or '/'
+        try
+            result = await @localDB.query('admin/byPath', { key: [@currentProject, path], include_docs: true })
+            if result.rows.length > 0
+                doc = result.rows[0].doc
+                return doc
+            else
+                throw new Error "Document not found"
+        catch e
+            debug.log "Fallback for path:", path, "lang:", lang
+            # fallback to English if not found
+            if lang != 'en'
+                return await @getDocumentByPath(path, 'en')
+            else
+                throw new Error "Document not available even in English"
+
+module.exports = AppDB

+ 5 - 0
assets/demo-hero.svg

@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" viewBox="0 0 800 600">
+  <rect width="800" height="600" fill="var(--bg-card)" />
+  <circle cx="400" cy="300" r="100" fill="var(--primary-light)" opacity="0.2" />
+  <text x="400" y="310" text-anchor="middle" font-size="24" fill="var(--text-muted)">Demo Content</text>
+</svg>

+ 12 - 0
assets/hero-s5l.svg

@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="600" viewBox="0 0 1200 600">
+  <defs>
+    <linearGradient id="g1" x1="0%" y1="0%" x2="100%" y2="100%">
+      <stop offset="0%" stop-color="var(--primary-dark, #ef4444)" />
+      <stop offset="50%" stop-color="var(--primary-color, #f87171)" />
+      <stop offset="100%" stop-color="var(--accent-color, #22d3ee)" />
+    </linearGradient>
+  </defs>
+  <rect width="1200" height="600" fill="url(#g1)" />
+  <circle cx="300" cy="200" r="80" fill="rgba(255,255,255,0.1)" />
+  <circle cx="900" cy="400" r="120" fill="rgba(255,255,255,0.05)" />
+</svg>

+ 5 - 0
assets/icon-db.svg

@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+  <rect x="3" y="4" width="18" height="16" rx="2" />
+  <line x1="3" y1="12" x2="21" y2="12" />
+  <line x1="3" y1="16" x2="21" y2="16" />
+</svg>

+ 6 - 0
assets/icon-i18n.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+  <circle cx="12" cy="12" r="10" />
+  <path d="M12 2a10 10 0 0 0-10 10" />
+  <path d="M12 2a10 10 0 0 1 10 10" />
+  <path d="M8 10h8" />
+</svg>

+ 4 - 0
assets/icon-offline.svg

@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+  <path d="M12 2a9 9 0 0 0-9 9c0 2.5 1.2 4.7 3 6l2-2a4 4 0 0 1 4-4a4 4 0 0 1 4 4l2 2c1.8-1.3 3-3.5 3-6a9 9 0 0 0-9-9z" />
+  <path d="M8 17l4 4l4-4" />
+</svg>

+ 3 - 0
assets/logo-s5l-dark.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="120" height="32" viewBox="0 0 120 32">
+  <text x="0" y="24" font-family="'Inter', sans-serif" font-size="24" fill="#f8fafc" font-weight="700">s5l.ru</text>
+</svg>

+ 3 - 0
assets/logo-s5l-light.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="120" height="32" viewBox="0 0 120 32">
+  <text x="0" y="24" font-family="'Inter', sans-serif" font-size="24" fill="#0f172a" font-weight="700">s5l.ru</text>
+</svg>

+ 40 - 0
doc.coffee

@@ -0,0 +1,40 @@
+module.exports = 
+     version: "0.0.1"
+     adres: [
+        {
+          "adr": "https://cdn.tailwindcss.com/3.4.17"
+          "eventName": "tailwindReady"
+          "obj": "tailwind"
+        }
+        {
+          "adr": "https://unpkg.com/pouchdb/dist/pouchdb.min.js"
+          "eventName": "puochReady"
+          "obj": "PouchDB"
+        }
+        {
+          "adr": "https://unpkg.com/vue@3/dist/vue.runtime.global.prod.js"
+          "eventName": "vueReady"
+          "obj": "Vue"
+        }
+        {
+          "adr": "https://unpkg.com/vue-router@4/dist/vue-router.global.js"
+          "eventName": "VueRouterReady"
+          "obj": "VueRouter"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/@vue/compiler-sfc@3.5.22/dist/compiler-sfc.esm-browser.min.js"
+          "eventName": "compileTemplateReady"
+          "obj": "compileTemplate"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/marked@16.4.1/lib/marked.umd.min.js"
+          "eventName": "markedReady"
+          "obj": "marked"
+        }
+        {
+          "adr": "https://cdn.jsdelivr.net/npm/openlayers@4.6.5/dist/ol.min.js"
+          "css": "https://cdn.jsdelivr.net/npm/openlayers@4.6.5/dist/ol.min.css"
+          "eventName": "leafletReady"
+          "obj": "ol"
+        }
+    ]

+ 34 - 0
lzma.coffee

@@ -0,0 +1,34 @@
+globalThis.debug = require('debug.coffee').default
+require('headVue.coffee')
+
+
+document.documentElement.classList.add('dark')
+
+globalThis.initCount = 0
+ic = ()->
+    if initCount > 5
+       window.location.reload()
+    else if  not globalThis['appReady']
+       initCount++
+       #setTimeout ic, 200
+ic()
+# обязательно подключение глобальных массивов
+globalThis.renderFns = require 'pug.json'
+globalThis.stylFns   = require 'styl.json'
+
+try
+    init =  (event={})->
+        debug.dir   globalThis['vueReady']
+        debug.log "Init Start"
+        if  not globalThis['appReady'] and globalThis['vueReady'] and globalThis['puochReady']
+            debug.log 'init start ok'
+            try
+                require('app/app.coffee')
+                globalThis['appReady'] = true
+                debug.log "init is ok"
+            catch err
+                debug.dir err
+        else if  not globalThis['appReady']
+                debug.log 'pausedEvent appReady'
+                setTimeout init, 200
+    init()

+ 14 - 0
pug/base.pug

@@ -0,0 +1,14 @@
+include ./bem.pug
+
+
+mixin mbh
+    - var otherClasses = attributes.class || ''
+    +b('hfn')(class="h-max overflow-hidden relative")
+        +e('hfn','fon')
+
+mixin mbl
+    - var otherClasses = attributes.class || ''
+    +b('hfn')(class="h-max overflow-hidden relative")
+        +e('hfn','fon')(class="[background:url('https://jahonnamo.s5l.ru/assets/jahonnamo.s5l.ru/bkg00.webp')_0_0_/_cover_no-repeat] bg-[#ffffff] absolute h-full w-full z-[-1]")
+                  if block
+                        block

+ 38 - 0
pug/bem.pug

@@ -0,0 +1,38 @@
+//- bem.pug
+
+//- Базовый миксин для блоков и элементов
+mixin b(blockName, elemName)
+  - var className = blockName
+  - var twClasses = attributes.tw || ''
+  - var otherClasses = attributes.class || ''
+
+  if elemName
+    - className += '__' + elemName
+
+  //- Обработка модификаторов
+  if attributes.mod
+    - className += ' ' + blockName + '--' + attributes.mod
+  if attributes.mods
+    each mod in attributes.mods.split(',')
+      - className += ' ' + blockName + '--' + mod.trim()
+
+  //- Собираем финальный класс
+  - var finalClass = [className, twClasses, otherClasses].filter(Boolean).join(' ')
+
+  //- Удаляем обработанные атрибуты
+  - attributes.tw = null
+  - attributes.mod = null
+  - attributes.mods = null
+  - attributes.class = null
+
+  //- Генерация элемента
+  if block
+    div(class=finalClass)&attributes(attributes)
+      block
+  else
+    div(class=finalClass)&attributes(attributes)
+
+//- Миксин для элементов (альтернативный синтаксис)
+mixin e(blockName, elemName)
+  +b(blockName, elemName)&attributes(attributes)
+    block