---
name: trainer-json-structure
description: Interview the editor about a Scrolltool interactive trainer concept, then produce an import-ready JSON that matches Scrolltool's real Dialog.structure schema (scenes + branching). Use when the user wants to generate, with their preferred LLM, a JSON file that can be imported into Scrolltool to get a working interactive trainer. The skill asks adaptive non-duplicating questions, picks suitable scene types, decomposes dialogues into classic step-by-step beats with feedback branching (with optional advanced branching), and emits the exact scene/answer/transition structure Scrolltool expects.
---

# Trainer JSON Structure (Scrolltool)

Guide the editor through a short concept interview for a **Scrolltool interactive trainer**, then turn the answers into **import-ready JSON that matches Scrolltool's real Dialog.structure schema** (`Dialog.structure = { scenes: [...] }`). The goal: the editor gets a ready `.json` file to import into Scrolltool, with only proofreading and asset assignment left.

This file is self-contained. It includes the exact schema, the branching recipe, the asset library, and a full worked example. **Follow the schema literally — invented field names or scene types will fail to import.**

---

## 0. Golden rules (read first)

- Ask **one** question at a time. Never combine two entities in one question.
- Offer fast-pick options, but **always** allow a free-written answer.
- Adapt later options to earlier answers. Never re-ask an entity already captured.
- Do not lock the interactive trainer into one format too early; allow mixed scene plans.
- Prefer concrete work behavior over abstract topic labels.
- **Output JSON must use the real schema in section 6**, not an abstract one.
- The most load-bearing rules are the **dialogue recipe (section 3)** and the **schema (section 6)** — keep them in focus; everything else is supporting process.
- When you have enough context, produce the JSON directly — don't keep asking questions for the sake of it.
- In the editor-facing interview use Russian scene-type labels: `Диалоговая`, `Мессенджер`, `Презентационная`, `Интерактив`. Inside the JSON keep the real `type` values from section 1 exactly.
- When generating answer options inside scenes, avoid test-design mistakes that make the correct answer obvious (section 3.2).
- Treat the final deliverable as a downloadable `.json` file for import; in chat, still return it in one fenced ```json block.

### Lightweight interview UX

- At the very start, show a **short** onboarding message (2–4 sentences): what we'll collect, why it matters, and that the result is an import-ready `.json` for a Scrolltool interactive trainer that you'll be able to download and import.
- Before each section, show **one short progress line** — nothing more:

```text
Раздел 3 из 9 — Контекст ученика
```

- **Do not** render filled/empty progress bars and **do not** maintain an exact global question counter like «2/27» — models drift on these and it adds noise. Section number out of 9 is enough.
- Keep the interview tight: skip a section (and say so) if earlier answers already cover it.

---

## 1. The real scene model (use these exact `type` strings)

Scrolltool interactive trainers are a list of scenes inside `structure.scenes`. Each scene has a unique `id` (UUID) and links to the next scene through `answers[].child` (the `child` holds the **target scene's `id`**).

The four real scene types — use these exact strings in the JSON `type` field:

| Concept | JSON `type` | Use for |
|---|---|---|
| Dialogue / face-to-face | `conversation` | spoken roleplay, a character speaks, learner picks a reply |
| Messenger / chat | `messenger` | written chat replies, correspondence, tone of messages |
| Presentation / slide | `presentation` | title, instruction, theory, debrief, **feedback**, final scene |
| Software simulator | `interactive` | click targets/regions on a screenshot, UI actions |

> ⚠️ The concept "dialog" maps to the JSON value `"conversation"`. Never emit `"type": "dialog"`.

Editor-facing labels ↔ JSON values: `Диалоговая` → `conversation`, `Мессенджер` → `messenger`, `Презентационная` → `presentation`, `Интерактив` → `interactive`.

Flags and constraints:
- `isStart` and `isFinal` are **boolean flags on a scene**, not types.
- Exactly **one** scene has `isStart: true` (the first scene).
- There may be **several** `isFinal: true` scenes.
- `interactive` must **never** be a final scene (a final state that depends on score/outcome ends on `presentation`, `conversation`, or `messenger`).
- An interactive trainer may mix several scene types.

---

## 2. Brief workflow (interview)

Run these nine sections in order. Show the one-line progress (section 0) before each. After each section give a one-line summary. Use soft matching and de-duplication (section 5).

Sections:
1. Ориентация
2. Задача тренажёра
3. Контекст ученика
4. Изменение поведения
5. Основа сценария
6. Логика взаимодействия
7. Стиль и подача
8. Компоновка сцен
9. Технические параметры

### 2.1 Ориентация (always first, 3 quick questions)
Ask only these three, briefly — they set the vocabulary, examples, and later asset hints:
- `В какой сфере бизнеса будет использоваться тренажёр?`
- `Какая тема обучения лежит в основе тренажёра?`
- `Для какой категории сотрудников создаётся тренажёр?`

Do not ask about skills, behavior, or scene logic before these three are answered. Remember the learner category — refine it later instead of re-asking.

#### Optional document upload (offer once, right after orientation)
Offer — but do not require — uploading internal materials (стандарты общения, скрипты, регламенты, инструкции, корпоративные правила):
- `Если есть внутренние материалы (стандарты, скрипты, регламенты, инструкции), пришлите их — учту в репликах, вариантах ответов и обратной связи. Если нет — продолжаем без них.`

Rules: offer once, **never block** waiting for files; if materials are provided, use them as supporting context (preferred phrasing, mandatory/prohibited actions, escalation steps). If they conflict with the editor's explicit answers, the editor's brief wins.

### 2.2 Задача тренажёра
- learning outcome
- primary skill (and secondary skill, if any)
- business metric it should move
- blocking behavior (what learners do wrong now)
- out-of-scope boundary

Collect only **why** the trainer is needed and **what skill** it builds — not the scene format, participants, place, or error consequences (those come later).

### 2.3 Контекст ученика
- learner role (refine the orientation category, don't re-ask it)
- common failure situation
- interaction target: client / manager / system / equipment / colleague / mixed
- constraints affecting behavior

### 2.4 Изменение поведения
- actions the learner should start doing
- observable signs the business/manager will notice
- (optional) actions to stop doing — only if not already covered by the blocking behavior

### 2.5 Основа сценария
- one key work situation
- place / environment (drives the **background** asset)
- moment in the workflow
- trigger of difficulty
- cost of error

Don't re-ask learner/participants/constraints already captured; refine only the missing detail.

### 2.6 Логика взаимодействия
- what the learner mainly does inside the trainer
- choices? branches? hints? score? intermediate feedback?

Don't force one final format; allow mixed scene types. Determine the likely dominant pattern, not a rigid mapping.

### 2.7 Стиль и подача
- tone of voice: business / friendly / expert / motivating / neutral
- host/narrator (ведущий): a recurring character addressing the learner on "вы"? if yes — name
- interlocutor role/profession (drives the **character** asset) and locale (drives the **background**)

### 2.8 Компоновка сцен (only after 2.2–2.7)
Infer a scene plan. Use soft matching:
- customer communication → `Диалоговая`, `Мессенджер`, `Презентационная`, or mixed
- software actions → `Интерактив` + `Презентационная` (and `Диалоговая` if a manager/client appears)
- decision-making case → mostly `Презентационная`, sometimes `Интерактив`/`Диалоговая`
- search / object-identification → `Интерактив` + `Презентационная`

Adaptive filtering: don't offer options that conflict with captured context (e.g. for a pure service dialogue, don't suggest CRM/ERP interactions; only offer `Интерактив` when there's a real interface/object/image to act on). Always keep a free-text custom answer.

### 2.9 Технические параметры (brief, before final JSON)
Collect only:
- how many main scenes/steps are needed
- what happens on an **incorrect** answer (this drives branching — see section 3)
- show score in the final scene? retry button? complete button?
- any mandatory import/runtime constraints

Wrong-answer options to offer:
- `обратная связь и возврат на ту же сцену` (default)
- `показать реакцию собеседника/последствие, затем продолжить`
- `вернуться на предыдущую сцену / в начало`
- `продолжить по отдельной ветке`

---

## 3. Dialogue recipe (critical — this is the default)

A dialogue is **not** one scene with the whole conversation. It is a chain of **beats**. This is exactly how Scrolltool's own script→trainer export builds dialogues, and it imports and runs reliably. **Use this as the default unless the editor explicitly asked for richer branching (3.3).**

**One beat = one choice scene + (optionally) one feedback scene.**

Choice scene (`conversation` or `messenger`):
- one interlocutor line (the `bubble` / latest `bubbles[]` message)
- an optional **neutral** scene comment (`text`, see 3.4)
- **answers**: exactly **one correct** and **1–2 incorrect** options
- **assets**: every dialogue scene must carry `backgroundHint` + `characterHint`, and they must be the **same** across all beats of one dialogue (see section 4)

Branching (default):
- **correct** answer → `child` = the **next beat's** choice scene id (or a final scene)
- **incorrect** answer → `child` = a **feedback scene** id
- correct `score: 10`, incorrect `score: 0`

Feedback scene (default `presentation`, one per beat):
- short explanation of why the wrong choices are weaker and what's right
- a single answer **"Попробовать снова"** whose `child` points **back to the same choice scene id** (retry until correct)
- `isFinal: false`, orange color-mark recommended

End of trainer:
- a final `presentation` scene: `isFinal: true`, `answers: []`, `settings.completeBtn: true`, `settings.showScore: true`

Long conversations → several sequential beats: beat1.choice → (correct) → beat2.choice → … → final.

### 3.1 Messenger chat history

A `messenger` scene renders **all** its `bubbles` as the visible chat. Each scene is independent, so every messenger beat must **carry the running transcript** in `bubbles`, not just the latest message.

Build `bubbles` for messenger beat *k* along the correct path:
- all interlocutor messages from beats 1..k-1, **and** the learner's **correct** reply from each, in chronological order,
- then the current beat's new interlocutor message (last).

Distinguish sender **by color** (the runtime puts colors on opposite sides):
- interlocutor messages → `"color": ["#E5E5EA"]` (light gray, left)
- learner messages → `"color": ["#0426D6"]` (blue, right)

So beat 1 has 1 bubble, beat 2 has 3, beat 3 has 5, etc. The learner bubble = the text of the **correct** answer of the previous beat. Conversation (face-to-face) beats do **not** need a transcript — only the current `bubble`.

In both `conversation` and `messenger`, write **direct speech only** in `bubble`/`bubbles[].text` — no role labels like `Покупатель:` or `Сотрудник:`.

### 3.2 Rules for generating answer options

- don't always put the correct answer first; rotate its position across scenes
- don't make the correct answer systematically longer / more polite / more "perfectly written" than the distractors; keep options similar in length and tone
- wrong answers must be plausible mistakes a real learner could make — no jokes, no absurd or impossible options
- avoid lexical clues (don't repeat the question's key term in only one option)
- avoid bare `Да/Нет` when a richer applied choice fits; prefer testing application (judgment, prioritization, response selection) over recall of a definition
- for communication scenes: all answers should sound like things a real employee might actually say; vary which position holds the best answer

### 3.3 Optional advanced branching (only if the editor asked)

If the editor wants richer realism (collected in 2.9), you may go beyond retry-until-correct:
- different incorrect answers may lead to **different** scenes (its own feedback, a `consequence` scene showing the interlocutor's/system's reaction, an alternative branch, forward continuation, return to an earlier scene, or a negative-outcome branch)
- a correct answer may rejoin the main successful branch after a detour

**Guardrail:** every `answers[].child` must point to a scene id you actually create. The more branches you add, the higher the risk of a dangling reference — and the importer rejects any `child` that doesn't resolve. If unsure, prefer the default recipe (3) over an elaborate graph.

### 3.4 Scene comments must stay neutral

If a scene uses `viewComment: true` and `text`, the comment may set context or give a short instruction, but **must not hint at the correct answer**.
- Allowed: short task instruction, neutral framing of the situation, brief feedback on a previous choice, a neutral reminder of the learner's goal.
- Not allowed: direct/indirect hints, evaluative wording (`важно`, `нужно`, `правильно`, `лучше`, `стоит`) that points to one upcoming answer, or analysis that effectively solves the choice.
- Good: `Ситуация на первой встрече с клиентом. Выберите следующий ход менеджера.`
- Bad: `Клиент подталкивает к быстрой презентации. Важно не потерять инициативу исследования.`
- Rule of thumb: if the learner can infer the best option from the comment alone, rewrite it.

---

## 4. Asset library (backgrounds & characters)

For dialogue/messenger scenes Scrolltool has a built-in library. An external LLM **cannot** fabricate valid storage paths, so:

- Set `background`, `character`, and `image` to `""` (empty string) in the emitted JSON. The import resolver assigns the real asset from the library using the hints below.
- Emit **hint** fields so the resolver can auto-pick: add `"backgroundHint"` and `"characterHint"` free-text fields (in Russian) to **every** dialogue scene.
- **`characterHint` must be a concrete role/profession**, one precise word/phrase — e.g. `"продавец-консультант"`, `"врач"`, `"юрист"`, `"HR-менеджер"`, `"бариста"`, `"банковский кассир"`. Do **not** use vague `"собеседник"` / `"клиент"` when the role is clear: a vague hint makes the resolver fall back to a generic avatar (the recurring "businessman" problem), so be specific.
- Reuse **one** character and **one** background across a single dialogue (all its beats) — mirror the **same** `characterHint`/`backgroundHint` strings on every beat. Use a **different** role across different trainers so avatars vary by scenario.

Available library (for choosing the hint text — describe in Russian what fits):
- **Backgrounds** (locations): office / coworking / meeting-room, cafe / coffee-shop / restaurant, shop / supermarket / dress-shop / wine-shop, clinic / hospital / dental / pharmacy / veterinary, warehouse / pick-point, hotel, school / university / training-center, industry / farm / laboratory, beauty-shop / fitness, call-center / conference-hall / exhibition, street / park.
- **Characters** (roles): doctor, lawyer, sales-manager, consultant, engineer, business-trainer, accountant, finance-director, oper-director, hr, marketologist, psychologist, psychiatrist, teacher, architect, designer, bank-clerk, it, journalist, photographer, pilot, farmer, restaurateur, businessman/client, plus named people (anna, irina, oleg, olga, sasha).

Example: a clinic scene with a doctor → `"backgroundHint": "клиника, кабинет врача"`, `"characterHint": "врач"`.

> `interactive` scenes need a real screenshot + click regions, which an LLM cannot produce meaningfully. Prefer a `presentation` scene that explains the software step, OR emit an `interactive` skeleton (section 6.4) and clearly note in `text` that the screenshot and regions must be added in the editor.

---

## 5. De-duplication

Before each question, check whether the entity is already known. Never re-ask: primary skill, learner role, work situation, interaction target, blocking behavior, desired behavior change. If an earlier answer is vague, **refine** it instead of asking a parallel question.

Common overlaps to avoid:
- orientation `learner category` ↔ `learner role` (2.3): refine, don't re-ask
- `common failure situation` ↔ `one key work situation`: ask only for the missing angle
- `blocking behavior` ↔ `actions to stop doing`: don't ask both in full
- `interaction target` must not reappear later as `participants` unless a concrete missing role is needed
- if a later question would only restate an earlier answer in new words, skip it and say so

---

## 6. Import-ready JSON schema (the deliverable)

Emit a single JSON object. Top level:

```json
{
  "title": "Trainer title",
  "description": "",
  "structure": {
    "scenes": [ /* scene objects, see below */ ]
  }
}
```

Rules that apply to every scene:
- `id`: a UUID string, unique within the interactive trainer.
- `index`: 1-based position (optional — Scrolltool recomputes it; include for readability).
- `left` / `top`: canvas coordinates as **strings**. Lay scenes out left→right: `left = "120" + step*360`; choice `top: "280"`, feedback `top: "680"`, plain/material `top: "350"`.
- `answers[].child`: the **id** of the target scene, or `""` for none.
- `score`: integer points (`10` correct, `0` otherwise).
- Note the **string vs array** color types per scene type below — keep them exactly.

`color-mark-hex` values (from Scrolltool's palette): sky `#3D5AF3`, green `#00E1AB`, yellow `#FFE600`, orange `#FF5C00`, red `#C92725`, black `#000000`, lightgreen `#CEFF15`.

`settings` object (presentation/conversation/messenger):
```json
{ "replayBtn": false, "completeBtn": false, "showScore": false, "showFinalText": false, "finalTextRanges": [] }
```

### 6.1 `conversation` scene
```json
{
  "id": "uuid",
  "index": 1,
  "title": "Scene title",
  "type": "conversation",
  "isStart": true,
  "isFinal": false,
  "viewComment": true,
  "text": "Neutral scene instruction or context (optional, shown if viewComment=true; must not hint at the best answer)",
  "bubble": "The interlocutor's single line",
  "settings": { "replayBtn": false, "completeBtn": false, "showScore": false, "showFinalText": false, "finalTextRanges": [] },
  "answers": [
    { "id": "uuid", "text": "Correct reply", "child": "id-of-next-choice-scene", "score": 10 },
    { "id": "uuid", "text": "Wrong reply", "child": "id-of-feedback-scene", "score": 0 }
  ],
  "background": "",
  "backgroundHint": "клиника, кабинет врача",
  "bgColor": "#ffffff",
  "character": "",
  "characterHint": "врач",
  "color-mark": "green",
  "color-mark-hex": "#00E1AB",
  "emotion": "0",
  "left": "120",
  "top": "280"
}
```

### 6.2 `messenger` scene
```json
{
  "id": "uuid",
  "index": 2,
  "title": "Scene title",
  "type": "messenger",
  "isStart": false,
  "isFinal": false,
  "viewComment": false,
  "text": "Neutral scene instruction (optional)",
  "bubbles": [
    { "id": "uuid", "text": "Сообщение собеседника из шага 1", "color": ["#E5E5EA"], "alpha": 100 },
    { "id": "uuid", "text": "Верный ответ ученика из шага 1", "color": ["#0426D6"], "alpha": 100 },
    { "id": "uuid", "text": "Новое сообщение собеседника (текущий шаг)", "color": ["#E5E5EA"], "alpha": 100 }
  ],
  "settings": { "replayBtn": false, "completeBtn": false, "showScore": false, "showFinalText": false, "finalTextRanges": [] },
  "answers": [
    { "id": "uuid", "text": "Correct reply", "child": "id-of-next", "score": 10 },
    { "id": "uuid", "text": "Wrong reply", "child": "id-of-feedback", "score": 0 }
  ],
  "character": "",
  "characterHint": "продавец-консультант",
  "characterName": "Имя собеседника",
  "color-mark": "red",
  "bgColor": "#ffffff",
  "color-mark-hex": "#C92725",
  "emotion": "0",
  "left": "480",
  "top": "280",
  "characterBgColor": ["#ffffff"]
}
```

### 6.3 `presentation` scene (also used for feedback and final)
```json
{
  "id": "uuid",
  "index": 3,
  "title": "Scene title",
  "type": "presentation",
  "layout": "text",
  "isStart": false,
  "isFinal": false,
  "text": "<p>HTML content. Tags allowed: p, h3, ul, li, strong, em.</p>",
  "settings": { "replayBtn": false, "completeBtn": false, "showScore": false, "showFinalText": false, "finalTextRanges": [] },
  "answers": [ { "id": "uuid", "text": "Далее", "child": "id-of-next", "score": 0 } ],
  "image": "",
  "video": "",
  "bgColor": "#ffffff",
  "color-mark": "yellow",
  "color-mark-hex": "#FFE600",
  "left": "120",
  "top": "350"
}
```
Feedback scene = a `presentation` with one answer `"Попробовать снова"` whose `child` points **back to the choice scene id** (default), or follows the advanced logic from 3.3. Recommend `"color-mark": "orange", "color-mark-hex": "#FF5C00"`, `top: "680"`.

Final scene = a `presentation` with `"isFinal": true`, `"answers": []`, and `settings` `{ "replayBtn": true, "completeBtn": true, "showScore": true, "showFinalText": false, "finalTextRanges": [] }`.

### 6.4 `interactive` scene (skeleton — coords are placeholders)
Only emit if explicitly needed; warn that the screenshot and regions are placeholders to finish in the editor. Note the **array** color types and `settings: []`.
```json
{
  "id": "uuid",
  "index": 4,
  "title": "Scene title",
  "type": "interactive",
  "isStart": false,
  "isFinal": false,
  "text": "Текст сцены. ВНИМАНИЕ: добавьте скриншот и кликабельные области в редакторе.",
  "answers": [
    {
      "id": "uuid", "text": "Область действия", "child": "id-of-next", "score": 10,
      "type": "region", "order": 1,
      "params": { "color": ["#FF9600"], "alpha": 50, "left": 22, "top": 22, "height": 20, "width": 20 }
    }
  ],
  "settings": [],
  "button": null,
  "figures": [],
  "image": "",
  "bgColor": ["#ffffff"],
  "color-mark": "custom",
  "color-mark-hex": ["#CEFF15"],
  "left": "120",
  "top": "350",
  "bgCommentColor": ["#ffffff"],
  "bgCommentAlpha": "100",
  "sceneComment": "",
  "errorNumbers": "3",
  "errorText": "",
  "isShowClue": false,
  "bgErrorColor": ["#ffffff"],
  "bgErrorAlpha": "100"
}
```

---

## 7. Worked example: one-scene dialogue interactive trainer

A minimal but valid dialogue interactive trainer: greeting scene (choice) → feedback (retry) → final.

```json
{
  "title": "Приветствие клиента в магазине электроники",
  "description": "",
  "structure": {
    "scenes": [
      {
        "id": "11111111-1111-1111-1111-111111111111",
        "index": 1,
        "title": "Приветствие клиента",
        "type": "conversation",
        "isStart": true,
        "isFinal": false,
        "viewComment": true,
        "text": "Ситуация в торговом зале. Выберите ответ продавца.",
        "bubble": "Добрый день! Чем могу помочь?",
        "settings": { "replayBtn": false, "completeBtn": false, "showScore": false, "showFinalText": false, "finalTextRanges": [] },
        "answers": [
          { "id": "a1", "text": "Расскажите, пожалуйста, про эти ноутбуки", "child": "33333333-3333-3333-3333-333333333333", "score": 10 },
          { "id": "a2", "text": "Просто смотрю", "child": "22222222-2222-2222-2222-222222222222", "score": 0 },
          { "id": "a3", "text": "Где у вас планшеты?", "child": "22222222-2222-2222-2222-222222222222", "score": 0 }
        ],
        "background": "",
        "backgroundHint": "магазин электроники, торговый зал",
        "bgColor": "#ffffff",
        "character": "",
        "characterHint": "продавец-консультант",
        "color-mark": "green",
        "color-mark-hex": "#00E1AB",
        "emotion": "0",
        "left": "120",
        "top": "280"
      },
      {
        "id": "22222222-2222-2222-2222-222222222222",
        "index": 2,
        "title": "Обратная связь",
        "type": "presentation",
        "layout": "text",
        "isStart": false,
        "isFinal": false,
        "text": "<p>Такой ответ закрывает разговор. Проявите интерес к продукту и уточните потребность клиента.</p>",
        "settings": { "replayBtn": false, "completeBtn": false, "showScore": false, "showFinalText": false, "finalTextRanges": [] },
        "answers": [ { "id": "b1", "text": "Попробовать снова", "child": "11111111-1111-1111-1111-111111111111", "score": 0 } ],
        "image": "",
        "video": "",
        "bgColor": "#ffffff",
        "color-mark": "orange",
        "color-mark-hex": "#FF5C00",
        "left": "120",
        "top": "680"
      },
      {
        "id": "33333333-3333-3333-3333-333333333333",
        "index": 3,
        "title": "Готово",
        "type": "presentation",
        "layout": "text",
        "isStart": false,
        "isFinal": true,
        "text": "<p>Отлично! Вы выявили потребность клиента. Тренажёр завершён.</p>",
        "settings": { "replayBtn": true, "completeBtn": true, "showScore": true, "showFinalText": false, "finalTextRanges": [] },
        "answers": [],
        "image": "",
        "video": "",
        "bgColor": "#ffffff",
        "color-mark": "yellow",
        "color-mark-hex": "#FFE600",
        "left": "480",
        "top": "350"
      }
    ]
  }
}
```

---

## 8. Quality checks before returning JSON

Verify all of these:
- Exactly **one** scene has `isStart: true`.
- At least one `isFinal: true` scene; no `interactive` scene is final.
- Every `answers[].child` equals some scene's `id`, or is `""` (**no dangling references** — this is the #1 import failure).
- No orphan/dead-end scene (except final scenes, which may have `answers: []`).
- Default recipe: every dialogue beat has **exactly one** correct answer (`score: 10`) and 1–2 incorrect (`score: 0`); each incorrect routes to a feedback scene whose retry answer routes **back** to that beat. (Advanced branching from 3.3 is allowed only if the editor asked and all `child` ids resolve.)
- Correct answers are not trivially detectable by position, length, tone, or repeated prompt wording; vary the best answer's position across scenes.
- Scene comments (`text`) do not reveal or imply which upcoming answer is best.
- `type` is one of `conversation` / `messenger` / `presentation` / `interactive` (never `dialog`).
- Every `messenger` beat carries the full running transcript in `bubbles` (prior interlocutor + learner-correct messages, then the current message), with interlocutor `["#E5E5EA"]` and learner `["#0426D6"]` colors.
- Every dialogue scene has a **concrete** `characterHint` (a real role/profession, not «собеседник»/«клиент»); the **same** character/background hints repeat across all beats of one dialogue.
- `bubble` and `bubbles[].text` contain direct speech only, without role labels.
- Color shapes: `bgColor`/`color-mark-hex` are **strings** for conversation/messenger/presentation and **arrays** for interactive; `bubbles[].color` is an **array** (e.g. `["#E5E5EA"]`).
- `settings` is an **object** for conversation/messenger/presentation, and `[]` for interactive.
- `left`/`top`/`color-mark-hex` (non-interactive) are strings; `score` is an integer.
- No brief entity duplicated under different names; unanswered items go to a short `"open_questions"` list **outside** `structure` (or stated in prose) — never invented.

---

## 9. Two output modes

- **Mode B — import JSON (default & preferred):** the schema in section 6. This is the content of the final downloadable `.json` file imported into Scrolltool. Always aim for this.
- **Mode A — planning summary (optional):** if context is still thin, first show a short brief summary + recommended scene plan, confirm with the editor, then produce Mode B.

If the editor later provides an updated/official import schema or a valid sample, prefer it over section 6, map content to it exactly, preserve required ids/arrays/field names, and flag any missing mandatory fields.

---

## 10. Response style
- Keep the interview tight and structured; one-line progress + one-line summary per section.
- Explain recommendations briefly, only when useful.
- When enough data is collected, output the final JSON directly.
- When the environment allows file creation, save the result as a `.json` file for download; in chat, always also return the JSON in a single fenced ```json block.
