Compare commits

..

No commits in common. "main" and "gitea-pages" have entirely different histories.

4 changed files with 0 additions and 565 deletions

142
PRD.md
View File

@ -1,142 +0,0 @@
# PRD: Сайт с простыми рецептами «Простые рецепты»
## 1. Обзор продукта
Веб-сайт с коллекцией простых рецептов меню на каждый день. Пользователь получает структурированный каталог блюд, разбитый по разделам, с описанием состава, перечнем необходимых продуктов, пошаговым приготовлением и пищевой ценностью (калории, БЖУ). Цель — помочь пользователю быстро выбрать, что приготовить, и собрать список покупок.
## 2. Цели и задачи
### Бизнес-цели
- Создать узнаваемый кулинарный ресурс с простыми и понятными рецептами.
- Увеличить время, проводимое пользователем на сайте (просмотр карточек, изучение состава).
- Сформировать базу для дальнейших фич: избранное, корзина продуктов, шеринг.
### Продуктовые цели
- Предоставить пользователю каталог рецептов в 5 ключевых категориях.
- Каждый рецепт содержит: краткий состав, продукты с граммовкой, шаги, калорийность и БЖУ.
- Обеспечить мобильную адаптивность и быстрый поиск нужного блюда.
## 3. Целевая аудитория
### Основные сегменты
1. **Домохозяйки и работающие женщины 25–45 лет** — нужны быстрые повседневные рецепты.
2. **Студенты и молодые специалисты 18–30 лет** — ищут простые блюда из доступных продуктов.
3. **Поклонники ПП и фитнес-питания** — следят за калориями и БЖУ.
4. **Хозяева застолий** — ищут идеи для праздничного стола и сервировки.
### Ключевые пользовательские задачи (Jobs-to-be-Done)
- «Что приготовить на завтрак за 10 минут?»
- «Нужен рецепт обеда из того, что есть в холодильнике.»
- «Хочу полезный ужин, но не знаю калорийность.»
- «Гости на пороге — нужны идеи закусок и сервировки.»
## 4. Разделы сайта
Сайт содержит **5 основных разделов**, доступных через верхнее меню (sticky навигация):
### 4.1. Завтраки ☕
Лёгкие и сытные блюда, готовящиеся за 5–15 минут.
Примеры наполнения: творожные оладьи, яичница с помидорами, овсянка с фруктами, сэндвич с авокадо.
### 4.2. Обеды 🍲
Сытные блюда для основного приёма пищи: первые блюда, гарниры, мясные/рыбные основные.
Примеры: куриный суп с лапшой, паста карбонара, плов с курицей, котлеты с картошкой.
### 4.3. Ужин 🌙
Лёгкие, преимущественно белковые и овощные блюда для вечера.
Примеры: запечённая рыба с овощами, тёплый салат с курицей, омлет со шпинатом, овощное рагу.
### 4.4. ПП питание 🥗
Полезные, сбалансированные рецепты без сахара и с контролем калорий. Подходит для худеющих и спортсменов.
Примеры: чиа-пудинг, куриная грудка на гриле, боул с киноа, ПП-смузи, ПП-сырники в духовке.
### 4.5. Праздничная сервировка 🎉
Рецепты для особых случаев + рекомендации по сервировке стола.
Примеры: запечённая курица целиком, канапе ассорти, цезарь с креветками, торт «Наполеон», шпаргалка по сервировке.
## 5. Функциональные требования
### 5.1. Каталог рецептов
- **F-1.** Каталог разбит на 5 разделов, переключение через табы в навигации.
- **F-2.** Каждый раздел отображает сетку карточек рецептов (responsive grid).
- **F-3.** Активная вкладка визуально выделена.
- **F-4.** При переключении раздела страница скроллится наверх.
### 5.2. Карточка рецепта
Каждая карточка в свёрнутом виде содержит:
- **F-5.** Эмодзи/иконку блюда.
- **F-6.** Название рецепта.
- **F-7.** Мета-бейджи: время приготовления, количество порций, калорийность.
- **F-8.** Короткое маркетинговое описание (1 строка).
- **F-9.** Состав — перечисление основных компонентов через запятую.
При клике карточка раскрывается и показывает:
- **F-10.** Полный список необходимых продуктов с граммовкой/штучным количеством.
- **F-11.** Пошаговое приготовление (нумерованный список).
- **F-12.** Раздел «Калорийность» с указанием ккал на порцию и БЖУ.
- **F-13.** Для праздничных рецептов — отдельный блок «Сервировка» с рекомендациями.
- **F-14.** Повторный клик сворачивает карточку.
### 5.3. Навигация
- **F-15.** Sticky-меню вверху страницы, всегда доступно при скролле.
- **F-16.** Меню адаптируется под мобильные устройства (wrap при недостатке ширины).
### 5.4. Дизайн и UX
- **F-17.** Тёплая, аппетитная цветовая палитра (оранжево-розовые градиенты, кремовый фон).
- **F-18.** Hover-эффекты на карточках (приподнятие, тень).
- **F-19.** Шрифт системный (San Francisco / Segoe UI / Roboto) для скорости загрузки.
- **F-20.** Адаптивный grid: 1 колонка на мобильном, 2–4 на десктопе.
## 6. Нефункциональные требования
- **NF-1.** Время загрузки страницы ≤ 1 сек на десктопе, ≤ 2 сек на 4G.
- **NF-2.** Размер HTML-файла ≤ 100 КБ (без внешних зависимостей).
- **NF-3.** Совместимость с современными браузерами: Chrome, Safari, Firefox, Edge (последние 2 версии).
- **NF-4.** Мобильная адаптация для устройств от 320 px ширины.
- **NF-5.** Семантическая разметка (header, nav, main, section, footer).
- **NF-6.** Контент полностью на русском языке.
## 7. Out of Scope (на MVP не делаем)
- Авторизация и личный кабинет пользователя.
- Избранное / сохранённые рецепты (запланировано в v2).
- Поиск и фильтрация рецептов (запланировано в v2).
- Корзина продуктов и генерация списка покупок (v2).
- Комментарии и рейтинги (v2).
- Загрузка фотографий блюд (используются эмодзи).
- Видео-рецепты.
- Мультиязычность.
- Backend и база данных.
## 8. Метрики успеха
- **M-1.** Среднее время сессии ≥ 90 сек.
- **M-2.** Глубина просмотра ≥ 3 раскрытых карточки за сессию.
- **M-3.** Bounce rate ≤ 50%.
- **M-4.** Доля мобильного трафика ≥ 60%.
- **M-5.** Минимум 4 рецепта в каждом разделе на MVP.
## 9. План релизов
### MVP (v1.0)
- 5 разделов с 4–5 рецептами в каждом (≥ 21 рецепт всего).
- Каталог + раскрывающиеся карточки.
- Калорийность и БЖУ для каждого блюда.
- Адаптивная вёрстка.
### v1.1
- Добавление 10+ рецептов в каждый раздел.
- Поиск по названию.
- Печать рецепта.
### v2.0
- Избранное (localStorage).
- Фильтры (по времени, калориям, ингредиентам).
- Генератор списка покупок.
- Рейтинги и комментарии (потребуется backend).
## 10. Открытые вопросы
- Q-1. Нужно ли подключать аналитику (Plausible / Yandex.Metrika) с MVP?
- Q-2. Использовать ли реальные фото блюд (с CDN) или ограничиться эмодзи?
- Q-3. Деплой: GitHub Pages, Gitea Pages или собственный домен?

View File

@ -1,83 +0,0 @@
# Простые рецепты
Статический одностраничный сайт с коллекцией простых рецептов меню на каждый день. Реализация PRD/TRD: каталог из 5 разделов (Завтраки, Обеды, Ужин, ПП питание, Праздничная сервировка), 21 рецепт с составом, продуктами, шагами приготовления и калорийностью.
Документы: [PRD.md](PRD.md), [TRD.md](TRD.md).
## Стек
- **HTML5 + CSS3 + vanilla JavaScript (ES6+)** — один файл, без сборщиков.
- **Внешние зависимости**: 0 (никаких npm, CDN, фреймворков).
- **Хостинг**: Gitea Pages (см. [GITEA.md](GITEA.md)).
## Структура
```
yuldasheva/
├── recipes.html # Сайт (HTML + inline CSS + inline JS)
├── PRD.md # Product Requirements Document
├── TRD.md # Technical Requirements Document
├── README.md # Этот файл
└── GITEA.md # Инструкции по Gitea Pages деплою
```
## Быстрый старт
### Открыть локально
```bash
open recipes.html
```
или двойной клик в Finder.
### Локальный HTTP-сервер
Если нужен URL вида `http://localhost:8000/recipes.html`:
```bash
python3 -m http.server 8000
```
Открыть <http://localhost:8000/recipes.html>.
## Контент
### Разделы
| ID секции | Раздел | Кол-во рецептов |
|-----------|--------|-----------------|
| `breakfast` | Завтраки | 4 |
| `lunch` | Обеды | 4 |
| `dinner` | Ужин | 4 |
| `healthy` | ПП питание | 5 |
| `holiday` | Праздничная сервировка | 5 (включая шпаргалку по сервировке) |
### Структура карточки рецепта
- Иконка (emoji), название.
- Мета: время приготовления, количество порций, калорийность.
- Краткое описание + состав.
- Раскрываемая часть: список продуктов с граммовкой, шаги приготовления, БЖУ.
- Для праздничных рецептов — отдельный блок «Сервировка».
## Деплой
### Gitea Pages
Репозиторий уже настроен на сборку Gitea Pages — коммит в `main` автоматически публикует `recipes.html`. Подробнее: [GITEA.md](GITEA.md).
### GitHub Pages (альтернатива)
1. Settings → Pages → Source: `main` branch, root.
2. Опционально: переименовать `recipes.html` → `index.html` для корневого URL.
## Развитие
См. раздел «План релизов» в [PRD.md](PRD.md) и «План расширения» в [TRD.md](TRD.md). Ключевые направления v2:
- Поиск и фильтрация по разделам, времени, калориям.
- Избранное на `localStorage`.
- Корзина продуктов с агрегацией ингредиентов.
- Schema.org Recipe markup для SEO.
- Замена эмодзи на фотографии блюд с CDN.

340
TRD.md
View File

@ -1,340 +0,0 @@
# TRD: Сайт «Простые рецепты» — техническая спецификация
> Сопровождающий документ к [PRD.md](PRD.md). Описывает технические решения для реализации MVP сайта с рецептами.
## 1. Цели TRD
- Зафиксировать архитектурное решение: статический одностраничный сайт без backend.
- Определить структуру данных рецептов, разметки и стилей.
- Обеспечить минимальную стоимость хостинга и максимальную скорость загрузки.
- Заложить точки расширения для функций v2 (поиск, избранное, корзина).
## 2. Архитектура
### 2.1. Общая схема
```
┌─────────────────────────────────────────────┐
│ Браузер пользователя │
│ ┌─────────────────────────────────────┐ │
│ │ recipes.html (HTML + CSS + JS) │ │
│ │ - Контент рецептов (inline) │ │
│ │ - Стили (inline <style>) │ │
│ │ - Логика табов и раскрытия (JS) │ │
│ └─────────────────────────────────────┘ │
└──────────────────┬──────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────┐
│ Статический хостинг │
│ (GitHub Pages / Gitea Pages / Netlify) │
└─────────────────────────────────────────────┘
```
### 2.2. Тип приложения
- **Static Single Page** — один HTML-файл, без сборщиков, без runtime-зависимостей.
- Контент рецептов хранится в разметке HTML (semantic markup).
- Состояние UI (активная вкладка, раскрытая карточка) — в DOM и CSS-классах.
### 2.3. Обоснование
| Альтернатива | Решение | Причина отказа |
|--------------|---------|----------------|
| SPA (React/Vue) | ❌ | Overkill для 21 статической карточки; +200 КБ JS |
| SSG (Next/Astro) | ❌ | Сборка усложняет правки контента непрофильному автору |
| WordPress / CMS | ❌ | Требует backend и БД; не нужно для MVP |
| **Single HTML файл** | ✅ | Минимум зависимостей, быстрая загрузка, легко деплоить |
## 3. Технологический стек
| Слой | Технология | Версия | Назначение |
|------|------------|--------|------------|
| Разметка | HTML5 | — | Семантическая структура |
| Стили | CSS3 (vanilla) | — | Дизайн, grid, адаптив |
| Логика | JavaScript ES6+ | — | Табы, раскрытие карточек |
| Иконки | Unicode emoji | — | Визуальное оформление без CDN |
| Шрифты | System fonts | — | -apple-system, BlinkMacSystemFont, Segoe UI, Roboto |
| Хостинг | Gitea Pages | — | Используется существующая конфигурация репо (см. `GITEA.md`) |
**Внешние зависимости: 0.** Никаких npm-пакетов, CDN, фреймворков.
## 4. Структура проекта
```
yuldasheva/
├── recipes.html # Основной файл сайта (MVP)
├── PRD.md # Product Requirements Document
├── TRD.md # Technical Requirements Document (этот файл)
├── README.md # Описание репозитория
└── GITEA.md # Инструкции по Gitea Pages деплою
```
## 5. Структура HTML
### 5.1. Дерево документа
```
<html>
<head>
<meta charset, viewport, title>
<style>...inline CSS...</style>
</head>
<body>
<header> — заголовок и слоган
<nav> — переключатель разделов (5 кнопок)
<ul>
<li><button class="tab" data-target="...">
<main>
<section id="breakfast" class="section active">
<h2 class="section-title">
<p class="section-desc">
<div class="recipes">
<div class="card">
<div class="card-emoji">
<div class="card-body">
<h3>
<div class="card-meta"> — время, порции, ккал
<p class="short"> — описание
<div class="composition"> — состав
<div class="recipe-details"> — раскрываемая часть
<h4>Необходимые продукты</h4>
<ul>
<h4>Приготовление</h4>
<ol>
<h4>Сервировка</h4> — только для праздничных
<div class="kcal-box"> — калории и БЖУ
<section id="lunch"> ... (повторяется для каждой категории)
<section id="dinner">
<section id="healthy">
<section id="holiday">
<footer>
<script>...JS...</script>
</body>
</html>
```
### 5.2. Идентификаторы секций
| ID | Раздел |
|----|--------|
| `breakfast` | Завтраки |
| `lunch` | Обеды |
| `dinner` | Ужин |
| `healthy` | ПП питание |
| `holiday` | Праздничная сервировка |
## 6. Модель данных рецепта
Каждый рецепт реализован как блок `<div class="card">` со следующей внутренней структурой:
| Поле | Тип | HTML-якорь | Обязательно |
|------|-----|------------|-------------|
| Иконка | emoji | `.card-emoji` | Да |
| Название | string | `h3` | Да |
| Время | string | `.card-meta span` | Да |
| Количество порций | string | `.card-meta span` | Да |
| Калорийность (бейдж) | string | `.card-meta span` | Да (кроме шпаргалок) |
| Короткое описание | string | `p.short` | Да |
| Состав | string | `.composition` | Да |
| Список продуктов | array of strings | `.recipe-details ul` (первый) | Да |
| Шаги приготовления | array of strings | `.recipe-details ol` | Да |
| Сервировка | array of strings | `.recipe-details ul` (после `<h4>Сервировка</h4>`) | Только для holiday |
| Калории + БЖУ | string | `.kcal-box` | Да (кроме шпаргалок) |
### 6.1. Будущая миграция на JSON
Для v2 рецепты можно вынести в `data/recipes.json`:
```json
{
"id": "tvorozhnye-oladyi",
"section": "breakfast",
"emoji": "🥞",
"title": "Творожные оладьи",
"time": "15 мин",
"servings": "2 порции",
"kcal": 220,
"short": "Пышные, нежные, с тёплым мёдом.",
"composition": ["творог", "мука", "яйцо", "сахар"],
"ingredients": [
{"name": "Творог", "amount": "200 г"},
{"name": "Яйцо", "amount": "1 шт"}
],
"steps": ["Смешать творог...", "Добавить муку..."],
"nutrition": {"kcal": 220, "protein": 18, "fat": 7, "carbs": 22}
}
```
## 7. CSS-архитектура
### 7.1. Подход
- Все стили inline в `<style>` для нулевого количества HTTP-запросов.
- BEM-подобные имена классов: `.card`, `.card-body`, `.card-meta`, `.recipe-details`.
- CSS-переменные не используются (один файл, простая палитра).
### 7.2. Палитра
| Назначение | Цвет |
|------------|------|
| Фон страницы | `#fdf8f3` |
| Основной акцент | `#ff8a65` |
| Вторичный акцент | `#f06292` |
| Заголовки секций | `#d84315` |
| Текст основной | `#2c2c2c` |
| Текст вторичный | `#666` |
| Фон карточки | `#ffffff` |
| Фон бейджа kcal-box | `#e8f5e9` |
### 7.3. Сетка
- `.recipes` — `display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));`
- Автоматическая адаптация: 1 колонка ≤ 600 px, 2–4 на десктопе.
### 7.4. Адаптив
- Один media-query `@media (max-width: 600px)`.
- Уменьшение размеров заголовков.
- Nav-меню переносится через `flex-wrap: wrap`.
## 8. JavaScript: логика
### 8.1. Переключение разделов
```javascript
const tabs = document.querySelectorAll('.tab');
const sections = document.querySelectorAll('.section');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const target = tab.dataset.target;
tabs.forEach(t => t.classList.remove('active'));
sections.forEach(s => s.classList.remove('active'));
tab.classList.add('active');
document.getElementById(target).classList.add('active');
window.scrollTo({ top: 0, behavior: 'smooth' });
});
});
```
### 8.2. Раскрытие/сворачивание карточки
```javascript
document.querySelectorAll('.card').forEach(card => {
card.addEventListener('click', () => {
card.classList.toggle('expanded');
});
});
```
### 8.3. Объём JS
Менее 30 строк. Без зависимостей. ES6+ (стрелочные функции, `let`/`const`).
## 9. Производительность
| Метрика | Целевое значение | Реализация |
|---------|------------------|------------|
| Размер HTML | ≤ 100 КБ | Inline CSS/JS, без изображений |
| HTTP-запросов | 1 | Один HTML без внешних ресурсов |
| Первый рендер (FCP) | ≤ 0.5 сек | Critical CSS inline |
| Time to Interactive | ≤ 1 сек | Минимум JS |
| Lighthouse Performance | ≥ 95 | Нет внешних запросов |
## 10. Доступность (a11y)
- **A-1.** Семантические теги: `<header>`, `<nav>`, `<main>`, `<section>`, `<footer>`.
- **A-2.** Кнопки навигации — настоящие `<button>`, доступны через клавиатуру (Tab + Enter).
- **A-3.** Контраст текста к фону ≥ 4.5:1 (WCAG AA).
- **A-4.** Шрифты ≥ 14 px для основного текста.
- **A-5.** В v1.1 добавить `aria-expanded` для раскрывающихся карточек.
## 11. SEO
- **S-1.** `<title>` уникальный, описательный.
- **S-2.** `<meta name="description">` — **добавить в v1.1** (на MVP отсутствует).
- **S-3.** Open Graph теги — **v1.1**.
- **S-4.** Schema.org Recipe markup — **v2** (требует ID и URL для каждого рецепта).
- **S-5.** `lang="ru"` на `<html>`.
## 12. Браузерная совместимость
| Браузер | Минимальная версия |
|---------|---------------------|
| Chrome | 90+ |
| Safari | 14+ |
| Firefox | 88+ |
| Edge | 90+ |
| Mobile Safari (iOS) | 14+ |
| Chrome Android | 90+ |
Используемые фичи: CSS Grid, Flexbox, ES6, классические `addEventListener`. Полифиллы не требуются.
## 13. Деплой
### 13.1. MVP — Gitea Pages
Репозиторий уже настроен под Gitea Pages (см. `GITEA.md` и коммит `cd1c613`).
Шаги:
1. Файл `recipes.html` коммитится в ветку `main`.
2. Gitea Pages автоматически публикует статику.
3. Доступ по URL вида `https://<user>.gitea.pages/yuldasheva/recipes.html`.
### 13.2. Альтернатива — GitHub Pages
1. Включить Pages в настройках репозитория.
2. Source: `main` branch, root.
3. Опционально: переименовать `recipes.html` → `index.html` для корневого URL.
### 13.3. CI/CD
На MVP не требуется. В v1.1 добавить:
- GitHub Action для валидации HTML (`html-validate`) при PR.
- Lighthouse CI для мониторинга метрик производительности.
## 14. Тестирование
### 14.1. Ручное (MVP)
- Открытие сайта в 4 браузерах (Chrome, Safari, Firefox, Edge).
- Проверка работы табов и раскрытия карточек.
- Проверка адаптивности на разрешениях 320, 768, 1024, 1440 px.
- Визуальная проверка контрастности и читаемости.
### 14.2. Автотесты (v1.1+)
- Playwright e2e: переключение разделов, клик по карточке.
- HTML-валидация: `html-validate recipes.html`.
- Lighthouse CI: budget на Performance ≥ 90.
## 15. Безопасность
- **SEC-1.** Контент полностью статический — нет user input, нет XSS.
- **SEC-2.** Нет cookies, нет авторизации, нет PII.
- **SEC-3.** Включить заголовок `Content-Security-Policy` на уровне хостинга (`default-src 'self' 'unsafe-inline'` — `unsafe-inline` нужен для inline `<style>` и `<script>`).
- **SEC-4.** При деплое — только HTTPS.
- **SEC-5.** При появлении user input (комментарии, v2) — обязателен Backend + санитизация.
## 16. План расширения (под v2)
| Фича | Техническое решение |
|------|---------------------|
| Поиск | Клиентский фильтр на JS по `data-title` атрибутам карточек |
| Избранное | `localStorage` + JSON-массив ID рецептов |
| Корзина продуктов | Агрегация ингредиентов из выбранных рецептов через клиентский JS |
| Рейтинги/комментарии | Потребуется backend — API + БД (Postgres / SQLite) |
| Картинки блюд | Подключение CDN (Cloudinary / ImgIX) + lazy loading |
| Мультиязычность | Вынос контента в JSON + i18n словари |
| Schema.org Recipe | Генерация `<script type="application/ld+json">` для каждого рецепта |
## 17. Риски и митигации
| Риск | Вероятность | Митигация |
|------|-------------|-----------|
| Файл `recipes.html` разрастается, становится трудно поддерживать | Высокая | На пороге 50+ рецептов мигрировать на JSON + рендеринг JS |
| Низкий органический трафик из-за отсутствия SEO | Средняя | В v1.1 добавить meta description, OG, Sitemap |
| Контент устаревает | Низкая | Назначить ответственного редактора, ревизия раз в квартал |
| Жалобы на точность калорийности | Средняя | Добавить дисклеймер «приблизительные значения», ссылки на источники в v1.1 |
## 18. Открытые технические вопросы
- TQ-1. Использовать Gitea Pages или GitHub Pages для первого деплоя?
- TQ-2. Нужна ли аналитика (Plausible / Yandex.Metrika) с MVP?
- TQ-3. Хранить рецепты в HTML до v2 или сразу мигрировать на JSON-файл с клиентским рендером?
- TQ-4. Какой хостинг изображений выбрать, когда придёт время заменить эмодзи на фото?