Initial: recipes site source
This commit is contained in:
commit
a97fd30e23
142
PRD.md
Normal file
142
PRD.md
Normal file
@ -0,0 +1,142 @@
|
||||
# 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 или собственный домен?
|
||||
83
README.md
Normal file
83
README.md
Normal file
@ -0,0 +1,83 @@
|
||||
# Простые рецепты
|
||||
|
||||
Статический одностраничный сайт с коллекцией простых рецептов меню на каждый день. Реализация 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
Normal file
340
TRD.md
Normal file
@ -0,0 +1,340 @@
|
||||
# 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. Какой хостинг изображений выбрать, когда придёт время заменить эмодзи на фото?
|
||||
1113
recipes.html
Normal file
1113
recipes.html
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user