Инструкция: Извлечь компоненты из лендинга

Trigger: пользователь говорит что нравится в готовом лендинге — "оставь hero, карточки норм, форма не нужна". Или явно — "вынеси понравившееся в компоненты".

Uses: instructions/create_landing_page, instructions/landing_brief

Зачем

Bottom-up дизайн-система: компоненты появляются из реальных лендингов, не проектируются заранее. Следующий лендинг переиспользует готовое, не выдумывает заново.

Структура хранения

_layouts/
  v1/                       ← первая тема
    tokens.md               ← палитра, шрифты, радиусы
    landing.html            ← layout для лендинга
    instaframe.html         ← layout для карусели (когда добавим)
    components/
      _index.md             ← каталог
      hero.md               ← один компонент = Jet block + превью + usage
      problem_card.md
      step.md
      cta_block.md
  v2/                       ← следующая тема (когда понадобится)
    ...

Никогда не удалять старые версии. Только добавлять новые.

Шаги

1. Определи целевую версию темы

ls /opt/data/secondbrain/_layouts/
  • Если тем нет — создавай v1
  • Если есть v1 без нужного компонента — добавляй в v1
  • Если стиль другой (новая палитра/шрифты) — создавай v2

2. Выясни у пользователя что именно нравится

Если пользователь сказал общо ("hero норм, карточки тоже"):

"Ок. Что именно вынести как компонент:

  1. Hero — заголовок + лид + CTA + правая панель
  2. Карточки проблем — 3 в ряд, иконка + лид + описание
  3. Шаги "Как работает" — нумерованные блоки
  4. Финальный CTA — баннер с заголовком и кнопкой
    Какие из них?"

Зафиксируй явный список перед извлечением.

3. Извлеки токены в tokens.md

Из CSS лендинга достань переменные и значения:

---
free: false
---

# Tokens v1

## Палитра
- `--bg`: #080a0d
- `--fg`: #f4f7ef
- `--accent`: #c8ff5a
- `--muted`: #9da892
- `--rule`: rgba(255,255,255,.08)

## Типографика
- `--sans`: Manrope, system-ui, -apple-system, "Segoe UI", sans-serif
- `--mono`: ui-monospace, "JetBrains Mono", Menlo, monospace
- Заголовки: clamp(28px, 4vw, 78px), letter-spacing -0.04em
- Лид: 17–20px, line-height 1.55

## Радиусы и отступы
- `--radius-sm`: 14px
- `--radius-md`: 22px
- `--radius-lg`: 30px
- `--pad-section`: 58px 0

Если нужного значения нет в исходном лендинге — оставь TODO, пусть пользователь подскажет позже.

4. Извлеки каждый компонент в отдельный .md

Файл: _layouts/v1/components/<name>.md. Структура:

---
free: false
---

# Component: hero

## Назначение
Первый экран лендинга. Заголовок + лид + CTA + опциональная правая панель с примером.

## Параметры
- `title` (string) — главный заголовок
- `lede` (string) — подзаголовок 1-2 предложения
- `cta_url` (string) — ссылка кнопки
- `cta_text` (string) — текст кнопки
- `panel` (block, optional) — правая панель с примером

## Jet block

```jet
{{ block hero(title="", lede="", cta_url="", cta_text="", panel="") }}
<section class="hero">
  <div class="hero__text">
    <h1 class="hero__title">{{ title }}</h1>
    <p class="hero__lede">{{ lede }}</p>
    <a class="hero__cta" href="{{ cta_url }}">{{ cta_text }}</a>
  </div>
  {{ if panel }}<div class="hero__panel">{{ panel }}</div>{{ end }}
</section>
{{ end }}

{{ block _style_hero() }}
.hero { display: grid; grid-template-columns: 1.08fr .92fr; gap: 44px; align-items: center; margin-bottom: 72px; }
.hero__title { font-size: clamp(42px, 7vw, 78px); line-height: .93; letter-spacing: -0.06em; color: var(--fg); }
.hero__lede { font-size: 20px; line-height: 1.55; color: var(--muted); max-width: 660px; }
.hero__cta { display: inline-flex; align-items: center; border-radius: 999px; padding: 12px 18px; background: var(--accent); color: var(--bg); font-weight: 750; text-decoration: none; }
@media (max-width: 860px) { .hero { grid-template-columns: 1fr; } }
{{ end }}
```

## Пример использования

```jet
{{ yield hero(
  title="Созвоны сами становятся базой знаний",
  lede="Агент забирает записи и готовит бриф перед каждой встречей.",
  cta_url="https://t.me/iiminion",
  cta_text="Написать @iiminion"
) }}
```

## Откуда извлечён
- Лендинг: `[[agent_calls]]`
- Дата: YYYY-MM-DD

Правила:

  • BEM-классы привязаны к имени блока (.hero__title, не .title)
  • Цвета через CSS-переменные из tokens.md, не хардкод
  • Один компонент = один .md файл
  • Описание в свободной форме сверху, код в кодблоках

5. Обнови components/_index.md

# Components v1

## Доступные
- [[components/hero]] — первый экран с CTA и опциональной панелью
- [[components/problem_card]] — карточка проблемы (3 в ряд)
- [[components/step]] — нумерованный шаг для секции "Как работает"
- [[components/cta_block]] — финальный баннер с CTA

## Извлечены из
- [[agent_calls]] — 2026-05-22 (hero, problem_card, step, cta_block)

6. Создай landing.html который собирает компоненты

<!DOCTYPE html>
<html lang="{{ note.Lang() }}">
<head>
  <meta charset="UTF-8">
  <title>{{ note.Title() }}</title>
  <style>
    /* подключить tokens из tokens.md */
    {{ yield_blocks("_tokens") }}
    {{ yield_blocks("_style_") }}
  </style>
</head>
<body>
  {{ note.HTMLString() | unsafe }}
</body>
</html>

В заметке-лендинге пользователь / агент пишет:

{{ yield hero(title="...", lede="...", cta_url="...", cta_text="...") }}
{{ yield problem_card(title="...", body="...") }}
{{ yield step(n=1, body="...") }}

7. Залогируй в daily note

HH:MM user: <запрос на извлечение>
Извлечены компоненты в [[_layouts/v1/components/_index]]:
- [[components/hero]]
- [[components/problem_card]]
- ...
Тема v1 готова к переиспользованию.

8. Сообщи пользователю

"Готово. Тема v1: {TRIP2G_URL}/_layouts/v1/components/_index
Дальше любой лендинг можно собрать командой 'сделай лендинг используя v1'."

Что НЕ делать

  • ❌ Не извлекать компоненты которые пользователь явно не отметил
  • ❌ Не удалять v1 если делаешь v2 — версии живут параллельно
  • ❌ Не хардкодить цвета и шрифты в компонентах — только через переменные из tokens
  • ❌ Не делать компоненты слишком гибкими — лучше 5 простых чем 1 универсальный с 20 параметрами

Когда не извлекать

  • Лендинг сильно one-off (юбилейная страница, мемная)
  • Стиль сильно отличается от существующих тем — нужен v2, но сначала спроси пользователя

Кейсы

Кейс 1: Первая тема
Пользователь говорит "норм всё, оставь". → Создай v1, извлеки все секции, дай каталог.

Кейс 2: Добавить недостающий компонент
В v1 нет pricing_table. Сделай новый лендинг с прайсингом. Юзер: "прайсинг сохрани". → Добавь pricing_table.md в v1/components/, обнови _index.md.

Кейс 3: Новая тема
Юзер хочет светлый минималистичный лендинг. Сделай. Юзер: "это надо в новую тему". → Создай v2/ с новыми токенами и компонентами.