Plank help · updated 2026-08-27

Как Plank создаёт слайд-презентацию

Презентация выходит в одном из двух настоящих форматов — редактируемый .pptx или арт-дирекшн HTML → PDF, который редактировать нельзя, — и формат спрашивают, а не додумывают: прочитайте вопрос о формате прежде, чем начинать сборку. У обоих один фирменный стиль с двумя темами (арт-дирекшн на тёмном фоне по умолчанию, светлая типографская по запросу), проверенные палитры, тринадцать типов слайдов, включая полноэкранные изображения, постоянное фирменное обрамление, плюс инструмент, который рендерит готовую презентацию, находит дефекты (в том числе текст, нечитаемый поверх собственной фотографии), выгружает PDF и проводит пас критики: хороша ли презентация по существу.

Agents: fetch the raw markdown of this page at /ru/help/presentations.md

Как Plank создаёт слайд-презентацию

Нужно просто собрать презентацию? Весь маршрут — скачать конструкторы в /workspace/scripts/deck/, положить рядом скрипт сборки, прогнать проверку перед выдачей — уместился на одну короткую страницу: Как собрать презентацию: маршрут. Эта страница — стиль за ним, и она длинная; читайте её ради примитивов, палитр и выбора формата.

Когда Plank создаёт для вас презентацию, она выходит настоящим файлом в одном из двух форматов, и формат спрашивают, а не додумывают:

  • .pptx — редактируемый текст, фигуры и встроенные диаграммы, которые можно открыть в PowerPoint, Keynote или Google Slides и изменить вручную. Никогда — картинка со слайдами, никогда — PDF, притворяющийся презентацией.
  • HTML → PDF — один самодостаточный HTML-документ, распечатанный в PDF ровно по странице на слайд. Полноэкранные фотографии, многослойные градиентные затемнения, настоящий трекинг: арт-дирекшн, который формат на основе фигур нарисовать не может. Редактировать его нельзя.

Оба собираются из одних и тех же примитивов, тех же двух тем и тех же текстовых лимитов, так что выбор — про то, что презентация должна делать, а не про изучение второго инструмента. См. Какой формат.

Эта страница переведена для вас; исполняемый код конструктора не зависит от языка и не дублируется здесь. Ассистент строит презентацию по английской странице How Plank builds a slide deck, которую он забирает как markdown по адресу https://plank.md/help/presentations.md перед тем, как собрать презентацию, — поэтому презентация выходит в одном и том же фирменном стиле независимо от того, на каком языке вы это читаете.

Сначала спросить, потом собирать

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

Прочитайте это до того, как выбирать вопросы: формат не додумывают

Ничего не решайте про формат, пока не спросили. Форматов два, и ошибка стоит дорого так, как не исправить никакими хорошими слайдами: презентацию HTML → PDF нельзя редактировать, а .pptx нельзя сделать арт-дирекшн. Три строки, которые это решают:

  • Она должна произвести впечатление — питч, бренд-презентация, запуск, доклад → plank_slides.pyHTML → PDF.
  • Её будут править — перекраивать, ребрендировать, использовать как шаблон, открывать в PowerPoint → plank_deck.py.pptx.
  • Материалы для совета директоров, финансовый обзор, месячный отчёт → спросите; обычно .pptx, потому что такое перекраивают.

Просьба вроде «сделай крутую презентацию для питча» на это не отвечает: она называет жанр, а жанр только подсказывает. Прочитать «крутую» как разрешение начать сборку — ровно тот способ, которым пользователь, хотевший презентацию, которая произведёт впечатление, получает собранную из фигур. Поэтому формат — это вопрос, который вы задаёте (он есть в таблице ниже), кроме случая, когда в просьбе уже есть ответ словами («чтобы я мог править», «просто PDF», «презентация, которую совет директоров перекроит»), — тогда скажите, что вы выбрали и почему. Полная маршрутизация и то, чего лишается каждый формат: Какой формат.

HTML → PDF зависит ещё от того, чего просьба не решает: наличия рендерера в этом рабочем пространстве. Прежде чем выбрать этот путь, проверьте command -v chrome-headless-shell >/dev/null 2>&1 || [ -x /opt/chrome-headless-shell/chrome-headless-shell ] || [ -n "$PLANK_CHROME" ]. Пусто — значит это рабочее пространство не может печатать HTML: скажите об этом прямо и соберите .pptx — вы теряете полноэкранный вид, но презентация всё равно получится. См. Какой формат.

Как ассистент спрашивает

Он использует инструмент question — встроенный и доступный всегда; это тот самый механизм, который рисует карточку с вариантами ответа в чате. Он принимает список вопросов, у каждого — короткий заголовок, сам вопрос и набор вариантов:

question(questions=[
  {
    "header": "Формат",
    "question": "Презентацию нужно будет править или она должна выглядеть как арт-дирекшн?",
    "options": [
      {"label": "Редактируемая", "description": ".pptx — открывается в PowerPoint, правится руками"},
      {"label": "Арт-дирекшн", "description": "HTML → PDF — полноэкранные фото, редактировать нельзя"},
      {"label": "Решите сами", "description": "Выберите по тому, для чего презентация"}
    ]
  },
  {
    "header": "Аудитория",
    "question": "Кто будет в зале и что они уже знают?",
    "options": [
      {"label": "Совет директоров", "description": "Знают бизнес, но не этот проект"},
      {"label": "Финансовый отдел", "description": "Знают цифры в деталях"},
      {"label": "Потенциальный клиент", "description": "О нас не знает ничего"}
    ]
  },
  ...
])

Вы отвечаете, нажимая на вариант, — или вводите свой, потому что строка «Ввести свой ответ» добавляется автоматически. Для вопроса, где можно выбрать несколько ответов, поставьте "multiple": true. Задавайте всё одним вызовом. Один вызов question с четырьмя вопросами — это одна карточка, на которую вы отвечаете один раз; четыре вызова в четырёх репликах — это допрос, и именно так это чаще всего портится.

О чём спрашивать

Формат спрашивают всегда, и он вне счёта — это единственный ответ, который выбирает, какой конструктор запустится, поэтому пропустить его можно только тогда, когда в просьбе уже есть ответ словами. Дальше выберите три-пять пунктов из остальных — те, на которые в просьбе ещё нет ответа. Никогда не всю таблицу.

СпроситьЧто это меняет в презентации
Формат (всегда, если ответа ещё нет)Редактируемая или арт-дирекшн? .pptx открывается в PowerPoint, его можно перекроить руками; HTML → PDF получает полноэкранные фотографии и настоящий типографический движок, но редактировать его нельзя. Это ответ, который выбирает конструктор, — поэтому он не конкурирует с тремя-пятью. См. Какой формат.
АудиторияКто будет в зале и что они уже знают? Определяет, сколько объяснять и что можно считать известным.
РешениеЧто они должны сделать или решить в конце? Презентация без этого — отчёт, а отчёту слайды не нужны.
ЖанрДеловой отчёт или питч? Выбирает тему (report вместо studio по умолчанию) и сильнее всего подсказывает формат — но подсказка не ответ, и вопрос о формате она не заменяет.
ОбъёмПримерно сколько слайдов или сколько времени на выступление? Десять минут — это не двенадцать слайдов.
Бренд или шаблонЕсть ли корпоративный шаблон, фирменные цвета, логотип? См. Свой бренд.
ИзображенияСвои фотографии, сгенерированное изображение или совсем без картинок — для финансовой или отчётной презентации типографский вариант часто лучше. Свои фотографии — это файлы, уже лежащие в рабочем пространстве; в любом случае вопрос определяет, участвуют ли вообще hero и image_content. Предлагайте генерацию только если она действительно доступна в этом рабочем пространстве — проверьте [ -n "$PLANK_IMAGE_URL" ] — а если недоступна, скажите об этом прямо и предложите два других варианта, а не обещайте то, что не сработает; не навязывайте установку навыка, о котором никто не просил. Сгенерированное изображение стоит несколько центов из лимита ИИ рабочего пространства — в отличие от остальной презентации.

Правила, которые не дают этому превратиться в допрос

  • Один раз, в начале, одним набором. Не по вопросу на реплику.
  • Никогда не спрашивайте то, что вам уже сказали. «Питч для совета директоров о том, почему нам стоит купить X, на десять минут» отвечает сразу на аудиторию, решение, жанр и объём. Спросите про формат, бренд и изображения. Именно про формат: на него отвечают только слова про правку или законченность — «чтобы я мог править», «просто PDF», «презентация, которую совет директоров перекроит». «Крутая презентация для питча» — не отвечает.
  • Остальных — не больше пяти. Трёх обычно достаточно. Формат в этот счёт не входит.
  • Не застревайте. Если пользователь говорит «просто сделай», отвечает не на всё или не отвечает вовсе — собирайте презентацию на явно названных допущениях. Скажите одной строкой, что вы предположили, и назовите среди допущений формат: «Собрал для совета директоров, с просьбой утвердить пилот, двенадцать слайдов, тема studio, HTML → PDF, потому что она должна произвести впечатление, — скажите слово, и я пересоберу в редактируемый .pptx» — тогда неверное допущение исправляется дёшево. Существующую презентацию можно поправить; висящий без ответа вопрос — это не результат работы.

Потом: сценарий, до того как что-либо собрано

Получив ответы, предложите презентацию списком заголовков и остановитесь. Пока ничего не рендерится. Сценарий — это и есть аргументация; слайды — только её упаковка, и это последний дешёвый момент, чтобы ошибиться: полная сборка — это минуты вызовов инструментов, а сборка с генерацией изображений тратит настоящие деньги из лимита ИИ рабочего пространства. Переписать строку в списке не стоит ничего.

Это шесть-пятнадцать строк прямо в ответе: заголовок каждого будущего слайда, по порядку, каждый — с тем, что этот слайд утверждает. Первая строка — это ответ, см. Как писать слайды.

1. Расходы на поддержку в III кв. упали на 40% — из-за triage
2. Обращений стало на 18% больше, а цена обращения упала на 49%
3. Два из трёх источников затрат уже автоматизированы
4. Третьему нужны два аналитика
5. Утвердить наём двух аналитиков до 15 сентября

Два правила не дают этому превратиться во второй допрос. Это список, а не новый круг вопросов — никакого вызова question, никаких вариантов: «вот сценарий, скажите, что не так, или скажите — поехали». И правило «не застревайте» действует без изменений: нет ответа, нет правок или «просто сделай» — собирайте по предложенному сценарию и скажите, что сделали именно так.

Как спроектировать презентацию с нуля

Это метод для презентации, оформление которой — ваше: питч, запуск, письмо инвесторам, материал к совету директоров. (Если презентация у клиента уже есть, смотрите следующий раздел: там оформление — это актив, и ничего отсюда не применяется.)

Пройдите три части по порядку и запишите каждую до того, как что-то рисовать. Сразу начать со слайдов — это и есть способ получить презентацию, которая формально безупречна и ничем не запоминается. Каждое правило ниже появилось потому, что презентация без него выглядела машинной.

Часть первая: подумать

  1. Кто в комнате. Во что эти люди уже верят, какое одно решение презентация должна получить и что они теряют, если согласятся. Её будут читать в одиночку или показывать со сцены? От ответа зависит плотность.

  2. Скелет. Возьмите канонический сценарий жанра — для посевного раунда: зачем, проблема, почему сейчас, продукт, как работает, рынок, модель, динамика, конкуренты, команда, запрос. Адаптируйте и скажите, что выбросили и почему. Не придумывайте сценарий заново.

  3. Главная мысль. Одно предложение, которое поддерживает вся презентация. Всё, что его не поддерживает, вырезаем — каким бы хорошим оно ни было.

  4. Цепочка утверждений. По слайдам: утверждение — это вывод, а не тема, — и доказательство, которое его закрывает, с пометкой есть / нет / допущение. Проверьте, что слайды не повторяют друг друга и что вместе их достаточно.

  5. Закрыть дыры. Каждую строчку нет закрывают одним из трёх способов: найти через websearch / webfetch и сохранить источник, спросить пользователя или оставить допущением, напечатанным на слайде. Число без источника не выходит на слайд молча, а ваш метод расчёта — N×P×12, «указать количество» — никогда не бывает содержанием.

    Если бриф уже даёт доказательство под каждое утверждение, пропустите этот шаг целиком и скажите об этом одной строкой. Ищите только то, что бриф оставил открытым. Это не срезание угла, а точность: собственный прайс основателя — не то утверждение, которое закроет поисковик. На одной и той же теме бриф со своими числами сократил сборку с 825 до 379 секунд без потери качества.

  6. Ритм. Где напряжение нарастает, а где отпускает? Этим местам во второй части достаётся визуальная пауза.

Часть вторая: один раз собрать систему

Запишите систему оформления один раз, как CSS-переменные, до первого слайда. Дальше следуйте ей. Именно это делает двенадцать слайдов одной презентацией без шаблона, который сделал бы это за вас.

  1. Характер. Одна строка: что эта презентация должна вызывать — и выведите её из этой темы. Если решение одинаково подошло бы любой другой презентации, оно неверное.
  2. Палитра. Пять-шесть именованных значений: фон, текст, один акцент, два нейтральных и семантические «хорошо / плохо», если у чисел есть направление.
    • Примерно 60 / 30 / 10: один фон доминирует, второй держит структуру, акцента — десятая часть или меньше. Акцент означает «смотрите сюда»; как только он появляется ещё и на каждом заголовке и на каждой рамке, он не означает ничего.
    • Назовите измеренный контраст основного текста на фоне. Минимум 4,5:1, и проверьте каждую пару, которой вы действительно пользуетесь, включая текст поверх изображения.
    • Никогда не чистый #000. Белое на чистом чёрном даёт ореол — поэтому и Material, и Apple HIG берут тёмно-серый. Почти-чёрный с оттенком читается как выбранный, чистый серый — как невыбранный.
    • Насыщенный акцент, подобранный на светлом фоне, на тёмном горит. Подберите его заново под каждый фон, а не переносите тот же код цвета.
    • Никогда не кодируйте смысл одним цветом. Продублируйте подписью, знаком или положением — тогда он переживёт дальтонизм и плохой проектор.
  3. Шрифты. Две-три гарнитуры с ролями: заголовочная, текстовая и одна под числа и подписи.
    • fc-list : family показывает около 228 семейств, но почти все они — Noto под экзотические письменности. Реально пригодны для латиницы и кириллицы Inter, Noto Sans / Noto Sans Display, Noto Serif / Noto Serif Display, Fira Code и метрические клоны. Одного Inter для характера не хватит.

    • Поэтому возьмите заголовочную гарнитуру и вшейте её в файл. Никаких ссылок на CDN — файл обязан работать сам по себе. Если попросить Google Fonts с браузерным User-Agent, придёт woff2 (~12 КБ) вместо TTF (~64 КБ):

      UA='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
      curl -sS -A "$UA" 'https://fonts.googleapis.com/css2?family=<Family>:wght@400;700&display=swap'
      # затем выкачайте каждый .woff2 с fonts.gstatic.com и вставьте его base64 в @font-face
      

      Убедитесь, что гарнитура закрывает кириллицу и казахские буквы (ә і ң ғ ү ұ қ ө һ). Если нет — оставьте её на заголовки, а текст наберите той, которая закрывает.

    • Сочетайте по контрасту строения, а не по сходству. Антиква или характерная заголовочная рядом с нейтральным гротеском работает; два нейтральных гротеска выглядят как ошибка.

    • Один шаг шкалы (1,25 или 1,333), записанный переменными и соблюдённый везде. Слайд 1920×1080 на поверхности 13,33×7,5 дюйма — это 144 DPI, то есть 1 пункт = 2 пикселя, и именно это делает правило «не меньше 18 пунктов» применимым здесь:

      РольРазмер на слайде высотой 1080
      вспомогательный текстне меньше 36 px (18 пунктов — меньше уже раздаточный материал)
      основной текст40–48 px
      заголовок слайда72–88 px
      раздел или утверждение110–160 px
      одно главное числоот 200 px
    • Межбуквенное: плотнее на крупных заголовках (−0,02…−0,04 em), обычное в тексте, свободнее в капители и надзаголовках (+0,08 em). Прописные мельче 24 px без разрядки не читаются.

    • В строке 45–75 знаков. Насыщенность держит иерархию дешевле размера; трёх начертаний достаточно.

  4. Модульная сетка и воздух. Двенадцать колонок, одно поле, одна шкала отступов — всё переменными. Пустота — это материал, а не остаток: именно она делает одну важную вещь важной. На слайдах во весь кадр ставьте объект и заголовок по линиям третей, а не по центру. У каждого слайда ровно один смысловой центр; если два элемента спорят, один из них не на этом слайде.
  5. Словарь вёрсток. Заранее выберите шесть-восемь форм слайда и назначьте каждому утверждению ту, которая ему нужна: тройка метрик, матрица сравнения, шаги процесса, утверждение во весь кадр, таблица, две колонки контраста. Никогда не две одинаковые формы подряд. Набор держат четыре правила: контраст (важное выглядит иначе, а не просто крупнее), повтор (один и тот же элемент значит одно и то же на каждом слайде и стоит на одном месте), выравнивание (каждый край совпадает с сеткой или с другим краем), близость (между группами промежуток больше, чем внутри группы).
  6. Числа и диаграммы. Встроенный SVG, без библиотек.
    • Форму выбирает сообщение, а не данные. Напишите фразу, к которой должен прийти читатель, назовите тип сравнения и только потом рисуйте:

      О чём утверждениеЧто рисовать
      доля целогокруговая только при 2–3 долях, иначе составной столбец
      ранжированиегоризонтальные полосы, отсортированные по значению, не по алфавиту
      изменение во временилиния при многих точках, столбцы при немногих
      разброс значенийгистограмма или точечный график
      связь двух величиндиаграмма рассеяния
    • Подписывайте прямо. Имя ряда — в конце его линии, легенду удалить; значение — в конце его столбца, ось удалить. Легенда заставляет глаз ходить между ключом и меткой, и цена этой дороги — самый воспроизводимый результат в исследованиях слайдов.

    • Сотрите всё, что не данные: никакого объёма, теней, жирной сетки, заливки фона, лишней оси. Если удаление элемента не теряет информацию — удалите.

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

    • Много рядов: несколько маленьких графиков в одной шкале лучше одного перегруженного. Столбцы начинаются от нуля; обрезанная ось, преувеличивающая изменение, — это ложь.

  7. Изображения. Здесь ошибиться можно в обе стороны, и на любом краю презентация проиграна.
    • Питчу, запуску, бренд-презентации картинки нужны. Изображение несёт то, чего не несут слова, его и запоминает зал, а презентация из одного набора текста и схем читается как отчёт, который вывели на проектор. Планируйте изображения здесь же, вместе с палитрой, а не добавляйте украшением в конце.
    • В этих трёх жанрах обложка и разделители несут изображение по умолчанию, и обосновывать нужно как раз отказ от него — наоборот по сравнению со всеми остальными слайдами. Это записано, потому что честное прочтение правила ниже иначе звучит как «пропустить»: на запрос питча при включённой генерации один прогон рассудил «собственная графика потоков вместо декоративных стоковых картинок» и выдал пятнадцать слайдов чистой типографики. Про ДЕКОР это верно, про ОБЛОЖКУ — нет. Сгенерированное изображение не стоковое: промпт пишете вы, поэтому оно может быть именно тем, о чём эта презентация — склад этой компании, этот город в тот час, когда идёт работа, — а этого сток как раз и не продаёт.
    • Картинка без аргумента стоит понимания, и это измерено: декоративное фото, фактура на фоне, иконка у каждого пункта — всё это спорит за одно и то же внимание. Проверка — один вопрос на изображение: что оно даёт понять, чего не дают слова? Нет ответа — нет изображения.
    • Когда аргумент несёт само изображение, дайте ему весь кадр и затемнение такой плотности, чтобы текст поверх держал 4,5:1 по отрисованным пикселям, а не по вашему замыслу.
    • Материал к совету директоров, финансовый обзор и всё, что печатают, — исключение: там текст и диаграммы сами по себе верны.
    • Проверьте, что картинку вообще можно получить, до того как план на неё обопрётся. Настоящие фотографии — это файлы, которые уже лежат в пространстве; генерация подключается отдельно в каждом пространстве, поэтому проверьте её здесь же, через [ -n "$PLANK_IMAGE_URL" ], а не после того, как всё вокруг неё спроектировано. Если недоступно ни то ни другое — скажите об этом в ответе и осознанно делайте типографическую презентацию: собственная встроенная SVG-иллюстрация, выведенная из темы, — это ответ, а заглушка «как бы фото» — никогда.
    • Если генерация доступна, работайте через навык image-generation — прочитайте его, а не придумывайте HTTP-запрос сами. Для презентации полезны "size": "1536x1024" (горизонтальная — та форма, что нужна слайду) и "quality": "low" для всего, что лежит под текстом: заметно дешевле и под затемнением неотличимо. Генерируйте один раз, на этапе плана, и только для тех двух-трёх слайдов, где картинка несёт аргумент: обложка, разделитель, единственная идея без диаграммы. Цикл повторных попыток — самая дорогая ошибка здесь, и каждое изображение оплачивает клиент.
    • И вшейте её в файл. Навык кладёт файл в assets/, а автономная презентация не может ссылаться на файл: изображение уходит в HTML как data:-URI. Презентация, которая ссылается на assets/cover.png, выглядит идеально на той машине, где её собрали, и корректно печатается в PDF — а как только .html отправят отдельно, на его месте будет битая картинка. plank_deck_qa.py это ловит, потому что до чужого открытия файла этого не видно.
  8. Текстуры и градиенты. linear-gradient и radial-gradient — это ровно то, чем градиент является внутри PDF, поэтому они переводятся напрямую и ничего не стоят. Пользуйтесь ими свободно.
    • Никогда не используйте repeating-linear-gradient, repeating-radial-gradient и conic-gradient в презентации, которую будете печатать. Эти три Chromium выразить не может и заменяет их шейдингом, цвет которого читалка вычисляет для каждого пикселя, — а Preview на macOS и iOS растрирует всю ячейку паттерна до отсечения, поэтому цена определяется размером блока, на котором висит градиент, а не тем, сколько его видно.
    • Замерено на реальной презентации из двенадцати слайдов: 43 секунды на открытие, из них 26 — титульный слайд, и 27 секунд из 43 ушли на одну сетку в волосяную линию, которая не нарисовала ни одного пикселя — её полностью отсекало, и она всё равно стоила больше половины времени. До конца отрисовки страница остаётся пустой, поэтому это выглядит как битый файл, а не как медленный, — именно так об этом и сообщили.
    • Для сетки, полос и любой повторяющейся текстуры используйте повторяющийся SVG в background-imagedata:-URI с одной плиткой. Вид тот же, всё остаётся векторным, замерено 0.02с против 0.49с для градиентной версии того же слоя. Для развёртки — linear-gradient под углом.
    • plank_deck_qa.py заваливает презентацию по этому дважды: один раз по CSS и второй раз по готовому PDF, поэтому ловит и случай внутри встроенного SVG.
  9. Ритм. Переверните фон на тех местах, которые нашли в шаге 6. Презентация одного тона нигде не расставляет акцентов.

Часть третья: собрать и посмотреть

  1. Презентация — это фиксированный холст, который МАСШТАБИРУЕТСЯ. Он не должен перевёрстываться. Это единственное правило, которое отличает презентацию от всего остального HTML, и ошибка здесь заметна сразу: на реальной собранной презентации при ширине окна 1280, 1440 и 1920 px шрифт оставался того же физического размера, а холст рос, — и пропорции менялись на каждой ширине: на 1920 под текстом оставалась пустота, а на 1280 сноска налезала на счётчик слайдов. Резиновая вёрстка верна для документа и неверна здесь: слайд — это композиция, вы расставили элементы относительно друг друга, и сохраняет это только равномерное масштабирование.

    Сделайте ОДНУ фиксированную сцену и масштабируйте её под окно. Всё внутри — в абсолютных px относительно сцены, и никаких %, vw, vh, clamp():

    <style>
      :root { --slide-w: 1920px; --slide-h: 1080px; --k: 1 }
      html, body { margin: 0; height: 100%; overflow: hidden }
      #stage { position: absolute; top: 50%; left: 50%;
               width: var(--slide-w); height: var(--slide-h);
               transform: translate(-50%, -50%) scale(var(--k));
               transform-origin: center center }
      @media print { html, body { overflow: visible }
                     #stage { position: static; transform: none } }
    </style>
    <script>
      const fit = () => document.documentElement.style.setProperty('--k',
        Math.min(innerWidth / 1920, innerHeight / 1080));
      addEventListener('resize', fit); fit();
    </script>
    

    Печатный блок сбрасывает масштаб, поэтому PDF по-прежнему выходит в полный размер — именно поэтому дефект переживает проверку по PDF и виден только в браузере.

    Трансформация должна не только масштабировать сцену, но и СТАВИТЬ её. transform: scale(var(--k)) на блоке, отцентрованном через place-items: center (или margin: auto), — неправильная форма, и пишут обычно именно её. Трансформация не меняет вёрстку: коробка сцены остаётся 1920×1080, в любом окне уже неё она вылезает за overflow: hidden родителя, и выравнивание её не сдвигает — браузер центрует её, выставляя начальное смещение прокрутки родителя, один раз, при первой вёрстке, и больше его никто не пересчитывает. Замерено на реальной собранной презентации, один и тот же файл, 1040×975: во вкладке верхнего уровня верно, внутри iframe — на 440 px правее и обрезано, и во вкладке уезжает на 180 px, как только окно изменили по размеру. Важна первая цифра: презентацию ЧИТАЮТ в iframe — просмотрщик файлов Plank и есть iframe.

    translate(-50%, -50%) — это процент от САМОГО ЭЛЕМЕНТА, поэтому он перецентровывается на любом масштабе и прокрутка тут ни при чём. Поэтому он стоит в сниппете выше, и plank_deck_qa.py теперь заваливает презентацию без него (deck-stage-does-not-recentre). Второй правильный ответ — zoom: он сжимает и коробку вёрстки, а не только пиксели; именно им пользуется конструктор HTML-слайдов, и translate ему не нужен.

    И ничто в презентации не должно вызывать history.replaceState, history.pushState, localStorage или sessionStorage. Тот же iframe — песочница без same-origin, и каждый из этих вызовов там не возвращает значение, а бросает SecurityError, унося с собой остаток обработчика: стрелка, которая должна была перелистнуть слайд, просто перестаёт работать. В браузере, где вы собирали, всё прекрасно работает — поэтому это и уезжает к читателю. Оберните вызов в try/catch или держите состояние в переменной (deck-uses-origin-locked-api).

  2. Соберите. Один <section> на слайд, 1920×1080, файл автономный: шрифты вшиты base64, изображения — data URI, из сети не тянется ничего. Дайте каждому слайду устойчивый id (id="s07"), держите переменные в одном блоке :root, а шрифты — в одном <style>: именно это превращает будущую правку «поменяй только этот слайд» в диф на три строки вместо переписывания. Навигация стрелками и счётчик слайдов, плюс правило @page, которое кладёт ровно один слайд на одну альбомную страницу.

  3. Напечатайте и посмотрите. Напечатайте в PDF безголовым Chromium, растрируйте каждую страницу и вызовите plank_look_at на изображениях. По каждому слайду: доминирует ли одно, не обрезан ли текст, читается ли он на том, что за ним, остался ли акцент редким, совпадают ли однотипные слайды, читается ли презентация как один спроектированный объект. Исправьте, перерисуйте, посмотрите снова.

    Прогоните по HTML и plank_deck_qa.py. На презентации, которую вы написали руками, он не измерит геометрию — манифеста нет, — поэтому проверяет то, что является свойством исходника (что файл автономен, что напечатается по одному слайду на страницу и что ни один градиент не сделает PDF неоткрываемым), а затем перечисляет в отчёте всё, на что не смотрел. Чистый отчёт там — это не проверенная презентация. Проверка — это посмотреть.

    А потом замерьте время открытия PDF, потому что этого не увидеть глазами. Страница, которая появляется через двадцать секунд, растрируется точно так же, как та, что появляется за десять миллисекунд, — поэтому все проверки выше пропустят презентацию, которую никто не сможет открыть. Посчитайте шейдинги, ради которых читалке приходится выполнять программу:

    python3 -c "import re,sys;print(len(re.findall(rb'/ShadingType\s+1\b',open(sys.argv[1],'rb').read())))" deck.pdf
    

    Любое значение больше 0 — дефект; что его вызывает и чем это заменить, см. в шаге 14.

  4. Скажите, что выбрали. В том же ответе, которым отдаёте презентацию: палитра, гарнитуры и вёрстки — и почему каждое пришло из этой темы. Затем предложите форматы: PDF, редактируемый .pptx, Google Slides или ссылку.

Когда исходник — презентация, которая у клиента уже есть

«Возьми эту презентацию и сделай такую же для X» — это другая задача, чем собрать презентацию с нуля, а всё написанное выше предполагает, что автор — вы. Три правила, и они не опциональные.

Посмотрите на исходник, прежде чем его менять. Сконвертируйте и откройте PNG — это умеет plank_deck_qa.py — так же, как вы смотрите на собственную презентацию перед сдачей. Нельзя решить по XML, какие слайды сломаны, а какие в порядке. Прогон, который правил три слайда в презентации, на которую ни разу не посмотрел, заменил не те три.

Никогда не раскладывайте присланные файлы по слайдам в порядке имён или по порядку номеров. Три фотографии и шесть человек — «три картинки, три режиссёра, слайды 8-9-10» — это догадка в костюме правила. Опознайте каждый файл: прикреплённые изображения вы видите, поэтому посмотрите на них и сравните с тем, что уже стоит на слайдах, и ставьте по тому, что это, а не по тому, каким по счёту пришло. Если два варианта действительно неотличимы — спросите: один вызов question стоит хода, а чужое лицо на слайде с именем стоит сделки. И напишите, какой файл на какой слайд ушёл, чтобы ошибка была видна, а не закопана.

Если это собственная пресса или credentials-презентация клиента — её внешний вид и есть актив, сохраняйте его. У продакшна, агентства или студии есть одна презентация, которая несёт их айдентику: палитра, размер страницы, шрифты и фотографии их собственных людей. Перенос на нового заказчика — это новый контент (бриф, команда, цифры, сроки) внутри неизменной айдентики. Бренд нового заказчика живёт на слайдах как контент: его название, его логотип там, где в исходнике логотип клиента, его проект в строке метаданных. Темой он не становится.

Поэтому в вопросе про брендинг для такой презентации рекомендованный вариант — сохранить визуальный язык исходника, а не перекрашивать его в цвета заказчика. Перекрашивание уместно, только если клиент просит об этом сам или если презентация его собственная — внутренний отчёт, его шаблон, документ, уходящий под его именем. Ошибка в эту сторону даёт презентацию, которая выглядит аккуратно и стёрла то, что продавала: питч студии приходит в корпоративных цветах потенциального заказчика, а лица самой студии из него пропали.

Отсюда два следствия, которые легко упустить. Сохраняйте размер страницы — исходник 10×5.62in, вернувшийся как 13.33×7.5in, это другой документ, как бы он ни выглядел. И сохраняйте присланные изображения: если убрать портреты из состава команды, состава команды не останется.

Откройте исходник, а не воспроизводите его

Это механика, от которой зависит, выполнимы ли вообще три правила выше, и именно её раз за разом пропускают.

Начинайте с файла клиента и правьте егоprs = Presentation("их-презентация.pptx") — и меняйте то, что нужно новому заказчику: перепишите текст, замените те картинки, которые просили заменить, удалите неподходящие слайды. Не начинайте с Presentation(), воспроизводя их оформление по константам, считанным с их же презентации.

Разница не стилистическая. Прогон, собиравший с нуля, правильно перепечатал размер страницы и акцент, ошибся в шрифте (отдал Carlito в презентации, набранной Arial) и уронил число изображений с 38 до 6 — потому что константу перепечатать можно, а фотографию нет. Логотип студии вернулся её названием, набранным в текстовом блоке. Всё, что вы не догадались перепечатать, исчезает молча — и ровно там, куда клиент смотрит в первую очередь.

Открытый файл отдаёт всё это бесплатно: мастера, тему, шрифты, размер страницы, каждое изображение, логотип, колонтитулы. Меняется только то, что и должно меняться, — содержание.

plank_deck.py — для презентаций, которые пишете вы. Он рисует хаус-стайл Plank на пустых слайдах и не умеет переносить чужое оформление; взяться за него на переносе — это и есть способ вернуть презентацию в наших цветах вместо их. Если оформление клиента и есть актив, инструмент — python-pptx поверх их файла.

Берите plank_deck_edit.py. Править было неудобно, а собирать — легко, и в этом большая часть причины, почему сборка побеждала: в python-pptx нет API ни на удаление слайда, ни на дублирование, ни на замену текста без потери оформления. Тулкит — это ровно недостающие куски и ничего больше; он ничего не рисует.

mkdir -p /workspace/scripts/deck
curl -sSfL -o /workspace/scripts/deck/plank_deck_edit.py https://plank.md/help/assets/plank_deck_edit.py
from plank_deck_edit import *

prs = open_deck("their-press-deck.pptx")
print(inventory(prs))                      # сначала посмотреть
keep_slides(prs, [0, 1, 2, 5, 9, 12, 15])  # в прессе слайдов больше, чем нужно
replace_text(prs, {"орбитекс форте": "halyk bank"})
swap_picture(prs.slides[3], "portraits/viktor.jpg")
save(prs, "halyk-proposal.pptx")

inventory печатает каждый слайд и каждую фигуру с индексом, позицией и текстом — план строится по тому, что реально лежит в файле, а не по догадке, и в ответе можно назвать, какая правка на какой слайд легла. replace_text правит раны (runs), и именно это сохраняет оформление: в аккуратной презентации подпись и значение уже разные раны, поэтому замена «орбитекс форте» оставляет серое «brand » серым, и знать это правило никому не нужно. Строка, которая ничего не нашла, поднимает ошибку: молча не изменить ничего — это способ отдать клиенту презентацию с именем предыдущего. swap_picture меняет картинку на месте, сохраняя позицию, размер и порядок слоёв: add_picture плюс удаление кладёт новую фотографию поверх текста, за которым она должна была стоять. А clear_links снимает гиперссылки, оставляя текст: замена слов ссылки саму ссылку не трогает, поэтому переписанный пункт сохраняет синее подчёркивание и по-прежнему ведёт на рил предыдущего клиента.

Слайд 2 эталонной презентации, перенесённый так, вернулся с теми же десятью фигурами в тех же координатах, тех же цветах, размерах и курсиве, что и в исходнике. Изменились только слова.

Если тянуть зависимость не хочется — вот две механики, на которых он построен:

# Удалить ненужный слайд (перенос обычно вычитает — в прессе слайдов больше,
# чем нужно под один бриф). Убирает слайд из списка слайдов презентации.
xml_slides = prs.slides._sldIdLst
for sld in list(xml_slides)[i:j]:
    xml_slides.remove(sld)

# Заменить картинку на месте, сохранив позицию, размер и порядок слоёв.
old = slide.shapes[k]                      # картинка, которую меняем
new = slide.shapes.add_picture(path, old.left, old.top, old.width, old.height)
old._element.addnext(new._element)
old._element.getparent().remove(old._element)

Нужен слайд, которого в исходнике нет? Продублируйте существующий и переназначьте его. Это и есть ответ на «добавьте два слайда в нашем шаблоне», и он единственный работает: оформление копируется, а не описывается, поэтому гарнитура, акцент, служебные элементы, номер страницы и фотография на фоне переезжают сами, и никому не приходится их замечать. Возьмите тот слайд, чья структура ближе всего к нужной, вызовите duplicate_slide(), переставьте его на место и перепишите текст через replace_text() / set_text(). Два прогона, сделавшие ровно это, вернули все 16 исходных слайдов побайтово теми же, а два новых — неотличимыми от презентации. Не работает другое: нарисовать новый слайд в фирменном стиле и надеяться, что совпадёт. Из «тёмная презентация, лаймовый акцент» никак не следует, что заголовочный шрифт курсивный.

Полнота замены — то, что отказывает молча, поэтому проверяйте счётом. replace_text() различает регистр и ищет по абзацу так, как он читается, поэтому {"ВИКТОР КИМ": "…"} переименует заголовок карточки и оставит Виктор Ким в списке кандидатов двумя слайдами раньше. Передавайте все написания, которые есть в презентации, а потом сверьте возвращённое число замен с числом вхождений, которое вы увидели, когда смотрели, и поищите старую строку в результате перед тем, как отдавать. Прогон, который этого не сделал, заменил одно вхождение из двух и написал «старых вхождений не осталось» — а это хуже, чем просто пропустить, потому что именно отчёту рецензент и верит.

И докажите, что сохранили. plank_deck_qa.py принимает презентацию, ИЗ которой вы переносили, и сообщает, что перенос потерял:

python3 /workspace/scripts/deck/plank_deck_qa.py ported.pptx --source their-original.pptx

Он сравнивает размер страницы, шрифт, курсив дисплейного набора, акцент и число изображений и выдаёт каждое расхождение как находку fidelity-* уровня всей презентации.

И задаёт второй вопрос — тот, из-за которого предложение возвращают: всё ли на слайдах верно для ЭТОГО клиента? Там, где геометрия позволяет сопоставить слайд с исходным, добавляются находки port-*. port-stale-figure — слайд, где заголовок поменяли, а цифру нет: названный режиссёр с гонораром предыдущего кандидата, ошибка, которую клиент находит раньше вас. port-stale-link — гиперссылка, у которой переписали слова, но не адрес: так перенесённый слайд продолжает вести на рил предыдущего режиссёра, и на слайде этого не видно. port-unchanged-slide перечисляет слайды, приехавшие без единой правки; это info, а не warning, потому что оставить слайд как есть часто правильно — собственные credentials продакшна не меняются вместе с клиентом, — и никакое измерение не отличит это от слайда, до которого просто не дошли. Прочитайте их.

На пересобранной презентации ни одна из этих находок не сработает: сопоставлять там нечего. Так и должно быть — у неё проблемы крупнее, и они выше, среди fidelity-*. Это намеренно агрегаты по файлу целиком: сопоставлять слайд 4 со слайдом 6 — гадание, а неверное сопоставление даёт уверенную чепуху; счётчики и множества ловят ту ошибку, которая реально случается. Перенос, сделанный правкой исходника, не даёт ни одной находки; пересобранный — загорается весь. Запускайте перед сдачей и относитесь к ошибке fidelity- как к тому, чем она является: это уже не их презентация.

Какой формат: .pptx или HTML → PDF?

Задайте вопрос про формат — он в таблице вопросов выше и единственный не подпадает под ограничение «три-пять» — и выбирайте по ответу. Скажите, что вы выбрали и чего это стоит, — одной строкой, в том же ответе, которым отдаёте презентацию. Пользователь, который хотел поправить один заголовок и получил PDF, пострадал от решения, о котором ему никто не сказал.

Презентация — это…Собирайте черезПотому что
Питч, бренд-презентация, запуск, доклад на конференции — она должна сработатьHTML, который вы проектируете сами → PDF, метод вышеПолноэкранные изображения, слоистые затемнения и настоящий типографический движок, а характер выведен из темы. Это потолок. plank_slides.py — запасной путь, когда презентацию нужно проверить по геометрии.
Материалы для совета директоров, финансовый обзор, месячный отчётлюбой — спроситеОбычно .pptx, потому что такое перекраивают. HTML — если показывают один раз и убирают в архив.
То, что заказчик будет править, ребрендировать или использовать как шаблонplank_deck.py.pptxPDF — законченная вещь. Если «пришлите презентацию» значит «пришлите то, что я смогу изменить», — это он.
То, что должно открыться в PowerPoint на чьём-то ноутбукеplank_deck.py.pptxОчевидно.

Чего лишается каждый из вариантов, прямым текстом:

  • HTML → PDF нельзя редактировать. Ни фигуры подвинуть, ни данные диаграммы открыть двойным кликом, ни текст перенабрать. Изменить что-либо — значит изменить скрипт сборки и распечатать заново. Если это неприемлемо, формат выбран неверно, — и выяснять это надо до сборки, а не после.
  • .pptx визуально слабее. Он рисует фигуры. Поверх фотографии ложится только одна линейная заливка, карточка — это плоский прямоугольник с острыми углами, и нет ни режимов наложения, ни градиентных сеток, ни линий тоньше пункта. Выглядит как хорошая презентация; не выглядит как арт-дирекшн.
  • HTML → PDF ещё и нужен рендерер, которого в этом рабочем пространстве может не быть. Печать идёт через headless Chromium. Выполните проверку доступности выше до сборки: пусто — значит это рабочее пространство не может печатать HTML, скажите об этом прямо и соберите .pptx; вы теряете полноэкранный вид, но презентация всё равно получится.

Всё остальное общее: те же темы studio/report, те же проверенные палитры, та же 12-колоночная сетка, те же примитивы с теми же именами и аргументами, те же текстовые лимиты, тот же инструмент проверки. Перевести готовый скрипт сборки с одного на другой — это поменять строку импорта.

HTML-путей два, и они меняют одно и то же в противоположные стороны. plank_slides.py пишет HTML и манифест .slides.json рядом, а по нему plank_deck_qa.py измеряет каждое положение слова, каждый вылет и каждое наложение — ценой того, что оформление будет хаус-стайлом, а не выведенным из темы. Спроектировать HTML самомуметод выше — это потолок того, как презентация может выглядеть; манифеста там нет, поэтому геометрию не измерит никакой инструмент. Это настоящий размен, а не вкусовщина: на ручном пути проход «напечатать и посмотреть» не опция, а единственная существующая проверка геометрии. Берите его для питча и запуска; берите plank_slides.py, когда презентация рутинная и проверяемость важнее запоминаемости.

Что вы получаете

  • Файл .pptx или презентацию HTML/PDF в формате 16:9 — стандартное широкоформатное соотношение сторон.
  • По умолчанию — арт-дирекшн на тёмном фоне: почти чёрные поверхности, курсивный крупный шрифт, экономно используемый акцентный синий Plank, полноэкранные фотографии там, где есть что показать, и постоянная строка с брендом сверху и снизу. Светлый типографский стиль — в одном аргументе: new_deck(theme="report").
  • Встроенные, редактируемые диаграммы — а не картинки диаграмм. Дважды кликните по диаграмме в PowerPoint — и её данные сразу под рукой.
  • Заметки докладчика на каждом слайде, а не только на тех, где они кажутся нужными.
  • Текст набран шрифтами Inter и JetBrains Mono, которые подставляются на том компьютере, где открывают файл. Если на компьютере нет этих шрифтов, он подставит свои — презентация всё равно откроется и будет читаться корректно, просто другим шрифтом.

Фирменный стиль

Две темы, и по умолчанию — тёмная

new_deck() собирает в теме studio; new_deck(theme="report") — в теме report.

studio (по умолчанию)report
Для чегоПитч, презентация бренда, запускСовет директоров, финансовый обзор, всё, что печатают
ПоверхностьОбсидиан #0A0A0F, карточка #1A1A22, линия #2E2E3AТёплая слоновая кость #FAFAF7, карточка #F0EDE8, линия #DDD8D0
Текст#FAFAF7, приглушённый #A2A2AE#3A3A42, приглушённый #6B6B75
Акцент — линейки и полосыСиний Plank #4F6DF5Синий Plank #4F6DF5
Акцент — мелкие подписи#8FA6FF (8.5:1 на обсидиане, 7.5:1 на карточке)#3F58CE (5.7:1 на слоновой кости, 5.1:1 на карточке)
Крупный шрифтКурсивПрямой
Сигналыхорошо #34D399, плохо #FF6B6B, предупреждение #F5B02Bхорошо #34D399, плохо #EF4444, предупреждение #F59E0B

Красный «плохо» в тёмной теме светлее не случайно: #EF4444 даёт на обсидиане всего 4.0:1.

Обе темы акцентируют синим Plank. Они различаются поверхностью, начертанием и наличием фотографий — но не фирменным цветом. Различается ступень светлоты для мелкого текста, и это требование контраста, а не вопрос вкуса: на 9 и 11 пунктах акцент — это основной текст, ему нужно 4.5:1, а чистый #4F6DF5 даёт лишь 4.55:1 на обсидиане и 3.98:1 на тёмной карточке — ниже порога ровно там, где стоят номера шагов и подписи карточек. В светлой теме та же проблема была в обратную сторону и даже чуть хуже (4.15:1 на слоновой кости, 3.72:1 на камне). Поэтому у каждой темы есть одна дополнительная ступень того же тона — светлее на тёмном, темнее на светлом, обе в пределах 2.3° от синего Plank по OKLCH. Линейки и полосы — крупные фигуры с порогом 3:1, они остаются чистым #4F6DF5 в обеих темах.

Поверх фотографии обе темы используют #8FA6FF: затемняющая подложка гарантирует только светлый текст на тёмной заливке.

Чего тема менять не имеет права — это геометрию, кегли и лимиты. Они общие: один и тот же скрипт собирается в любом виде, и таблица лимитов ниже одна. Пересборка презентации в другой теме меняет цвет, начертание и наличие фотографий — но никогда не то, что помещается на слайд.

Как выбрать. Убеждать — studio; разбираться в цифрах — report. Если презентацию будут печатать, копировать, читать на бумаге или проецировать в светлом зале, это report. Если пользователь просит «светлую версию», «как раньше» или презентацию на печать — передайте theme="report" и скажите об этом.

Палитры диаграмм — фиксированный порядок, не переставлять и не заменять цвета

Их две — по одной на поверхность, потому что безопасность для дальтоников — это утверждение о палитре и о фоне, на котором она нарисована, и оно не переносится с одного фона на другой. Каждая проверена именно в этой последовательности. Каждый примитив с диаграммой назначает цвета из палитры своей темы по порядку.

studio, на обсидиане #0A0A0F — наихудшая соседняя ΔE при цветовой слепоте 16.1 (протанопия), при обычном зрении 18.2, все шесть дают контраст ≥3:1 и попадают в диапазон светлоты OKLCH для тёмной темы 0.48–0.67: #4B8EFF синий, #C08A1F охра, #00A4BF бирюзовый, #30AE40 зелёный, #9B5CD7 фиолетовый, #DE5077 розовый.

report, на слоновой кости #FAFAF7 — наихудшая соседняя ΔE при цветовой слепоте 15.1, при обычном зрении 15.6, все шесть дают контраст ≥3:1: #4F6DF5 синий, #C2701F охра, #0E9F9F бирюзовый, #4C7A2E зелёный, #9B5DE5 фиолетовый, #C2456B розовый.

Тёмная палитра выведена заново, а не «осветлена на глаз». Светлая не проходит диапазон светлоты для тёмной темы вообще, а её охра и зелёный не дотягивают до 3:1 на почти чёрном — так что «те же цвета, только поярче» дали бы палитру без всякой гарантии.

Типографика. Inter — везде; JetBrains Mono закреплён за табличными данными — тело таблиц, где столбец цифр должен выравниваться, — и не распространяется на само значение KPI или его дельту, которым не с чем выравниваться (см. ниже). Заголовок обложки — 44pt/700, трекинг −0.03em. Заголовок слайда — 30pt/700, трекинг −0.03em, привязан к нижнему краю блока, достаточно высокого для двух строк плюс отступ 6pt под ними, поэтому длинный заголовок растёт вверх и никогда не сталкивается с акцентной линией под ним. Этот отступ несущий: отрисованная буква заходит чуть ниже своей строки, и пока блок заканчивался ровно там же, где текст, каждый слайд с заголовком в каждой презентации выносил выносной элемент буквы за пределы своей фигуры. Просто увеличить высоту блока не помогает — текст, привязанный к нижнему краю, уезжает вниз вместе с ним, — поэтому место приходится резервировать отступом, недоступным тексту. Метка секции-разделителя — 40pt/700, трекинг −0.03em — того же размера, что и заключительный слайд, а не меньшая надпись-«бровь», с которой она начиналась. Утверждение (statement) — 32pt/700. Основной текст — 16pt/400. Значение KPI — 40pt/700, Inter. Метки-«брови» (номера секций, подписи карточек сравнения, «бровь» на полноэкранном слайде) — 11pt/700, трекинг +0.08em. Футер обложки, контакты на финальном слайде и указание автора цитаты — тот же трекинг, но начертание 400 и приглушённый цвет: это тихие служебные строки, а не заголовки, и конструктор не делает их полужирными. Фирменное обрамление ещё тише — 9pt, трекинг +0.06em.

Крупный шрифт в теме studio — курсивный, в report — прямой: обложки, заголовки слайдов, утверждения, метки разделителей, цитаты, заголовки полноэкранных слайдов и финальный слайд. Это самое дешёвое, что превращает презентацию из шаблона в работу с арт-дирекшном, и, поскольку это начертание, а не кегль, на лимиты оно не влияет: ширины символов Inter Italic отличаются от прямого меньше чем на 1% — это внутри тех 9% запаса, которые и так заложены в каждую оценку.

Геометрия. 13.333in × 7.5in (16:9). Поля 0.75in слева/справа, 0.6in сверху, 0.7in снизу. 12-колоночная сетка с отступами 0.2in между колонками — каждый примитив располагается на этой сетке, никогда в произвольных координатах.

На каждом слайде зарезервированы две полосы обрамления — независимо от того, задан ли бренд: строка метаданных высотой 0.24in, начинающаяся от верхнего поля (0.60in), и футер высотой 0.25in, заканчивающийся у нижнего поля (6.55–6.80in). Они внутри безопасных полей, а не в них: содержимое в полях обрезают проекторы, и проверка считает это ошибкой. Резервируются они всегда, и это осознанно: презентация без бренда верстается так же, как та же презентация с брендом, поэтому добавленный позже логотип не переверстает молча все слайды, — и таблица лимитов остаётся одна, а не две, которые должны совпадать.

Поэтому полоса заголовка начинается на 0.94in, акцентная линия стоит на 2.17in, полоса содержимого идёт с 2.44in до 6.55in, а подписи источников живут в своей полосе на 6.24–6.49in, прямо над футером.

Вертикальный ритм. Под акцентной линией есть полоса содержимого высотой 4.11in, и каждый примитив тела слайда меряется по ней, а не по слайду целиком. Блок, который её игнорировал — плитка KPI фиксированной высоты, карточка шага, таблица из трёх строк, — заканчивался на 48–57% высоты слайда 16:9, и под ним не было ничего: это читается как незаконченный слайд, а не как намеренный воздух. Блоки по-прежнему начинаются у верха полосы и никогда ниже: ряд, отпущенный на дюйм ниже акцентной линии, перестаёт читаться как относящийся к своему заголовку. Вниз они растут двумя способами — в зависимости от того, что задаёт их высоту:

  • Карточки — плитки KPI и шаги процесса — имеют высоту, которую задаёт не содержимое, а вёрстка: 3.29in, содержимое карточки центрируется внутри. Не вся полоса: на 3.70in три коротких строки плитки повисают посреди почти пустой поверхности — дыра в слайде никуда не девается, она просто переезжает внутрь карточки. Высота карточки шага, кроме того, зависит от числа шагов: два шага — это карточки шириной 5.7in, а в шаге на порядок меньше «краски», чем в значении KPI на 40pt.
  • Строки — пункты списка, пункты сравнения, строки таблицы — это количество, умноженное на шаг. Растягивается именно шаг, до предела. Содержимое, которое и так заполняет полосу, размечено ровно как раньше; короткому достаётся больше воздуха, а не более крупный шрифт. Предел здесь и есть смысл: два пункта на слайде должны остаться двумя пунктами с хорошим воздухом, а не превратиться в два огромных.

Блок, заполняющий полосу, доходит до 3.70in и останавливается прямо над полосой подписи источника — ради этого доля заполнения и существует, и поэтому диаграмма теперь 3.70in высотой, а не 3.90in, как было до появления полос обрамления. Пустота, оставшаяся под действительно коротким содержимым, — это правильно, и её никто не убирает; см. Воздух.

Типы слайдов

Четырнадцать примитивов, каждый — функция в конструкторе. Выбирайте тот, что действительно подходит по смыслу слайда — не втискивайте содержимое в неподходящую форму только чтобы не осваивать новый примитив.

  • cover — открывающий слайд: заголовок, необязательный подзаголовок, докладчик и дата.
  • section_divider — нумерованная отбивка между разделами доклада, во весь слайд.
  • statement — одно яркое утверждение по центру, ничто больше не отвлекает.
  • bullets — слайд с заголовком и до шести пунктов, у каждого — сколько угодно необязательных подпунктов в пределах общего лимита в 8 строк.
  • compare_two — две подписанные карточки рядом, для сравнения «было/стало» или «А против Б».
  • kpi_row — от двух до четырёх ключевых чисел в плитках, у каждой — подпись, необязательная дельта и необязательный tone, который её окрашивает.
  • table_slide — таблица с данными и необязательной подписью источника под ней.
  • chart — встроенная, редактируемая диаграмма; тип выбирается по тому, что должен вынести читатель, а не по тому, какой тип красивее смотрится.
  • quote — одна цитата с указанием автора, во весь слайд.
  • labelled_blocks — от двух до четырёх подписанных карточек сеткой (2×2 для четырёх), с необязательной «бровью» на месте акцентной линии и необязательным лидом под заголовком. Форма для набора равноправных вещей: четыре компетенции, четыре гарантии, четыре рынка. Берите его вместо bullets всякий раз, когда у пункта есть НАЗВАНИЕ, а не только фраза: плоский список из четырёх читается как упорядоченный, а они не упорядочены.
  • process — до пяти пронумерованных шагов в виде ряда карточек. Шаг — это строка или {"label": …, "text": …}, если у этапа есть название, которое стоит отделить от описания.
  • hero — фотография во весь слайд с заголовком поверх неё, плюс необязательная «бровь» и одна строка под заголовком. Открытие питча, отбивка перед разделом, тот самый слайд, который должен подействовать картинкой, а не аргументом.
  • image_content — картинка в правых пяти колонках полосы содержимого, до четырёх пунктов в левых семи. Аргумент, которому нужна картинка рядом, а не под ним.
  • closing — финальный слайд: заголовок, необязательный призыв к действию, необязательные контакты.

hero и image_content — те два, что принимают путь к файлу. См. Изображения ниже: правила там не факультативны.

Текстовые лимиты

Каждый примитив измеряет свой текст относительно блока, в который тот должен поместиться, и выбрасывает DeckError, а не полагается на то, что кто-то запомнит число. Измерение происходит до того, как что-либо нарисовано: слайд, который не вмещает своё содержимое, не создаётся вовсе, вместо того чтобы обнаружиться позже. Превышение лимита значит, что слайд несёт две идеи сразу, а не что шрифт нужно уменьшить — исправление — сократить текст или разделить слайд, но никогда не уменьшать размер шрифта.

Лимиты — это проверка, которая выполняется во время сборки, и не единственная: когда файл готов, его можно отрендерить и посмотреть на него — см. Проверка готовой презентации.

Лимит — это измерение, а не подсчёт символов. Каждый символ «стоит» оценочную долю em: 0.52 для латиницы в нижнем регистре, цифр и пунктуации, 0.58 для кириллицы, 0.68 для прописных в любом алфавите, 1.0 для CJK и эмодзи, 0.26 для пробела — плюс примерно 9% запаса. Фрагменты в JetBrains Mono считаются по точной ширине 0.60em и без запаса: у моноширинного шрифта нет более широкого глифа, который можно было бы недооценить. Затем конструктор переносит строку по словам так же, как это сделает рендерер, и выбрасывает ошибку, если строк нужно больше, чем помещается в блок.

Практическое следствие: в один и тот же блок помещается примерно на 10% меньше кириллических символов, чем латинских, и ещё меньше, если текст набран прописными. Именно поэтому в таблице ниже два числа. Правило — не они, а само измерение. Прежний единственный коэффициент был откалиброван на английской прозе — и именно эта страница отдавала его русскоязычным читателям: русская строка на английском лимите выходила за пределы карточки.

Ещё два правила, которые проверяются:

  • Никаких переводов строк и табуляций. Каждая строка с лимитом по построению однострочная. "Q1\nQ2" — это пять символов, они проходят любой лимит ячейки и удваивают высоту строки таблицы с фиксированной высотой.
  • Никаких неразрывных фрагментов шире строки. Перенос по словам не может разорвать слово внутри, поэтому длинный URL, артикул или сложное слово вроде Перерасчёт-отчётности уезжает за край узкой карточки, каким бы коротким ни был весь текст. Разбейте его пробелом или дефисом.
Часть слайдаПримерная вместимость (английский / русский)
Блок обложки (заголовок + подзаголовок)Оба живут в ОДНОМ блоке, поэтому и лимит у них один, и он измеряется на паре. Заголовок — до 6 строк по ~26 / ~23 символа (редакторский предел 90), подзаголовок — до 2 строк по ~67 / ~60 (предел 140), но решает не это, а весь блок относительно места над строкой докладчика. Если заголовок помещается один, а пара — нет, подзаголовок отбрасывается, и обложка всё равно рисуется, с предупреждением Python о том, что именно ушло. Обложка — единственный слайд, отсутствие которого хуже любого компромисса в нём
Футер обложки, контакты на финальном слайдеодна строка, ~127 / ~115 символов
Заголовок слайда2 строки по ~52 / ~46 символов и не больше 80 символов — блок заголовка привязан к нижнему краю и растёт вверх, поэтому акцентная линия и текст под ней не двигаются. Блок — это 1.10in под текст плюс отступ 6pt снизу, который тексту недоступен. У image_content заголовку достаётся всего семь колонок: 2 строки по ~27 / ~24 символа
Метка секции-разделителяодна строка, ~33 / ~29 символов
Утверждение (statement)4 строки по ~39 / ~35 символов и не больше 140 символов
Список (bullets)максимум 6 пунктов; всего 8 строк на пункты и подпункты вместе; по одной строке на каждый — ~75 / ~67 символов на пункт (маркер «—» считается) и ~81 / ~73 на подпункт
Сравнение (compare_two)максимум 5 пунктов на сторону, по одной строке: ~44 / ~39 символов на пункт, ~53 / ~48 на подпись карточки
Ряд KPI2–4 плитки. Значение, подпись и дельта стоят в ОДНОЙ стопке внутри плитки, и лимит — это 2.45in этой стопки: строка значения в 40pt высотой в три строки подписи, поэтому построчный лимит на каждое поле отдельно эту связь выразить не может. На практике это однострочное значение плюс до 8 строк подписи (7 с дельтой) — примерно 130 / 115 символов подписи при четырёх плитках. До 18.09.2026 подпись была ограничена одной строкой: это около 12 символов кириллицей, чего не хватает, чтобы сказать, что значит число. Цвет дельты задаётся необязательным tone плитки (good / bad / neutral), а не знаком
Таблицамаксимум 6 колонок × 8 строк. Ячейка может переноситься, и строка растёт под неё; лимит — суммарная высота таблицы относительно полосы содержимого (3.70in), где однострочная строка стоит 0.30in, а каждая следующая строка текста — 0.20in. Поэтому четыре строки с двухстрочной колонкой помещаются, а восемь — нет; прежнее правило «одна строка на ячейку» этих двух случаев не различало. Ячейка не может быть длиннее 4 строк. Заголовок (Inter): ~41 / ~36 символов при 3 колонках и до ~18 / ~16 при 6. Ячейка тела (JetBrains Mono, точно): 36 на строку при 3 колонках и до 16 при 6. Строка с неверным числом ячеек отклоняется целиком
Процесс (process)максимум 5 шагов. Карточка растёт по содержимому: шаг может занять столько строк, сколько держит полоса содержимого (максимум 9, и 8, если у шага есть подпись), а карточка вырастает под самый полный из них — и не дальше. Короткий ряд не растягивается до «типовой» высоты: он берёт высоту своего содержимого, а сам ряд ставится в полосе оптически. Необязательная подпись шага label — одна строка, не больше 40 символов, и она отнимает у шага одну его строку. Символьного предела у текста шага нет: прежние жёсткие 32 отказывали примерно трети того, что карточка вмещает
Цитата4 строки по ~49 / ~44 символов и не больше 180 символов; указание автора — одна строка, не больше 60
Заголовок финального слайда3 строки по ~27 / ~24 символа и не больше 60 символов; призыв к действию — 2 строки, не больше 90
Подпись источника диаграммыодна строка, ~147 / ~131 символ
Подписи категорий диаграммыпо одной строке, делят ширину области построения: ~33 / ~29 символов при 4 категориях, ~22 / ~19 при 6
Полноэкранный слайд (hero)Заголовок — 3 строки по ~27 / ~24 символа и не больше 60: это намеренно жёстче, чем 80 у обычного заголовка, потому что длинную фразу поверх фотографии не читает никто. Блок привязан к нижнему краю, как и обычный заголовок, и вмещает все три строки: 2.07in под текст (три строчных бокса по 48pt плюс 4.8pt на выносные элементы вверх) плюс те же 6pt отступа снизу. Раньше было 1.86in — это 2.7 строки, и русский заголовок в 54 символа, укладывающийся в лимит, вылезал на 14.8pt за верхний край блока. «Бровь» — одна строка, не больше 40 символов, и она стоит над первой строкой заголовка, а не над блоком, поэтому не зависает в воздухе, если заголовок короткий. Строка под заголовком — 2 строки по ~67 / ~60, не больше 110
Картинка и текст (image_content)максимум 4 пункта. Пункт может переноситься; лимит — полоса содержимого, поэтому пункты вместе могут потратить 8 строк как угодно: те же восемь, что у bullets, потому что это та же полоса и тот же кегль. ~58 / ~52 символа на строку (маркер «—» считается). Подпись к картинке — одна строка, ~60 / ~53, не больше 70
Подписанные блоки (labelled_blocks)2–4 блока. Подпись — одна строка, не больше 40 символов. Карточка растёт по содержимому, и все карточки берут высоту самой высокой, поэтому лимит — весь блок целиком (лид, карточки и промежуток между рядами) относительно полосы содержимого (4.11in: этот примитив не рисует подпись источника, поэтому полоса под неё здесь ни подо что не зарезервирована). В сетке 2×2 лид отнимает место у ОБОИХ рядов, поэтому однострочный лид покупает каждой карточке по строке. «Бровь» — одна строка, не больше 48 символов, и она занимает место акцентной линии: над заголовком места нет, потому что строка метаданных заканчивается на 0.84in, а блок заголовка начинается на 0.94in
Фирменное обрамлениеСтрока метаданных — одна строка, ~79 / ~71 символ (она делит верхнюю полосу с логотипом). Строка футера — одна строка, ~107 / ~95. Обе измеряются один раз, в set_brand, а не на каждом слайде

Ограничения по числу символов выше (32, 40, 60, 70, 80, 90, 110, 140, 180) — это редакторские лимиты для «крупных» слайдов, которые применяются поверх измерения: заголовок обложки такой длины — это проблема текста раньше, чем проблема вёрстки.

Изображения

Картинку принимают два примитива: hero(prs, image, title, eyebrow=None, lead=None, notes="") и image_content(prs, title, image, points, caption=None, notes=""). Оба берут путь к файлу, который уже есть в рабочем пространстве: конструктор изображения потребляет, а не создаёт.

Убедитесь, что файл на месте, прежде чем на него ссылаться. Конструктор тоже проверяет и выбрасывает DeckError до того, как слайд создан, а не после: отсутствующая картинка — единственное в презентации, что ломается молча, превращаясь в пустую рамку, похожую на дизайнерское решение. Пути отсчитываются от того места, откуда запускается скрипт сборки, поэтому держите скрипт и картинки рядом и указывайте тот же относительный путь, каким открыли бы файл.

Текст поверх фотографии всегда получает затемнение (скрим), и это часть конструкции. Оба примитива кладут между картинкой и текстом тёмный градиент, и отключить его нечем. Это не вкусовщина: только он делает текст читаемым на картинке, которую никто не проверял, а «возьмите фото потемнее» — не гарантия, потому что следующее фото — это лотерея. Текст поверх изображения — всегда светлый по этому градиенту, в обеих темах: фотография не является поверхностью, чей цвет кому-то известен, поэтому светлая тема не кладёт на неё графитовый текст.

Градиент плотнее всего в нижней трети, где стоят заголовок, подводка и футер, и почти прозрачен посередине, чтобы картинка осталась картинкой. image_content по той же причине затемняет узкую полосу под подписью, а не всё изображение.

И это проверяется. plank_deck_qa.py растеризует каждый слайд, поэтому для каждого слова, отрисованного поверх картинки, он считывает пиксели, реально оказавшиеся позади, и вычисляет настоящий контраст по WCAG. Меньше 3:1 — ошибка; от 3:1 до 4.5:1 — предупреждение. См. Проверка готовой презентации.

Если вы ставите текстовый блок поверх картинки вручную, а не этими примитивами, затемнение — на вас, и проверка скажет, если вы ошиблись.

Диаграммы

chart(prs, title, goal, categories, series, source, notes) выбирает тип диаграммы по goal, а не «на глаз»: скажите, что должен вынести читатель, и конструктор сам подберёт форму, которая это показывает:

GoalТип диаграммы
comparisonсгруппированные столбцы
trendлиния
compositionсоставные (накопленные) столбцы
partкольцевая диаграмма (doughnut)
progressгоризонтальные столбцы (ранжированные, читаются сверху вниз)

Встроенные диаграммы — векторные и полностью редактируемые: читатель может кликнуть и увидеть данные, — и они автоматически наследуют шрифты и палитру серий презентации. Заголовок диаграммы формулирует вывод («Расходы на поддержку упали на 40% после внедрения triage»), а не просто измерение, которое отображается («Расходы на поддержку»). У каждой диаграммы есть подпись источника, и она измеряется так же, как любая другая строка.

У столбчатых диаграмм нулевая база. Для comparison, composition и progress минимум оси значений выставляется в 0, поэтому небольшую разницу нельзя преувеличить обрезанной осью: длина столбца кодирует величину, а длина, отмеренная от произвольного уровня, обманывает. Для trend автомасштаб PowerPoint оставлен намеренно: на временном ряду нулевая база обычно «сплющивает» именно то движение, ради которого диаграмма и строится.

goal="part" рисует одно кольцо: он отклоняет больше одной серии (кольцо может показать только одну) и больше шести категорий, потому что кольцевая диаграмма раскрашивает свои сегменты, а в проверенной палитре только шесть цветов — сгруппируйте длинный хвост в «Прочее», а не добавляйте седьмой сегмент. У остальных типов максимум двенадцать категорий: дальше подписи налезают друг на друга и диаграмма на самом деле является таблицей.

«Рваные» данные отклоняются, а не рисуются молча. Серия, у которой значений меньше, чем категорий, отобразит только часть данных; серия с лишними значениями потеряет хвост. И то и другое выбрасывает ошибку — как и значение, которое не является числом и не является NoneNone — это осознанный пропуск). table_slide так же отклоняет «рваную» таблицу: в каждой строке должно быть ровно столько ячеек, сколько заголовков.

Диаграммы следуют тому же разделению шрифтов, что указано выше: JetBrains Mono — только в ячейках тела таблиц, Inter — везде остальном, включая заголовки таблиц, подписи источников и подписи осей. Фиксированная ширина моно работает против крупного числа: она открывает заметный зазор вокруг запятой или ведущего минуса и ещё больший — перед кириллической единицей измерения, поэтому значение KPI тоже набирается в Inter.

Если то, что вам нужно, нельзя выразить как встроенную диаграмму OOXML — водопад (waterfall), диаграмма Ганта, санки (sankey), комбинированная диаграмма с аннотациями, — используйте запасной вариант: отрендерите её в matplotlib в PNG и вставьте как изображение. Делайте это осознанно: в рабочих пространствах Plank не установлены шрифты, поэтому matplotlib рендерит текст своим шрифтом по умолчанию — DejaVu Sans, — и результат не будет соответствовать остальной типографике презентации. Используйте это только для форм, которые OOXML действительно не может выразить, а не как обходной путь вместо встроенного примитива диаграммы.

Как писать слайды

Всё, что выше, делает слайд правильно устроенным. Хорошим он от этого не становится. Презентация может уложиться во все лимиты — и всё равно открываться заголовком, который называет тему вместо вывода, тратить шесть слайдов на одну мысль и прятать решение на девятом. Ниже — то, что код проверить не может.

Эти правила — сужение под презентации того общего стандарта, который поставляется в виде двух устанавливаемых навыков: Deliverable Writing и Deliverable Design. Они распространяют ту же планку на HTML-документы и дашборды. Для презентаций эта страница главнее и содержит разобранные примеры. Если хотя бы один навык установлен в этом рабочем пространстве, вызовите его перед выдачей результата. См. Навыки.

Начинайте с ответа и дальше его доказывайте. Первый слайд после обложки формулирует вывод. Всё, что после, — поддержка: аргументы, на которых вывод держится, и под каждым аргументом — его доказательства. Никогда не подводите к рекомендации двадцатью слайдами: зал решает в первую минуту, слушает он или нет, и читатель, у которого ответ уже есть, читает дальнейшее как доказательство, а не ждёт, зачем его позвали.

Презентация начинается сИ читается как
«Обзор рынка» → «Наши услуги» → «Кейсы» → «Наше предложение»Четыре слайда позади, а чего от него хотят — никто не знает
«Ручной пересчёт стоит нам 40 млн ₸ в год» → «Из чего складываются потери» → «Пилот убрал два источника из трёх» → «Утвердить внедрение до 1 октября»Сначала вывод, дальше — почему он верен и что с этим делать

Заголовок формулирует вывод, а не тему. Заголовок несёт утверждение, тело слайда — доказательства. Прочитайте одни заголовки подряд, сверху вниз, — должна получиться вся аргументация, начиная с первого, который уже должен быть ответом, а не обещанием ответа.

ВместоПишите
Расходы на поддержкуРасходы на поддержку упали на 40% после внедрения triage
Итоги III кварталаВыручка III квартала выросла на 12% — целиком за счёт продлений
План наймаНужны два аналитика до октября, иначе IV квартал сдвинется

Одна мысль на слайд. Это то же правило, которое лимиты проверяют с другой стороны: если текст не помещается, причина почти всегда в том, что на слайде две мысли, а не в том, что шрифт великоват. Разделите слайд и дайте каждой половине заголовок с её собственным выводом.

У каждого числа должна быть база сравнения и направление. «40%» не измеряет ничего. «На 40% меньше, чем во II квартале» — это вывод. Единицы измерения всегда, и всегда говорите, с чем сравниваете: с прошлым кварталом, с планом, с другим поставщиком. Дельта у плитки KPI — то же правило: -40% ко II кв., а не -40%.

И скажите, хорошая ли это новость, — знак этого не скажет. У kpi_row есть необязательный tone для каждой плитки — "good", "bad" или "neutral", — и только он определяет цвет дельты:

{"value": "-2,0", "label": "Передач на диалог", "delta": "-2,0 ко II кв.", "tone": "good"}
{"value": "-12%", "label": "Выручка на клиента", "delta": "-12% ко II кв.", "tone": "bad"}
{"value": "2,4x", "label": "Обращений в день", "delta": "2,4x ко II кв."}

Дельта без tone — нейтрального цвета, каким бы ни был её знак. Раньше конструктор читал знак: ведущий + — зелёный, всё остальное — красный, — и красил -2,0 передачи на обращение, -31% оттока и -40% расходов в тот же красный «ошибки», что и провал. Для большого класса деловых метрик снижение и есть выигрыш, поэтому знак действительно ничего не решает: -40% — выигрыш по расходам и провал по выручке. Конструктор больше не угадывает, потому что именно угадывание и породило эту ошибку, а неверный цвет хуже, чем никакой: нейтральная дельта всё равно сообщает число, красная сообщает о провале, которого не было. Если дельта заслуживает зелёного или красного — скажите это через tone. Опечатка в tone вызывает DeckError, а не молчаливый откат к значению по умолчанию.

Пункты одного слайда — в одной грамматической форме. Одинаковая форма означает, что читатель сравнивает содержание, а не разбирается в формулировках. Не «Расходы снижены на 18% / Мы наняли двух аналитиков / Улучшения по задержкам», а «Снизили расходы на 18% / Наняли двух аналитиков / Снизили задержку p95 на 40%».

Говорите «и что теперь». Назовите решение или действие — и того, кто за него отвечает. «Утвердить наём двух аналитиков до 15 сентября» — это оно; «стоит подумать о найме» — нет. Презентация, которая заканчивается без этого, — отчёт, а отчёту слайды не нужны.

Убирайте пустые слова. «Обзор», «Введение», «Дальнейшие шаги» — это названия ячеек в шаблоне, а не выводы: переименуйте слайд в то, что он на самом деле говорит. Никакой разогревающей фразы перед первым пунктом и никакого пункта, который пересказывает заголовок другими словами.

Заметки докладчика несут то, что на слайд не помещается. Конструктор отказывается собирать слайд без них — так пользуйтесь ими по назначению: откуда взято число, какую оговорку было бы нечестно опустить, ответ на очевидное возражение, цифра, которую вы назовёте, если спросят. Не пересказ пунктов — их аудитория и так прочитает.

Чтобы выглядело продуманно

Лимит доказывает, что текст помещается в свой блок, и больше ничего. Уравновешен ли слайд, есть ли иерархия, держится ли презентация как целое — это вопрос суждения. Ниже — привычки, которые заменяют тот взгляд на слайд, которого не будет.

Иерархия — это размер, насыщенность и место, именно в таком порядке. Заголовок заметно крупнее того, что его поддерживает, а не на пункт-другой, и главный вывод стоит там, где взгляд начинает: слева вверху для читающего по-русски или по-английски, ровно по центру — на statement. Примитивы это уже делают. Блок, поставленный руками и уводящий вывод вправо вниз, это отменяет.

Одна точка фокуса на слайд, и взгляд должен попадать в неё первым. Решите, что читатель должен увидеть первым — число, диаграмму, утверждение, — а всё остальное пусть будет поддержкой. Если за эту роль спорят два элемента, один из них — на отдельный слайд или в заметки.

Два шрифта, и никакого цвета вне темы. Фирменный стиль поставляется ровно с двумя гарнитурами (Inter, JetBrains Mono) и двумя проверенными палитрами по шесть цветов, поэтому правило по сути звучит как не добавлять: никакой третьей гарнитуры и никакого цвета, которого нет ни в токенах темы, ни в палитре серий. Иерархию внутри одного семейства делают насыщенность и кегль — они для этого и нужны. Шесть цветов серий — это смысл, а не украшение: они назначаются в фиксированном проверенном порядке, поэтому один и тот же цвет означает одно и то же по всей презентации. Если слайду нужен акцент, используйте положение, размер или воздух. plank_deck_qa.py считает гарнитуры и предупреждает о третьей; цвет он оставляет вам, потому что рабочее пространство имеет право переопределить primary и accent, и отличить это от слайда, покрашенного в красный «для оживления», инструмент не может.

Раскладка следует форме содержимого — то есть выбирайте примитив, а не придумывайте вёрстку. Текст с картинкой рядом — это image_content; утверждение против контрутверждения — compare_two; сгруппированные метрики — kpi_row из двух-четырёх плиток; последовательные этапы — process. Желание придумать новую раскладку почти всегда означает, что содержимому нужен уже существующий примитив.

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

Картинкой может быть сам шрифт. Презентация без фотографий — не худшая презентация. Крупная выразительная типографика как главный визуальный приём — statement, section_divider, обложка, на которой нет ничего, кроме утверждения, — это полноценная альтернатива изображениям и обычно лучший ответ для финансовой или отчётной презентации. Это же и есть ответ, когда на вопрос об изображениях отвечают «без картинок».

Диаграммы должны читаться. Правила выше уже задают заголовок с выводом, нулевую базу и подпись источника — соблюдайте их. Сверх этого: называйте серию словами, которые читателю не придётся сопоставлять с цветом. У одной серии легенды нет вообще — вынесите её название в заголовок («Регистрации по неделям, 2026»); шесть серий с легендой внизу означают, что читатель занят сопоставлением цветов: разделите диаграмму или сгруппируйте хвост в «Прочее».

Единообразие по всей презентации. Четвёртый слайд с KPI должен выглядеть как первый: тот же примитив для той же задачи, тот же порядок элементов, те же формулировки подписей.

Конструктор (builder)

Код конструктора не нужно переписывать вручную — его нужно скачать:

mkdir -p /workspace/scripts/deck
curl -sSfL -o /workspace/scripts/deck/plank_deck.py https://plank.md/help/assets/plank_deck.py

Он кладётся в /workspace/scripts/deck/plank_deck.py — именно в этот каталог и именно под этим именем: подчёркивание принципиально, потому что import plank-deck — синтаксическая ошибка Python. Свой build_*.py кладите в /workspace/scripts/deck/ туда же, тогда from plank_deck import * разрешается без PYTHONPATH и без cd: вызов bash не наследует каталог предыдущего вызова, и именно голое относительное имя файла ломается здесь надёжнее всего. Никогда не пишите файл с именем plank_deck.py сами: он импортируется, ничего не измеряет, и все последующие сборки в рабочем пространстве берут его вместо настоящего конструктора. Коротко обо всём этом: Как собрать презентацию: маршрут.

Полный исходный код для чтения приведён на английской странице How Plank builds a slide deck, в разделе «The builder»; ассистент забирает страницу как markdown по адресу https://plank.md/help/presentations.md. Код и токены не зависят от языка, поэтому он не дублируется здесь — здесь переведён только текст вокруг него.

Конструктор HTML-слайдов

Когда жанр говорит HTML → PDF, конструктор — это plank_slides.py. Ему нужен plank_deck.py рядом, в /workspace/scripts/deck/: он импортирует оттуда темы, сетку, лимиты и словарь целей диаграмм, а не переписывает их, — именно это гарантирует, что два пути не разойдутся:

mkdir -p /workspace/scripts/deck
curl -sSfL -o /workspace/scripts/deck/plank_deck.py   https://plank.md/help/assets/plank_deck.py
curl -sSfL -o /workspace/scripts/deck/plank_slides.py https://plank.md/help/assets/plank_slides.py
from plank_slides import *

deck = new_deck(lang="ru")            # или new_deck(theme="report", lang="en")
set_brand(deck, meta=(("brand", "ACME"),), city="Алматы", year="2026")
cover(deck, "Складская логистика без ручного пересчёта",
      subtitle="…", presenter="…", date="…", notes="…")
hero(deck, "photo.png", "Каждый час склада считают вручную",
     eyebrow="ПРОБЛЕМА", lead="…", notes="…")
save(deck, "deck.html")

Каждый примитив с этой страницы есть и здесь — под тем же именем, с теми же аргументами, и отказывается принимать такой же слишком длинный текст: лимиты импортированы, а не переписаны. Три отличия, о которых стоит знать:

  • new_deck(lang=…). Задаёт язык документа, чтобы браузер правильно переносил и ставил кавычки. Геометрию не меняет.
  • cover(image=…). Титульный слайд в HTML может нести полноэкранную фотографию, чего титульный слайд .pptx не умеет.
  • image_content уходит в обрез. Изображение доходит до верхнего и правого края слайда, а не сидит в рамке, и несёт собственное затемнение, защищающее строку с метаданными.

save() пишет два файла: deck.html и deck.slides.json рядом с ним. Второй — это заявленная геометрия каждого блока, то, что .pptx носит внутри себя, и без него инструмент проверки не сможет сказать, что слово вышло за свою рамку. Держите их вместе; передавайте PDF.

У .html две геометрии, и делать для этого ничего не нужно. Когда презентацию открывают в Plank — или в браузере, или на телефоне, — слайды масштабируются под доступную ширину и выстраиваются один под другим, так что её читают прокруткой: ничего не уезжает вбок и ничего не обрезается, при любом размере окна. Это только экран. На печати каждый слайд по-прежнему ровно 1280×720, один слайд на страницу, — именно поэтому PDF остаётся тем же артефактом фиксированного размера, что и всегда: масштабирование живёт внутри @media screen и до печати не доходит. Это обычный CSS: он работает с выключенным JavaScript, и файл остаётся самодостаточным. Увеличивать себя презентация не станет — шире 1280 px она центрируется в полный размер, а не раздувает шрифт.

PDF выходит из проверки, а не из конструктора — ровно так же, как для .pptx. Это сделано намеренно: PDF, который вы отдаёте, по построению именно тот, который был проверен.

python3 /workspace/scripts/deck/plank_deck_qa.py deck.html     # печатает deck.pdf, затем проверяет его

Свой бренд

Рабочее пространство может скорректировать фирменный стиль выше, добавив блок ## Brand в свой AGENTS.md:

## Brand
- theme: studio
- primary: #0B5FFF
- accent: #F2A65A
- fonts: Söhne / Söhne Mono
- logo: assets/acme-logo.png
- footer: ACME · Конфиденциально · Алматы · 2026
- meta: brand ACME / agency Plank Studio

Этот блок — подсказка, которую ассистент читает и применяет вручную. Его никто не разбирает программно — то есть это НЕ способ задать фирменные цвета заказчика. Это место, где записан бриф. У двух его ключей теперь есть механический путь, и пользоваться нужно им.

Цвета: new_deck(accent=, ink=, ground=)

prs = new_deck(accent="#DAFF00", ground="#000000", ink="#FFFFFF")

ground — это полотно, ink — текст на нём, accent — тот единственный цвет, который принадлежит заказчику. Всё остальное — поверхность карточки, тонкая линия, приглушённый текст — выводится из этих трёх, поэтому палитра остаётся палитрой, а не тремя цветами, брошенными в чужую. Передавайте один, два или все три; то, что не передали, останется от базовой темы.

Каждая выведенная пара измеряется до того, как тема вообще возникнет, по тем же порогам WCAG, которыми plank_deck_qa.py меряет готовый рендер: 4.5:1 для текста, приглушённого текста и мелких акцентных меток — и на полотне, и на карточке; 3:1 для акцента как линии или полосы. Пара, которая не проходит, поднимает DeckError с названием пары и числом — это правимый бриф. Альтернатива — презентация, которую собрали, отдали, и только потом выяснили, что её нельзя прочитать.

Одна пара не проходит чаще прочих: фирменный акцент, выбранный для логотипа, часто слишком тёмен, чтобы набирать им 9pt. Для этого есть accent_text= — более светлая или более тёмная ступень того же тона, не трогающая графический акцент. Ровно так устроены обе встроенные темы (#4F6DF5 как линия, #8FA6FF как метка на обсидиане).

prs = new_deck(theme="report", accent="#0B5FFF", accent_text="#0A47B8")

brand_theme(...) — то же самое, но как значение, если тему нужно собрать один раз и отдать нескольким презентациям: new_deck(theme=brand_theme(accent="#DAFF00", ground="#000000", ink="#FFFFFF")).

Палитра серий диаграмм не выводится и не двигается. Её шесть цветов проверены на безопасность для дальтоников именно в этой последовательности и именно на этой поверхности; фирменный акцент — другая задача, и тремя входными цветами она не решается. Если у заказчика есть настоящая палитра для диаграмм, передайте series= прямо в Theme и считайте, что проверка теперь ваша.

Обрамление: set_brand(...)

Обрамление — это один вызов, и он намеренно отделён от цветов выше: логотип и футер — это содержимое, а палитра — это тема.

prs = new_deck()                      # или new_deck(theme="report")
set_brand(prs,
          meta=(("бренд", "ACME"), ("отдел", "финансы")),
          logo="assets/acme-logo.png",
          confidential="Конфиденциально", city="Алматы", year="2026")

После этого каждый слайд несёт сверху строку метаданных и логотип, а снизу — гриф конфиденциальности, город, год и номер слайда. Вызовите это один раз, до первого слайда. Презентация без set_brand всё равно нумерует слайды: полосы зарезервированы в любом случае.

Четыре момента, которые стоит знать до того, как что-то переопределять:

  • theme выбирает между studio и report. Это единственный ключ, который не про цвет, — и меняет он больше, чем цвет. См. Две темы.
  • primary и accent в блоке ## Brand — это бриф; механизм — new_deck(accent=…). Прочитайте блок, затем передайте цвета. Они меняют акцентную линию и метки-«брови» и никогда не трогают палитру серий диаграмм — почему, сказано выше.
  • Акцент, который хорош на вашей поверхности, может не работать поверх фотографии. Синий Plank нормален на слоновой кости и на грани допустимого на затемнении — поэтому в светлой теме есть второе, осветлённое значение (#8FA6FF) для обрамления и «бровей», попадающих на изображение. Если переопределяете accent — посмотрите на полноэкранные слайды, проверка контраста скажет.
  • Переопределение fonts обесценивает все числа в текстовых лимитах выше. Они выведены из измеренной ширины символов Inter и JetBrains Mono. У другого шрифта ширины другие, ассистенту придётся пересчитать их вручную, а проверить результат в рабочем пространстве нечем — отрендерить презентацию там невозможно. Рассчитывайте посмотреть первую презентацию своими глазами.

logo — путь относительно корня рабочего пространства. Убедитесь, что файл действительно существует, прежде чем на него ссылаться. set_brand отклоняет путь, который не разрешается: это одна ошибка в начале скрипта вместо битой рамки на каждом слайде, — но презентация без логотипа корректна, поэтому лучше пропустить ключ, чем угадывать имя файла. fonts записывается в формате heading / mono; основной текст следует за заголовочным шрифтом — так же, как Inter и JetBrains Mono сочетаются по умолчанию.

Если в рабочем пространстве установлен навык (skill) для создания презентаций и он явно вызван, этот навык имеет приоритет над этой страницей во внешнем виде и содержании — фирменные цвета, шрифт, тон, состав слайдов. Явная инструкция всегда важнее значения по умолчанию. Но он не получает молча приоритет над инструментом: если там прямо не назван другой конструктор и не сказано почему, презентация всё равно собирается через /workspace/scripts/deck/plank_deck.py и всё равно проверяется через /workspace/scripts/deck/plank_deck_qa.py. Навык, который молчит о способе сборки, не выбрал другой маршрут — он просто не упомянул этот.

Проверка готовой презентации

Лимиты выше проверяются до того, как слайд нарисован. Часть дефектов возникает только после того, как рендерер разложил презентацию по странице: таблица, у которой ячейки перенеслись и строки выросли; два блока, наложившиеся друг на друга; диаграмма, у которой налезли подписи; картинка, которая не открылась. Рабочее пространство Plank теперь умеет отрендерить .pptx и посмотреть на результат — значит, всё это тоже проверяемо:

mkdir -p /workspace/scripts/deck
curl -sSfL -o /workspace/scripts/deck/plank_deck_qa.py https://plank.md/help/assets/plank_deck_qa.py
python3 /workspace/scripts/deck/plank_deck_qa.py quarterly-review.pptx

Инструмент конвертирует презентацию в PDF, растеризует каждую страницу в PNG, считывает, где на самом деле оказалось каждое слово, и сравнивает это с геометрией, которую презентация о себе заявляет. Замечания печатаются по слайдам — что не так и что изменить; при наличии ошибок код возврата ненулевой, поэтому инструмент естественно встраивается в цикл «собрать → проверить → исправить». После каждого исправления запускайте его заново.

Он принимает оба форматаplank_deck_qa.py deck.pptx или plank_deck_qa.py deck.html — и это один инструмент, а не два согласованных. Форматы различаются ровно в двух местах: чем читается заявленная геометрия (OOXML или файл .slides.json, который пишет HTML-конструктор) и что рендерит PDF (LibreOffice или headless Chromium). Всё, что ниже этого, — детекторы, пороги, замечания, код возврата — один и тот же код на обоих путях.

Он также создаёт PDF — в папке <имя>-qa/ рядом с презентацией. Это самостоятельный результат работы: презентацию .pptx обычно нужно передать и редактируемым файлом, и PDF, который везде выглядит одинаково, а для HTML-презентации PDF и есть то, что передают.

Что он находит. Текст, вышедший за пределы своей фигуры; текст за пределами безопасных полей слайда; слова, наложившиеся на другие слова, в том числе подписи диаграмм; фигуры, частично перекрывающие друг друга; пустые слайды и слайды, отрисовавшиеся вхолостую; текст-заполнитель вроде Lorem ipsum, TBD или [заполнить]; картинки, чьи байты не открываются или отрисовались пустой рамкой; текст поверх фотографии, который на ней не читается; шрифты, которые запрошены в презентации, но не установлены, — рендерер молча подставил вместо них другие; и больше двух гарнитур — предупреждение too-many-fonts, которое перечисляет все гарнитуры, заданные в презентации. Виновника оно не называет: в файле не написано, какие две имелись в виду, а переопределение бренда заменяет обе гарнитуры, а не добавляет третью.

Проверка контраста — та самая, которой нужен рендер. Из .pptx невозможно узнать, читается ли заголовок поверх собственной картинки: в файле записано, что текст #FAFAF7 и что за ним фотография, но ничего не сказано о том, какого цвета эта фотография именно в этом месте. Поэтому для каждого слова, отрисованного поверх картинки, инструмент считывает пиксели, которые рендерер реально положил позади, отбрасывает те, что являются самой буквой, и вычисляет контраст по WCAG к тому, что осталось. Меньше 3:1 — error: на таком контрасте не читается ничто, никакого кегля. От 3:1 до 4.5:1 — warning: заголовок 3:1 проходит, а подводка или подпись — нет. Лечится это не бо́льшим кеглем и не другой фотографией, а затемнением. См. Изображения.

Русская типографика проверяется тоже — и тем же инструментом можно проверить документ. Почти все, кто читает результат работы Plank, читают по-русски, а "прямые кавычки" вместо «ёлочек», дефис на месте тире и пропущенная ё делают документ чужим, как бы хорошо он ни был выстроен. Ничего из этого не требует читателя — всё решается по символам. Поэтому это проверяется, а не советуется: «ёлочки» в русских кавычках, ё там, где у слова одно прочтение, тире между частями предложения и короткое тире в диапазонах, разряды по-русски и запятая в дробях, неразрывный пробел между числом и единицей в строке, которая может перенестись.

Русский отчёт и дашборд — такой же результат работы, поэтому тому же инструменту можно передать файл .html, .md или .txt: он вычитает видимый текст по тем же правилам, с тем же отчётом и тем же кодом возврата. В этом режиме ничего не рендерится, поэтому не нужны ни LibreOffice, ни poppler:

python3 /workspace/scripts/deck/plank_deck_qa.py квартальный-отчёт.html
python3 /workspace/scripts/deck/plank_deck_qa.py дашборд.html

Получается, .html означает две разные задачи — но говорить, какую именно, не нужно. HTML-презентация рендерится и обмеряется, а HTML-документ или дашборд вычитывается. Инструмент различает их по манифесту .slides.json, который plank_slides.py кладёт рядом с презентацией: манифест есть — презентация, нет — документ. Поэтому презентация никогда не превращается молча в вычитку без проверки геометрии, а презентация с потерянным манифестом падает с ошибкой и просит пересобрать, а не читается как текст. Обе половины проверки презентация получает в любом случае: русские правила применяются и к её слайдам.

Список правил намеренно короткий. Отметить правильный русский хуже, чем пропустить неправильный: инструмент, который поднимает ложную тревогу, выключают, и тогда он не находит уже ничего. Поэтому всё, что нельзя решить по одному фрагменту, оставлено за скобками: ё в словах с двумя прочтениями (все/всё, чем/чём, узнаем/узнаём), неразрывный пробел после однобуквенного предлога, пропущенный пробел перед %, название в «ёлочках» (1С пишет свои документы как «Счет на оплату покупателю», и это не вам исправлять), а также всё внутри кода, ссылки или имени файла. Документ, в котором ё нет нигде, — это стиль, а не ошибка: про него одна строка в шапке отчёта, а не замечание на каждое слово.

Чего инструмент по-прежнему не проверяет — это сам текст: механическую лексику, которой выдаёт себя машинный русский, отглагольные существительные вместо глаголов, безличные пассивы, пустые оценочные прилагательные, утверждения без опоры. Эта половина требует читателя, и для неё есть навык Deliverable Writing.

Чего он не находит. У него нет мнения о том, хороша ли презентация: ни об иерархии, ни о темпе, ни о том, та ли это диаграмма и заслуживает ли слайд своего места. Он находит выход за границы, наложения и пустоту. Он не умеет находить «некрасиво». Чистый отчёт значит, что ничего не сломано, — но не значит, что презентация готова; для этого есть пас критики ниже.

Замечания нельзя молча проглотить. Инструмент делит найденное по важности: ERROR — сломанный слайд, WARNING — дефект, который, скорее всего, всё ещё читается: подставленный шрифт, выносной элемент буквы на пункт за границей блока. Это разделение сделано намеренно и повышать степень мы не будем: если каждое предупреждение станет ошибкой, ошибки перестанут что-либо значить.

Но разделение не даёт права отбрасывать предупреждения. Запуск, который сообщает «12 слайдов, 3 чистых, 9 с замечаниями», нашёл девять дефектов, и «ошибок рендеринга нет» — ложное описание этого запуска, даже если ошибкой не было ни одно из них. Предупреждения существуют для того, чтобы вы приняли решение: исправить — или счесть допустимым и сказать, какое именно. См. Перед тем как передать презентацию.

Одна вещь, от которой зависят эти измерения, и она разная для двух форматов. Для .pptx рендерер — LibreOffice, а не PowerPoint: перенос строк немного отличается, поэтому замечание в пределах одного-двух пунктов допуска стоит считать пограничным, а не фактом. Для HTML-презентации такого разрыва нет: Chromium — это тот самый движок, под который презентация и сделана, поэтому ширины в отчёте — это ширины читателя.

Слайд HTML-презентации обрезается по собственному краю (иначе перелив третьего слайда напечатался бы на странице четвёртого), поэтому текст, целиком уехавший за пределы слайда, раньше в отчёт не попадал — единственный случай, когда «замечаний нет» могло означать «никто и не смог посмотреть». Теперь он измеряется: перед печатью инструмент спрашивает у Chromium, где на самом деле оказались слова каждого блока, и те, что вышли за пределы слайда, возвращаются обычными замечаниями о переливе — с указанием блока, из которого они вышли. В шапке отчёта указано, сколько блоков измерено и сколько слов оказалось за краем. Презентацию, собранную старым plank_slides.py, измерить нельзя — в ней нет разметочных меток, и отчёт скажет об этом, а не промолчит.

Вторая раньше оставалась на вас: шрифты презентации должны быть действительно установлены, иначе каждая ширина в отчёте измерена по шрифту-заменителю. Теперь инструмент спрашивает об этом fontconfig и сообщает сам — предупреждение font-substituted с именем каждого отсутствующего шрифта, на первом слайде, который его запрашивает. Чистый отчёт означает, что измерения сделаны по тем шрифтам, которые запрошены в презентации, а не что никто не проверял.

Пас критики

Всё, что выше, проверяет, что презентация корректно устроена. Ничто из этого её не прочитало — о том, чего это не ловит, см. Как писать слайды.

Поэтому сборка презентации — это четыре шага, а не три, и третий не является необязательным:

собрать → механическая проверка → критика → доработать → передать

Критика выполняется на готовом файле, после plank_deck_qa.py и до того, как вы что-либо передали. Инструмент печатает её в конце каждого запуска — в том числе чистого, потому что чистый механический отчёт — это ровно тот момент, когда презентацию передают непрочитанной. После доработки запустите критику заново, так же как перезапускаете проверку.

Механическая половина

Из инструмента выходят две вещи, и обе дёшевы:

  • Лестница заголовков — заголовок каждого слайда, по порядку, отдельными строками. Это не проверка. Это тест «одни заголовки», от которого невозможно уклониться: инструмент и так знает все заголовки, поэтому напечатать их ничего не стоит — и это снимает отговорку их не читать.
  • Несколько шаблонных подсказок — заголовок, совпавший со служебным словом (Обзор, Наши преимущества, Итоги, Спасибо); заголовок из трёх слов и меньше без единого числа; первый слайд после обложки, который называет тему вместо того, чтобы формулировать ответ (answer-not-first); два слайда, у которых заголовки состоят в основном из одних и тех же слов; слайд с процентом или кратностью, у которого на виду нет подписи источника.

answer-not-first — это принцип пирамиды, механизированный настолько, насколько он вообще механизируется. Инструмент видит, что открывающий заголовок называет тему; он не видит, что корректно сформулированный открывающий заголовок формулирует не тот вывод. Эта половина — вопрос суждения №1.

Подсказки — это эвристики с реальной долей ложных срабатываний, поэтому они печатаются как вопросы, а не как приговоры. У них тип info, они никогда не становятся ошибками и никогда не меняют код возврата. Не согласиться с подсказкой — совершенно нормальный ответ; не согласиться молча — нет.

Половина, которая есть суждение

Эти пять вопросов невозможно автоматизировать, и инструмент печатает их, не отвечая на них. Ответьте на все пять, словами, в своём ответе:

  1. Одни заголовки. Прочитайте лестницу и больше ничего. Формулирует ли первая строка уже сам ответ — или только обещает его? Дальше: держит ли лестница аргументацию от начала до конца? Назовите первый заголовок, из-за которого вам пришлось заглянуть в текст слайда, — вот он называет тему, а не формулирует вывод.
  2. Каждый ли слайд оправдывает своё место? Назовите слайд, который можно удалить без потери, — или скажите, что таких нет, и почему. Слайд, повторяющий более раннюю мысль, считается удаляемым.
  3. Сформулировано ли «и что теперь»? Процитируйте слова на слайдах, которые говорят, что читателю следует сделать, и назовите, кто за это отвечает. Не подразумевается, не «стоит рассмотреть» — решение с ответственным и, где уместно, со сроком. Если процитировать нечего, это отчёт, а отчёту слайды не нужны.
  4. Каких доказательств не хватает? Назовите каждое число без источника и каждое утверждение, за которым ничего не стоит. «Таких нет» — допустимый ответ, только если вы проверили каждое. Источник, который живёт лишь в заметках докладчика, стоит проговорить вслух: зал их не видит.
  5. Посмотрите на отрендеренные PNG. plank_deck_qa.py растеризует каждый слайд и печатает пути к картинкам; передайте эти пути в plank_look_at (до шести за один вызов) — и вы увидите слайды как изображения. Это единственный способ их увидеть: read на файле картинки возвращает base64, с которым ничего не сделать. Дальше оцените то, чего геометрия не видит: есть ли на слайде одна точка притяжения взгляда или две вещи конкурируют? Одинаково ли выглядят слайды одного типа? Не читается ли что-то как незаконченное — одинокий блок текста, диаграмма без вывода, наполовину пустая карточка? Ничто из этого не измеряется, и всё это видно. Картинки перед показом уменьшаются, поэтому судите о компоновке, контрасте и иерархии, а не о самом мелком шрифте.

Перед тем как передать презентацию

Прежде чем считать презентацию готовой, проверьте её по этому списку:

  • Нигде нет текста-заполнителя — ни «Lorem ipsum», ни «TBD», ни текста в квадратных скобках вроде [заполнить].
  • Соблюдён каждый текстовый лимит выше. DeckError означает, что слайд нужно разделить, а не уменьшить шрифт.
  • На каждом слайде есть заметки докладчика. Конструктор отказывается собирать слайд без них: он проверяет всё до того, как что-либо нарисовать, поэтому отклонённый вызов не добавляет слайд вообще.
  • У каждой диаграммы есть заголовок с выводом и подпись источника.
  • Каждый путь к изображению указывает на реально существующий файл, и каждый слайд с картинкой просмотрен глазами в отрендеренном PNG через plank_look_at — а не выведен из отчёта о геометрии.
  • Если используется логотип, его путь указывает на реально существующий файл.
  • Тема — та, в которой презентация должна быть: studio — чтобы убеждать, report — для всего, что печатают или разбирают по цифрам.
  • У файла описательное, содержательное имя — никогда не deck.pptx.
  • plank_deck_qa.py не находит ошибок, а созданный им PDF передаётся вместе с .pptx. См. Проверка готовой презентации.
  • Пас критики выполнен на финальном файле, и на все пять вопросов суждения даны ответы.

Что нужно сказать пользователю

Передать файлы — это ещё не вся передача работы. В ответе должны быть названы три вещи, и они не перестают быть обязательными оттого, что все замечания оказались предупреждениями:

  1. Что нашла проверка — количество и виды. Если это количество не ноль, то «ошибок рендеринга нет» — нечестное описание запуска, сколько бы из замечаний ни были предупреждениями, а не ошибками.
  2. Что вы исправили — и что после этого заново запустили plank_deck_qa.py.
  3. Что вы осознанно оставили и почему — каждое неисправленное замечание, названное поимённо, с причиной, по которой это допустимо. Молчание — не решение: замечание, о котором никто не сказал, — это замечание, по которому никто не принял решения.

Затем — пять ответов на вопросы суждения из паса критики. Презентация, которую измерили, но не прочитали, не проверена — она отрендерена.