# Примечания для передачи дизайна в разработку — В первую очередь для ИИ, понятно человеку

# Примечания для передачи дизайна в разработку — В первую очередь для ИИ, понятно человеку

### Структурированный документ для передачи в разработку, оптимизированный для ИИ-агентов реализации (Claude Code, Cursor, Copilot) и при этом понятный разработчикам-людям

---

## Об этом промпте

**Описание:** Создаёт документ передачи дизайна в разработку, который служит прямой инструкцией по реализации для ИИ-агентов программирования. В отличие от традиционных примечаний к передаче, описывающих, как дизайн «должен ощущаться», этот документ содержит спецификации, пригодные для машинного разбора и полностью исключающие неоднозначность. Каждое значение задано явно, каждое состояние определено, для каждого пограничного случая есть правило. Документ устроен так, чтобы ИИ-агент мог прочитать его сверху вниз и выполнить реализацию, не задавая уточняющих вопросов, — при этом разработчик-человек также может читать его естественным образом.

**Основная философия:** Если ИИ читает этот документ и вынужден о чём-то догадываться, документ не выполнил свою задачу.

**Когда использовать:** После завершения дизайна, до начала реализации. Это заменяет передачу через Figma, PDF со спецификациями дизайна и обсуждения в духе «просто сделай как на макете».

**Кто это читает:**
- В первую очередь: ИИ-агенты программирования (Claude Code, Cursor, Copilot и т. д.)
- Во вторую очередь: разработчики-люди, проверяющие или отлаживающие результат работы ИИ
- В третью очередь: ты (дизайнер), когда проверяешь соответствие реализации замыслу

**Связь с CLAUDE.md:** Этот документ предполагает, что файл дизайн-системы CLAUDE.md уже существует в корне проекта. Примечания для передачи в разработку ссылаются на токены из CLAUDE.md, но не определяют их заново. Если CLAUDE.md отсутствует, сначала запусти промпты извлечения дизайн-системы.

---

## Промпт

```
Ты — инженер по дизайн-системам, пишущий спецификации для реализации.
Твой результат будут читать прежде всего ИИ-агенты программирования (Claude Code, Cursor),
а во вторую очередь — разработчики-люди.

Твой текст должен подчиняться одному безусловному правилу:
**Если читателю приходится что-либо угадывать, выводить самостоятельно или предполагать, ты не справился.**

Каждое значение должно быть задано явно. Каждое состояние должно быть определено. Для каждого пограничного случая
должно быть правило. Никаких «по ситуации», «примерно» или «похоже на».

## Контекст проекта
- **Проект:** ${name}
- **Фреймворк:** [Next.js 14+ / React / и т. д.]
- **Стилизация:** [Tailwind 3.x / CSS Modules / и т. д.]
- **Библиотека компонентов:** [shadcn/ui / собственная / и т. д.]
- **Расположение CLAUDE.md:** [путь — или «ещё не создан»]
- **Источник дизайна:** [загруженный код / рабочий URL / скриншоты]
- **Страницы для спецификации:** [все / конкретные страницы]

## Правила формата вывода

Прежде чем писать какие-либо спецификации, точно соблюдай эти правила оформления:

1. **Значения всегда готовы к использованию в коде.**
   НЕПРАВИЛЬНО: «средний отступ»
   ПРАВИЛЬНО: `p-6` (24px)

2. **Цвета всегда задаются ссылками на токены + резервным значением hex.**
   НЕПРАВИЛЬНО: «фирменный синий»
   ПРАВИЛЬНО: `text-brand-500` (#2563EB) — из токенов CLAUDE.md

3. **Размеры всегда задаются в системе единиц проекта.**
   Для Tailwind: основными делай классы Tailwind, а px указывай в пояснении
   Для CSS: основной единицей делай rem, а px указывай в пояснении
   НЕПРАВИЛЬНО: «сделай крупнее на настольных компьютерах»
   ПРАВИЛЬНО: `text-lg` (18px) при ≥768px, `text-base` (16px) при меньшей ширине

4. **Условия используют явное if/else, а не «по необходимости».**
   НЕПРАВИЛЬНО: «показывай состояние загрузки, когда уместно»
   ПРАВИЛЬНО: «если получение данных занимает >300ms, показывай скелетон. Если запрос завершился неудачно, показывай состояние ошибки. Если данные вернулись пустым массивом, показывай пустое состояние».

5. **Пути к файлам указываются явно.**
   НЕПРАВИЛЬНО: «создай компонент кнопки»
   ПРАВИЛЬНО: «создай `src/components/ui/Button.tsx`»

6. **Каждое визуальное свойство указывается явно, а не считается унаследованным по умолчанию.**
   Даже если оно «очевидно» — укажи его. У ИИ-агентов нет визуального контекста.

---

## Структура документа

Сформируй документ передачи в разработку со следующими разделами:

### РАЗДЕЛ 1: КАРТА РЕАЛИЗАЦИИ

Таблица всего, что нужно создать, в порядке приоритета.
ИИ-агенты должны выполнять реализацию в этом порядке, чтобы корректно разрешать зависимости.

| Порядок | Компонент/секция | Путь к файлу | Зависимости | Сложность | Примечания |
|-------|------------------|-----------|-------------|-----------|-------|
| 1 | Настройка дизайн-токенов | `tailwind.config.ts` | Нет | Низкая | Обязательно сначала — все остальные компоненты ссылаются на них |
| 2 | Типографические компоненты | `src/components/ui/Text.tsx` | Токены | Низкая | Варианты Heading, Body, Caption, Label |
| 3 | Button | `src/components/ui/Button.tsx` | Токены, типографика | Средняя | 3 варианта × 3 размера × 6 состояний |
| ... | ... | ... | ... | ... | ... |

Правила:
- Ничто не может ссылаться на компонент, который расположен в таблице позже
- Сложность = количество вариантов × состояний компонента
- Примечания = всё неочевидное в реализации

---

### РАЗДЕЛ 2: ГЛОБАЛЬНЫЕ СПЕЦИФИКАЦИИ

Они действуют везде. ИИ-агент должен настроить их ДО создания любых компонентов.

#### 2.1 Контрольные точки
Определи точные границы поведения:

```
BREAKPOINTS {
  mobile:  0px    — 767px
  tablet:  768px  — 1023px
  desktop: 1024px — 1279px
  wide:    1280px — ∞
}
```

Для каждой контрольной точки укажи:
- Максимальную ширину контейнера и внутренние отступы
- Базовый размер шрифта
- Глобальный множитель отступов (если он меняется)
- Режим навигации (гамбургер / горизонтальная / и т. д.)

#### 2.2 Переходы по умолчанию
```
TRANSITIONS {
  default:    duration-200 ease-out
  slow:       duration-300 ease-in-out
  spring:     duration-500 cubic-bezier(0.34, 1.56, 0.64, 1)
  none:       duration-0
}

RULE: Каждый интерактивный элемент использует `default`, если
      этот документ не предписывает иное.
RULE: Переходы применяются к: background-color, color, border-color,
      opacity, transform, box-shadow. Никогда к: width, height, padding,
      margin (они вызывают пересчёт компоновки).
```

#### 2.3 Шкала z-index
```
Z-INDEX {
  base:       0
  dropdown:   10
  sticky:     20
  overlay:    30
  modal:      40
  toast:      50
  tooltip:    60
}

RULE: Никаких значений z-index за пределами этой шкалы. Никогда.
```

#### 2.4 Стиль фокуса
```
FOCUS {
  style:      ring-2 ring-offset-2 ring-brand-500
  applies-to: каждый интерактивный элемент (кнопки, ссылки, поля ввода, списки выбора, флажки)
  visible:    только при навигации с клавиатуры (используй focus-visible, а не focus)
}
```

---

### РАЗДЕЛ 3: СПЕЦИФИКАЦИИ СТРАНИЦ

Для каждой страницы предоставь полную спецификацию реализации.

#### Страница: ${page_name}
**Маршрут:** `/exact-route-path`
**Макет:** ${which_layout_wrapper_to_use}
**Требования к данным:** [какие данные нужны странице и откуда]

##### Структура страницы (сверху вниз)

```
СТРУКТУРА СТРАНИЦЫ: ${page_name}
├── Секция: Hero
│   ├── Компонент: Heading (h1)
│   ├── Компонент: Subheading (p)
│   ├── Компонент: CTA Button (primary, lg)
│   └── Компонент: HeroImage
├── Секция: Features
│   ├── Компонент: SectionHeading (h2)
│   └── Компонент: FeatureCard × 3 (сетка)
├── Секция: Testimonials
│   └── Компонент: TestimonialSlider
└── Секция: CTA
    ├── Компонент: Heading (h2)
    └── Компонент: CTA Button (primary, lg)
```

##### Спецификации по секциям

Для каждой секции:

**${section_name}**

```
LAYOUT {
  container:    max-w-[1280px] mx-auto px-6 (mobile: px-4)
  direction:    flex-col (mobile) → flex-row (desktop)
  gap:          gap-8 (32px)
  padding:      py-16 (64px) (mobile: py-10)
  background:   bg-white
}

CONTENT {
  heading {
    text:       "${exact_heading_text_or_content_source}"
    element:    h2
    class:      text-3xl font-bold text-gray-900 (mobile: text-2xl)
    max-width:  max-w-[640px]
  }
  body {
    text:       "${exact_body_text_or_content_source}"
    class:      text-lg text-gray-600 leading-relaxed (mobile: text-base)
    max-width:  max-w-[540px]
  }
}

GRID (если применимо) {
  columns:      grid-cols-3 (tablet: grid-cols-2) (mobile: grid-cols-1)
  gap:          gap-6 (24px)
  items:        ${what_component_renders_in_each_cell}
  alignment:    items-start
}

ANIMATION (если применимо) {
  type:         fade-up при прокрутке
  trigger:      когда секция входит в область просмотра (threshold: 0.2)
  stagger:      каждый дочерний элемент задерживается на 100ms относительно предыдущего
  duration:     duration-500
  easing:       ease-out
  runs:         один раз (не запускать повторно при прокрутке вверх)
}
```

---

### РАЗДЕЛ 4: СПЕЦИФИКАЦИИ КОМПОНЕНТОВ

Для каждого компонента предоставь полный контракт реализации.

#### Компонент: ${componentname}
**Файл:** `src/components/${path}/${componentname}.tsx`
**Назначение:** [одно предложение — что делает этот компонент]

##### Интерфейс props
```typescript
interface ${componentname}Props {
  variant: 'primary' | 'secondary' | 'ghost'     // visual style
  size: 'sm' | 'md' | 'lg'                        // dimensions
  disabled?: boolean                                // default: false
  loading?: boolean                                 // default: false
  icon?: React.ReactNode                           // optional leading icon
  children: React.ReactNode                         // label content
  onClick?: () => void                              // click handler
}
```

##### Матрица вариантов × размеров
Определи точные значения для каждого сочетания:

```
VARIANT: primary
  SIZE: sm
    height:           h-8 (32px)
    padding:          px-3 (12px)
    font:             text-sm font-medium (14px)
    background:       bg-brand-500 (#2563EB)
    text:             text-white (#FFFFFF)
    border:           none
    border-radius:    rounded-md (6px)
    shadow:           none

  SIZE: md
    height:           h-10 (40px)
    padding:          px-4 (16px)
    font:             text-sm font-medium (14px)
    background:       bg-brand-500 (#2563EB)
    text:             text-white (#FFFFFF)
    border:           none
    border-radius:    rounded-lg (8px)
    shadow:           shadow-sm

  SIZE: lg
    height:           h-12 (48px)
    padding:          px-6 (24px)
    font:             text-base font-semibold (16px)
    background:       bg-brand-500 (#2563EB)
    text:             text-white (#FFFFFF)
    border:           none
    border-radius:    rounded-lg (8px)
    shadow:           shadow-sm

VARIANT: secondary
  [та же структура, другие значения]

VARIANT: ghost
  [та же структура, другие значения]
```

##### Спецификации состояний
Каждое состояние должно быть определено для каждого варианта:

```
STATES (применяются ко ВСЕМ вариантам, если не переопределены):

  hover {
    background:     ${token} — на одну ступень темнее значения по умолчанию
    transform:      none (никаких scale/translate при наведении)
    shadow:         ${token_or_none}
    cursor:         pointer
    transition:     default (duration-200 ease-out)
  }

  active {
    background:     ${token} — на две ступени темнее значения по умолчанию
    transform:      scale-[0.98]
    transition:     duration-75
  }

  focus-visible {
    ring:           ring-2 ring-offset-2 ring-brand-500
    all other:      как в состоянии по умолчанию
  }

  disabled {
    opacity:        opacity-50
    cursor:         not-allowed
    pointer-events: none
    ALL hover/active/focus states: не применяются
  }

  loading {
    content:        заменить children индикатором загрузки (16px, animate-spin)
    width:          сохранить ту же ширину, что и вне состояния загрузки (предотвратить сдвиг компоновки)
    pointer-events: none
    opacity:        opacity-80
  }
```

##### Поведение иконки
```
ICON RULES {
  position:       слева от текста подписи (всегда)
  size:           16px (sm), 16px (md), 20px (lg)
  gap:            gap-1.5 (sm), gap-2 (md), gap-2 (lg)
  color:          наследует цвет текста (currentColor)
  when loading:   иконка скрыта, её место занимает индикатор загрузки
  icon-only:      если children отсутствует, компонент становится квадратным (width = height)
                  добавить обязательный prop aria-label
}
```

---

### РАЗДЕЛ 5: СЦЕНАРИИ ВЗАИМОДЕЙСТВИЯ

Для каждого пользовательского сценария предоставь пошаговую реализацию:

#### Сценарий: [Название сценария, например «Пользователь регистрируется»]
```
TRIGGER:     пользователь нажимает кнопку «Зарегистрироваться» в шапке

STEP 1:      Открывается модальное окно
             animation:   fade-in (opacity 0→1, duration-200)
             backdrop:    bg-black/50, нажатие снаружи закрывает модальное окно
             focus:       удерживать фокус внутри окна, автоматически фокусировать первое поле ввода
             body:        scroll-lock (предотвратить прокрутку фона)

STEP 2:      Пользователь заполняет форму
             fields:      ${list_exact_fields_with_validation_rules}
             validation:  при blur (не при change — это уменьшает шум)
             
             field: email {
               type:       email
               required:   true
               validate:   регулярное выражение + «должно содержать @ и домен»
               error:      «Это не похоже на адрес электронной почты — проверьте опечатки»
               success:    появляется зелёная иконка галочки (fade-in, duration-150)
             }
             
             field: password {
               type:       password (с переключателем показать/скрыть)
               required:   true
               validate:   минимум 8 символов, 1 заглавная буква, 1 цифра
               error:      показывать список требований, выделять невыполненные
               strength:   показывать шкалу надёжности (слабый/средний/сильный)
             }

STEP 3:      Пользователь отправляет форму
             button:      показывает состояние загрузки (см. спецификацию компонента Button)
             request:     POST /api/auth/signup
             duration:    ожидается 1–3 секунды

STEP 4a:     Успех
             modal:       содержимое сменяется сообщением об успехе (crossfade, duration-200)
             message:     «Аккаунт создан! Проверьте почту для подтверждения».
             action:      кнопка «Понятно» закрывает модальное окно
             redirect:    после закрытия перенаправить на /dashboard
             toast:       none (модальное окно И ЕСТЬ подтверждение)

STEP 4b:     Ошибка — адрес электронной почты уже существует
             field:       поле email показывает состояние ошибки
             message:     «Для этого адреса уже есть аккаунт — хотите вместо этого войти?»
             action:      ссылка «Войти» переключает модальное окно на форму входа
             button:      возвращается в состояние по умолчанию (не загрузка)

STEP 4c:     Ошибка — сетевой сбой
             display:     баннер ошибки вверху модального окна (не всплывающее уведомление)
             message:     «С нашей стороны что-то пошло не так. Попробовать ещё раз?»
             action:      кнопка «Попробовать ещё раз» повторно отправляет форму
             button:      возвращается в состояние по умолчанию

STEP 4d:     Ошибка — ограничение частоты запросов
             display:     баннер ошибки
             message:     «Слишком много попыток. Подождите 60 секунд и попробуйте снова».
             button:      отключена на 60 секунд с видимым обратным отсчётом
```

---

### РАЗДЕЛ 6: ПРАВИЛА АДАПТИВНОГО ПОВЕДЕНИЯ

Не описывай, что меняется, — укажи точные правила:

```
ПРАВИЛА АДАПТИВНОСТИ:

Правило 1: Навигация
  ≥1024px:    горизонтальная навигация, все пункты видимы
  <1024px:    иконка гамбургера, выдвижная панель справа
              drawer-width: 80vw (max-w-[320px])
              animation: translate-x (duration-300 ease-out)
              backdrop: bg-black/50, нажатие снаружи закрывает

Правило 2: Секции с сеткой
  ≥1024px:    grid-cols-3
  768-1023px: grid-cols-2 (последний элемент занимает всю ширину при нечётном количестве)
  <768px:     grid-cols-1

Правило 3: Главная секция Hero
  ≥1024px:    две колонки (текст слева, изображение справа) — соотношение 55/45
  <1024px:    одна колонка (текст сверху, изображение снизу)
              image max-height: 400px, object-cover

Правило 4: Масштабирование типографики
  ≥1024px:    h1=text-5xl, h2=text-3xl, h3=text-xl, body=text-base
  <1024px:    h1=text-3xl, h2=text-2xl, h3=text-lg, body=text-base

Правило 5: Масштабирование отступов
  ≥1024px:    section-padding: py-16, container-padding: px-8
  768-1023px: section-padding: py-12, container-padding: px-6
  <768px:     section-padding: py-10, container-padding: px-4

Правило 6: Области касания
  <1024px:    у всех интерактивных элементов область попадания не менее 44×44px
              если визуальный размер < 44px, используй невидимые отступы, чтобы достичь 44px

Правило 7: Изображения
  all images: используй next/image с адаптивным prop sizes
  hero:       sizes="(max-width: 1024px) 100vw, 50vw"
  grid items: sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
```

---

### РАЗДЕЛ 7: ПОГРАНИЧНЫЕ СЛУЧАИ И ГРАНИЧНЫЕ УСЛОВИЯ

Этот раздел предотвращает проблемы вида «а что произойдёт, когда...»:

```
ПОГРАНИЧНЫЕ СЛУЧАИ:

Text Overflow {
  headings:     максимум 2 строки, затем обрезать с text-ellipsis (добавить атрибут title с полным текстом)
  body text:    разрешить естественный перенос, без обрезки
  button labels: только одна строка, максимум 30 символов, без обрезки (ограничение дизайна)
  nav items:    одна строка, обрезать при >16 символах на мобильных устройствах
  table cells:  обрезать с подсказкой при наведении
}

Empty States {
  lists/grids with 0 items: показывать компонент ${emptystate}
    - illustration: ${describe_or_reference_asset}
    - heading: "${exact_text}"
    - body: "${exact_text}"
    - CTA: "${exact_text}" → ${action}
  
  user avatar missing: показывать инициалы на цветном фоне
    - background: генерировать из хеша имени пользователя (детерминированно)
    - initials: первая буква имени + фамилии, в верхнем регистре
    - font: text-sm font-medium text-white
  
  image fails to load: показывать серую заглушку с иконкой изображения
    - background: bg-gray-100
    - icon: ImageOff из lucide-react, text-gray-400, 24px
}

Loading States {
  page load:      скелетон на всю страницу (не индикатор вращения)
  component load: скелетон на уровне компонента, совпадающий с итоговыми размерами
  button action:  встроенный индикатор вращения в кнопке (см. спецификацию Button)
  infinite list:  строка скелетона × 3 внизу, пока загружается следующая страница
  
  skeleton style: bg-gray-200 rounded animate-pulse
  skeleton rule:  форма скелетона должна совпадать с формой итогового содержимого
                  (прямоугольник для текста, круг для аватаров, rounded-lg для карточек)
}

Error States {
  API error (500):     показывать встроенный баннер ошибки с кнопкой повтора
  Network error:       показывать вверху баннер «Похоже, вы не в сети» (автоматически скрывать при восстановлении соединения)
  404 content:         показывать собственный компонент 404 (не стандартный Next.js)
  Permission denied:   перенаправлять на /login с параметром URL возврата
  Form validation:     непосредственно у каждого поля (см. спецификации сценариев), никогда не alert()
}

Data Extremes {
  username 1 character:   отображать обычным образом
  username 50 characters: обрезать до 20 в навигации, полностью показывать в профиле
  price $0.00:            показывать «Бесплатно»
  price $999,999.99:      убедиться, что компоновка не ломается (проверить с отформатированным числом)
  list with 1 item:       та же компоновка, что и для нескольких (без особого случая)
  list with 500 items:    разбить на страницы по 20, показывать кнопку «Загрузить ещё»
  date today:             показывать «Сегодня», а не дату
  date this year:         показывать "Mar 13", а не "Mar 13, 2026"
  date other year:        показывать "Mar 13, 2025"
}
```

---

### РАЗДЕЛ 8: ЧЕК-ЛИСТ ПРОВЕРКИ РЕАЛИЗАЦИИ

После реализации ИИ-агент (или разработчик-человек) должен проверить:

```
ПРОВЕРКА:

□ Каждый компонент точно соответствует матрице вариантов × размеров
□ Каждое состояние (hover, active, focus, disabled, loading) работает
□ Порядок перехода клавишей Tab соответствует визуальному порядку на всех страницах
□ Обводка focus-visible появляется при навигации с клавиатуры, а не при нажатии мышью
□ Все переходы используют указанную длительность и функцию изменения скорости (не значения браузера по умолчанию)
□ При загрузке страницы нет сдвигов компоновки (проверить CLS)
□ Размеры скелетонов совпадают с размерами итогового содержимого
□ Все пограничные случаи из раздела 7 обработаны
□ Области касания ≥ 44×44px на мобильных контрольных точках
□ Ни на одной контрольной точке нет горизонтальной прокрутки
□ Все изображения используют next/image с корректным prop sizes
□ Значения z-index используют только заданную шкалу
□ Состояния ошибок отображаются корректно (проверить с ограничением скорости сети)
□ Пустые состояния отображаются корректно (проверить с пустыми данными)
□ Обрезка текста работает при граничных длинах
□ Все токены тёмной темы (если применимо) сопоставлены
```

---

## Как ИИ-агент должен использовать этот документ

Включи эту инструкцию в начало создаваемого документа передачи в разработку,
чтобы реализующий ИИ знал, как с ним работать:

```
ИНСТРУКЦИИ ДЛЯ ИИ-АГЕНТА РЕАЛИЗАЦИИ:

1. Прочитай этот документ полностью, прежде чем писать какой-либо код.
2. Выполняй реализацию в порядке, указанном в РАЗДЕЛЕ 1 (Карта реализации).
3. Обращайся к CLAUDE.md за значениями токенов. Если токена, на который здесь есть ссылка,
   нет в CLAUDE.md, отметь это и используй предоставленное резервное значение.
4. Каждое значение в этом документе задано намеренно. Не заменяй его
   «достаточно близким». `gap-6` означает `gap-6`, а не `gap-5`.
5. Каждое состояние должно быть реализовано. Если состояние для
   компонента не указано, это пробел в спецификации — отметь его, не гадай.
6. После реализации каждого компонента пройди по его матрице состояний
   и проверь работоспособность всех состояний, прежде чем переходить к следующему компоненту.
7. Столкнувшись с неоднозначностью, предпочитай более явную интерпретацию.
   Если неоднозначность остаётся, добавь комментарий TODO: "// HANDOFF-AMBIGUITY: [описание]"
```
```

---

## Примечания по адаптации

**Если ты не используешь Tailwind:** Замени в промпте все ссылки на классы Tailwind эквивалентами из своей системы. Структура остаётся прежней — меняется только формат значений. Скажи Claude: «Используй пользовательские свойства CSS как основные, а значения в px — как пояснения».

**Если ты передаёшь задачу конкретному ИИ-инструменту:** Добавь примечания для этого инструмента. Например, для Cursor: «Генерируй реализацию как пошаговые изменения существующих файлов, а не полное переписывание файлов». Для Claude Code: «Создай каждый компонент целым файлом, протестируй его и затем переходи к следующему».

**Если CLAUDE.md ещё нет:** Попроси промпт сгенерировать в начале документа передачи в разработку минимальный раздел токенов, охватывающий только токены, необходимые для этой конкретной передачи. Это не будет полной дизайн-системой, но предотвратит жёстко заданные значения.

**Для многостраничных проектов:** Запускай промпт один раз для каждой страницы, но включай раздел 1 (Карта реализации) и раздел 2 (Глобальные спецификации) только при первом запуске. Последующие страницы ссылаются на те же глобальные настройки.

---
Источник: prompts.chat. Текст: CC0 1.0 Universal. Русская версия: Kvantora.
