| name | design-guardrails |
| description | Финальная верификация дизайн-артефакта: Design Read → Quality Gate → Visual Diff → Drift Rejection. Для «повтори сайт в коде», «редизайн без поломки» или как QA-гейт PASS/FAIL перед сдачей. Соседи: design-taste (ДО), design-orchestrator (генерация). |
| when_to_use | 1) Пользователь дал скриншот/URL/дизайн-референс и просит воспроизвести в коде максимально точно.
2) Пользователь дал существующий функциональный React/HTML/CSS-код (Bootstrap-дефолты, ад-хок Tailwind) и просит
сделать красивее БЕЗ поломки состояния, эффектов, API-вызовов, обработчиков событий, роутинга.
3) Финальная проверка любого сгенерированного design-orchestrator/frontend-design/design-taste артефакта перед сдачей —
нужен механический PASS/FAIL чек-лист, а не субъективное "выглядит нормально".
|
Design Guardrails — верификация вместо «на глаз похоже»
Источник механики: Yu-369/VibeCurb (MIT, 298★, ресёрч канала @usefulrepa 2026-07-20). Полные вендор-копии двух исходных скиллов (pixel-perfect-replication, visual-redesign) — references/pixel-perfect-full.md и references/visual-redesign-full.md. Этот файл — обобщённая рабочая механика для нашей дизайн-семьи (не привязана к конкретному npm-CLI VibeCurb, только к паттерну).
Зачем это НЕ дублирует наше
У нас уже есть design-taste (шкалы вкуса + список AI-tells) и frontend-design/design-orchestrator (генерация). Ни один из них не верифицирует результат против эталона механически. design-taste — про вкус ДО и ВО ВРЕМЯ генерации. design-guardrails — про доказательство ПОСЛЕ: реальный PASS/FAIL по категориям, а не самоотчёт «сделал красиво». Это ортогональная функция — из семьи VibeCurb берём именно её.
Общий пайплайн (5 стадий, применяется к обоим сценариям ниже)
1. Design Read — извлеки сигналы ДО кода: из референса (скриншот/URL) ИЛИ из аудита существующего кода
2. Quality Gate 1 — не начинай писать код/CSS, пока extraction/audit не заполнены конкретными значениями
3. Precise Build — строй/правь с точным соответствием извлечённому, слой за слоем (не всё сразу)
4. Visual Diff — сверь результат с эталоном по PASS/FAIL таблицам (см. ниже)
5. Drift Rejection — если что-то не прошло: CSS keyword-easing (ease-in-out), AI-purple, div-фейк-скриншоты,
plain-text wordmarks вместо логотипов, placeholder-паттерны — отклони и переделай тот слой
Ни одна стадия не пропускается. Провал Quality Gate блокирует переход к следующей стадии.
Сценарий A: скриншот/референс → точный код (Pixel-Perfect)
Реф = спецификация. Твоя роль — переводчик, не дизайнер. Полная методика (7 слоёв извлечения) — references/pixel-perfect-full.md.
Extraction Sheet (7 слоёв, заполняй КОНКРЕТНЫМИ значениями, не «примерно»)
| Слой | Что измеряешь |
|---|
| 1. Layout Grid | max-width контейнера, колонки, отступы, высоты секций, выравнивание |
| 2. Typography | шрифт (по форме букв: a однокорпусная/двухкорпусная, g открытый/закрытый хвост, R/Q), вес, размер, line-height, tracking — на КАЖДЫЙ текстовый элемент отдельно |
| 3. Color | точный hex на каждую роль (bg/text/accent/border/shadow), не «синеватый» |
| 4. Spacing | базовая единица, паддинги кнопок/карточек, grid-gap, секционные отступы (верх и низ ОТДЕЛЬНО — часто не равны) |
| 5. Components | радиус углов (единый язык: sharp/subtle/rounded/pill/mixed-с-правилом), border, shadow, состояния |
| 6. Atmosphere | шум/grain, radial glow, frosted glass, градиенты, тонированные тени — добавляй, ТОЛЬКО если референс их показывает |
| 7. Responsive/Interaction | сигналы поведения из статики: sticky-nav, carousel-точки, что схлопнется на мобильном |
Артистичные ассеты (фото/иллюстрации/текстуры) — CSS их не воспроизводит. Классифицируй каждый визуальный элемент: solid-цвет/градиент/геометрия → CSS ок; фото/hand-drawn/органичные текстуры → генерируй изображение (generate_image/nano-banana) или picsum.photos/seed/{keyword}/{w}/{h}, НИКОГДА не аппроксимируй CSS-градиентом — глаз мгновенно ловит разницу.
Visual Diff — PASS/FAIL (прогони после сборки)
Категории: Layout (порядок и число секций, max-width, grid-ratio, вертикальные отступы, выравнивание) · Typography (шрифт, вес, line-height, tracking по каждому уровню) · Color (bg/text/accent/border — точные hex, не «похоже») · Component (радиус, паддинг, тень, стиль навигации) · Spacing (все гэпы из слоя 4) · Atmosphere (только то, что видно на референсе — не добавляй лишнего) · Technical (0 console-ошибок, шрифты загружены, нет horizontal overflow, min-h-[100dvh] не h-screen, prefers-reduced-motion).
Каждая строка — PASS или FAIL. Любой FAIL блокирует сдачу.
Сценарий B: редизайн существующего РАБОЧЕГО кода (Sacred vs Slop)
Полная методика (5 фаз + Post-Op) — references/visual-redesign-full.md. Правило №1: JS-логика неприкосновенна.
Sacred vs Slop — классификация ПЕРЕД любой правкой
SACRED (никогда не трогать):
useState/useReducer, useEffect/useCallback/useMemo, API-вызовы, ЛОГИКА обработчиков (не то, как выглядит кнопка,
а что происходит по onClick), условный рендеринг, роутинг, валидация форм, контексты, кастомные хуки,
трансформации данных (map/filter/reduce), error handling, prop-интерфейсы, ref-присвоения, aria-*/data-*/id
(если используются в JS/тестах)
SLOP (апгрейдь агрессивно):
className-строки, инлайн-стили НЕ завязанные на state, CSS/SCSS файлы, Tailwind/Bootstrap-классы,
цвета/шрифты/spacing/radius/тени/transition/z-index значения, layout-структура (flex/grid конфиг),
обёрточные div'ы ДЛЯ ВЁРСТКИ (не для условной логики)
Серая зона: className={isActive ? 'active' : ''} — тернарник неприкосновенен, но САМИ имена классов — slop ('nav-link--active' : 'nav-link'). style={{display: isOpen ? 'block' : 'none'}} — это state-логика, не трогать. Золотое правило серой зоны: если не уверен — не трогай, добавь стили РЯДОМ, а не вместо.
Пайплайн: Audit → Extraction → Prescription → Surgery → Post-Op
- Audit — прочитай каждый файл, заполни таблицу Sacred/Slop/Risk (Low/Medium/High) на файл, каталогизируй конкретные «эстетические преступления» (не «выглядит плохо», а «
box-shadow: 0 2px 4px rgba(0,0,0,0.1) — дефолтная Bootstrap-тень»).
- Extraction — зафиксируй ТЕКУЩИЕ значения (7 слоёв как в сценарии A) — это снимок «до».
- Prescription — для каждого slop-пункта распиши целевую замену с обоснованием («почему»). Один accent-цвет на весь проект, не рандомный.
- Surgery — правь ОДИН слой за раз (tokens → typography → color → spacing → components → atmosphere → motion), тестируй после каждого слоя. Предпочитай НОВЫЙ CSS-файл, подключённый последним в каскаде (
gold.css), а не правку существующих стилей — это делает откат тривиальным. НИКОГДА не переписывай JSX-структуру ради эстетики — только className/style/data-* добавления.
- Post-Op — прогони чек-листы ниже. Любой FAIL в Functionality блокирует всё остальное — сначала откати слой и разберись.
Post-Op чек-листы — PASS/FAIL
Functionality (Sacred Integrity) — все роуты грузятся · формы отправляются · API-вызовы возвращают и рендерят данные · все state-тогглы работают · все обработчики стреляют · 0 console-ошибок · 0 TS-ошибок · нет undefined property errors.
⚠ Если хоть один Functionality-чек FAIL — откат последнего слоя, разбор причины ДО перехода к визуальным чекам.
Visual/Atmosphere/Motion/Responsive — см. полные таблицы в references/visual-redesign-full.md (Phase 5). Ключевое: gold.css можно удалить одной строкой и откатить ВСЁ визуальное; ни один существующий CSS-файл не удалён (safety net); ни одной структурной правки JSX.
Drift Rejection — быстрый словарь дефолтов, которые ловим и отклоняем
CSS keyword-easing (ease-in-out без cubic-bezier) · AI-purple/неоновые градиенты · div-based fake screenshots · plain-text wordmarks вместо реальных SVG-логотипов в logo wall · placeholder-паттерны (// TODO, lorem ipsum в финальной сдаче) · Bootstrap-синий #0d6efd как «акцент» · zebra-striped таблицы без причины.
Полный список AI-tells (60+, em-dash, eyebrow-инфляция, Jane Doe и т.д.) уже покрыт в design-taste — не дублируется здесь, при обнаружении нарушения сверяйся с тем скиллом.
Когда НЕ этот скилл
Нет референса и нет существующего кода — это генерация с нуля, иди в frontend-design/design-orchestrator + design-taste. Этот скилл включается, когда есть ЭТАЛОН для сверки (изображение или живой код), а не когда рисуешь с чистого листа.