# Скіл 1 — розбір буклетів A12, рівні 0–4

Зимова розсилка інструкторам по Україні. Порядок робіт змінено: спершу
**A12 → B1 → B2**, серія A2 відкладена.

Витяг:

```bash
.venv/bin/python ua_build/extract.py Level0_A12 Level1_A12 Level2_A12 \
    Level3_A12 Level4_A12
```

| Буклет | Стор. | Блоків | Спанів | Контурних прогонів |
|---|---|---|---|---|
| Level0_A12 | 4 | 63 | 143 | 0 |
| Level1_A12 | 8 | 194 | 262 | 0 |
| Level2_A12 | 8 | 166 | 379 | 2 |
| Level3_A12 | 8 | 213 | 492 | 0 |
| Level4_A12 | 8 | 192 | 408 | 0 |

Усі п'ять — текстові PDF, OCR не потрібен. Обсяг тексту той самий, що в A1
(3 246 / 5 515 / 9 440 / 9 352 / 11 936 символів). Сторінок стільки ж,
стандартні блоки на місці й розподілені так само, як в A1: бланк повернення
скрізь, смуга B.E.S. на рівнях 0–3 (у рівні 4 її немає — як і в Level4_A1),
`Bible version` на рівнях 3–4, `KEY VERSE` на рівнях 2–4, `Adult Guidance`
лише в рівні 0.

Тобто структурних сюрпризів немає. Але розвідка знайшла дві речі, через які
конвеєр, налагоджений на A1, дав би **мовчазну** помилку.

---

## 1. Фірмовий колір належить буклету, а не рівню

`lessons.py` тримав по одному кольору на рівень — числа зняті з A1. Перевірка
всіх дванадцяти буклетів серії A показала, що на рівнях 0, 1 і подекуди 4
колір гуляє:

| | A1 | A2 | A3…A12 |
|---|---|---|---|
| рівень 0 | `b3579d` | `af589d` | `c452b4` (усі десять) |
| рівень 1 | `f49944` | `f49843` | `f49843`, а в A5, A8, A12 — `f28c00` |
| рівень 2 | `ea515a` | `ea515a` | `ea515a` (тримається скрізь) |
| рівень 3 | `009d78` | `009d78` | `009d78` (тримається скрізь) |
| рівень 4 | `3055a3` | `22326f` | `3055a3` (решта) |

Чому це дорого: `fields_detect.py` шукає варіанти відповіді **точною
рівністю** кольору (`sp["color"] == BRAND`, §3.3 крок 5). Розбіжність в один
байт — це «варіантів не знайдено», без жодного повідомлення. Той самий колір
іде в логотип (`rebrand.py`), і логотип у відтінку A1 стояв би поруч із
шапкою іншого тону.

**Виправлено.** `lessons.measure_colour()` міряє колір по самому буклету —
найчастіший колір за кількістю символів, крім чорного й білого; константа
рівня лишається запасом. Підключено в трьох місцях:

* `Lesson.colour` / `Lesson.colour_rgb` — виміряний колір буклета;
* `fields_detect.set_level(n, src)` — міряє по файлу, який розбирає;
* `brand.logo_for(colour)` — логотип під довільний колір, малюється раз і
  лишається в `data/logo/logo_<hex>.png`; `rebrand.py` бере його звідти.

Серія A1 від цього не змінилася: виміряний колір усіх п'яти буклетів A1
дорівнює старій константі, а згенеровані логотипи побайтово збігаються з
`logo_L0…L4.png`.

## 2. SassoonInfantRg — суцільний варіант дитячого шрифту

У A1 траплявся лише `SassoonInfantDtB` (Dt = dotted, для обведення по
крапках). У Level1_A12 на стор. 4 у **тому самому рядку** з'явився суцільний
`SassoonInfantRg`:

```
p4  SassoonInfantDtB 48pt  “For
p4  SassoonInfantRg  48pt  nothing        ← слово набране суцільним
p4  SassoonInfantDtB 48pt  will be
p4  SassoonInfantDtB 48pt  impossible with God.”
```

Тобто дитина обводить вірш, а одне слово вже надруковане — підказка-опора.
Шрифта не було в `FONTFILES`, і рендер упав би або підставив хибний.

**Виправлено:** `SassoonInfantRg` → `SFNSRounded.ttf`, та сама підміна, що й
для Dt. Крапки малює `puzzlekit.dotted_text()` — саме вона й відрізняє
пунктирний варіант від суцільного, тож один файл шрифта обслуговує обидва.

Інші незвичні шрифти в A12 сюрпризів не дали: `Arial-Black` (великі цитати
на рівні 2) і `ZapfDingbatsITC` (галочка й хрестик на Level2_A12 стор. 2)
вже описані в `FONTFILES`.

---

## Механіки завдань — 128 на п'ять буклетів

```bash
.venv/bin/python ua_build/inventory.py <тека> --json a12.json
.venv/bin/python ua_build/inventory_types.py a12.json
```

| тип | поле | разом | L0 | L1 | L2 | L3 | L4 |
|---|---|---|---|---|---|---|---|
| write | так | 80 | 0 | 6 | 13 | 31 | 30 |
| choose | так | 9 | 0 | 2 | 3 | 4 | 0 |
| join-line | ні | 8 | 3 | 3 | 1 | 1 | 0 |
| art-paint | част. | 7 | 2 | 4 | 1 | 0 | 0 |
| yes-no | так | 5 | 0 | 1 | 1 | 3 | 0 |
| cells | так | 5 | 0 | 0 | 4 | 0 | 1 |
| draw | ні | 4 | 0 | 3 | 1 | 0 | 0 |
| acrostic | ні | 2 | 0 | 0 | 1 | 1 | 0 |
| art-circle | част. | 2 | 0 | 0 | 0 | 2 | 0 |
| look-up | част. | 2 | 0 | 0 | 0 | 2 | 0 |
| art-label | част. | 1 | 0 | 1 | 0 | 0 | 0 |
| unjumble | так | 1 | 0 | 0 | 0 | 1 | 0 |
| не розпізнано | — | 2 | 0 | 0 | 0 | 1 | 1 |

Полем форми робиться 100 завдань (78 %) — рівно та сама частка, що по всій
програмі. Нових механік немає: усі дванадцять типів конвеєр уже проходив на
A1.

Два зауваження на потім:

* **Level0_A12 не має жодного завдання типу `write`** — самі малюнки,
  з'єднання ліній і зафарбовування. Це найдорожчий буклет партії, як і
  передбачає порядок рівнів у методі (`4 → 3 → 2 → 1 → 0`);
* **два акростихи** (L2, L3) — та сама механіка, яку в A1 двічі довелося
  замінювати на письмове завдання (`BACKLOG.md`). Рішення досі не ухвалене.

Обидві «не розпізнані» інструкції — довгий хвіст формулювань, не пропущена
механіка: «write IN YOUR OWN WORDS why…» (це `write`) і «Put in the boxes the
number of the title which matches» (це `cells`).

---

---

## Level4_A12 — пройдено наскрізь

| | Файл | |
|---|---|---|
| Друк | `lessons/uk/print/Level4_A12_UA_v10.pdf` | `qa.py` — 0 зауважень |
| Інтерактив | `lessons/uk/interactive/Level4_A12_UA_v01.pdf` | 163 поля, круговий тест 160/160 |

Тема буклета — «Народження Спасителя»: звістки ангела, наказ імператора,
відвідини пастухів, дари мудреців. Для зимової розсилки влучно.

### Що довелося вирішити у Скілі 2

**Акростих.** Оригінал складає по перших літерах слово TREASURES (скарби).
Українською з тими самими дев'ятьма відповідями воно не збирається взагалі:
перші літери задані самими словами, і жодне осмислене слово в них не лягає.
Тому бралося з іншого боку — **спершу слово, потім підказки під нього**.
`ПОДАРУНОК` теж із дев'яти літер (бали `/9` лишаються ті самі) і теж по темі
(«Дари мудреців»); усі дев'ять відповідей — з Матвія 2: 1-23, як і в
оригіналі, п'ять підказок збігаються з англійськими. Це третій випадок
акростиха в проєкті й перший, який вдалося зберегти як акростих, а не
замінити письмовим завданням.

**Сітка слів на стор. 2** — сім відповідей згори вниз. Стару сітку закрито,
нову намальовано під українські довжини; у `puzzlekit` для цього додано
`draw_cols` — дзеркало `draw_rows` для вертикальних стовпчиків. Підказкові
літери «СТ» від СТРИВОЖЕНА лягли рівно в перші дві клітинки третього
стовпчика, тож переносити їх не довелося.

**Карта.** Підказкова літера в кожній назві своя, бо українські слова
коротші за англійські: `Г _ _ І _ _ _`, `_ _ _ _ Р _ _`, `Ю _ _ _`,
`_ _ Ф _ _ _ _`. В ЮДЕЇ підказка стоїть **першою** навмисно: одинокий `_`
перед літерою полем не стає (детектор рахує пропуском два підкреслення й
більше), і перша літера була б невводимою.

**Милі → кілометри.** 70 миль → «близько 110 кілометрів», 6 миль → «близько
десяти кілометрів», масштаб карти `50 miles` → `80 км`. У тексті вони
служать відчуттю відстані, а не цитуванню.

### Що це полагодило в конвеєрі

Шість дрібниць, кожна з яких псувала не цей буклет, а всі наступні:

* **`qa.py` перевіряв не той документ.** Шаблон, джерело й зібраний PDF були
  вписані в нього константами від пілотного буклета Level 2 — тобто на всій
  серії A1 геометричний контроль працював проти чужого файла. Тепер
  `qa.py <буклет>` бере все з конфігу уроку;
* **логотип лягав на бокс балів.** Евристика шукала емблему `bes` як дрібні
  фігури у верхньому правому куті; на сторінці 8, яка починається завданням,
  у тому куті стоїть бокс балів. Розрізняє їх кількість фігур: емблема — це
  два десятки дрібних, бокс — один прямокутник;
* **табуляція друкується порожнім квадратиком** — гліфа `\t` в Arial немає.
  У шаблоні вона трапляється в переліках;
* **п'ять правил детектора** (§3.3, пункти 6–10 у файлі агента): хмаринка
  репліки як овальна рамка, поріг ширини рамки, умовна шапка, «1. 2. 3.» як
  три поля, і `EXTRA_FIELDS` — оголошені уроком місця, яких геометрія не
  показує.

Перевірено, що серія A1 від усього цього не змінилася: детектор дає ті самі
196 / 152 / 252 поля на рівнях 2–4, а на рівнях 0 і 1 — на одне більше
(хмаринка на першій сторінці, яка доти лишалася без поля).

## Стан

Level4_A12 закрито. Наступне — 3 → 2 → 1 → 0.
