Сайт фастфуда в Чехии: что скил для Claude нашёл по GDPR, ePrivacy, AI Act, Digital Services Act и доступности и почему cookie-баннер не понадобился

Я администрирую сайт hostivicefood.cz. Это киоск быстрого питания в Гостивице под Прагой: бургеры, гриль, борщ и пельмени. WordPress, тема Divi, две страницы: главная и меню. Ни форм, ни корзины, ни личного кабинета. Кажется, что с точки зрения европейского права проверять тут нечего.

Чтобы выяснить, так ли это, я прогнал сайт через свой открытый скил eu-web-compliance для Claude. Ниже — что он нашёл, что оказалось ложной тревогой и что поменялось после исправлений. Это не юридическая консультация, а инженерный разбор.

Скил: пять блоков права ЕС и три правила

Claude Skill — папка с инструкциями и скриптами. Claude подгружает её, когда задача подходит под описание. Мой скил проверяет сайт по пяти блокам права ЕС: GDPR, ePrivacy (cookies), AI Act, Digital Services Act и доступность (WCAG, European Accessibility Act).

Я делал его ради трёх правил:

  • не выдумывать ссылки на законы. Всё, что скил не проверил в текущей сессии, он помечает VERIFY, а сроки и статусы законов проверяет поиском и записывает дату;
  • сначала понять, применяется ли норма. У DSA, EAA и директивы о доступности госсайтов есть пороги, и маленький киоск под них чаще всего не попадает;
  • не трогать сайт без плана и согласия владельца.

В комплекте — чеклисты, шаблоны документов и scan.py: сканер на стандартной библиотеке Python ищет трекеры, сторонние ресурсы, формы и базовые проблемы доступности.

Проверка в пять шагов

  1. Контекст. Кто оператор (ИП, Чехия), что делает сайт, какие данные собирает. Часть скил взял из подвала сайта, на остальное ответил я.
  2. Сканер по сохранённым страницам.
  3. Браузер. Cookies и Set-Cookie, localStorage, все запросы к чужим доменам до любых действий, axe-core, контраст текста на фото, клавиатура на ширине 375 px.
  4. Сервер, только на чтение: WP-CLI, настройки панели хостинга, логи.
  5. Законы. Поиск по статусу Digital Omnibus, EU-US Data Privacy Framework, чешским правилам про cookies и отзывы — с датой проверки.

Что нашлось: шесть проблем

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

Google Fonts грузились с серверов Google при первой загрузке страницы. Это был единственный сторонний хост на сайте, и ради трёх шрифтов IP посетителя уходил третьей стороне. Немецкий суд LG München I в 2022 году признал такое нарушением. Для Чехии это решение не обязательно, но довод понятный: те же шрифты работают и со своего сервера.

Устаревшая ОС сервера. Версия вышла из стандартной поддержки, и обновления безопасности не приходили. По GDPR это вопрос статьи 32 (безопасность обработки). Исправлено.

Мелочи по WordPress: в корне сайта открыто скачивался wordpress-6.1.1.zip на 24 МБ, /?author=1 раскрывал логин администратора, висели два ненастроенных плагина аналитики и попапов.

Цепочка обработчиков. Сайт принадлежит владелице киоска, а сервером занимаюсь я как администратор. Скил сопоставил IP сайта с автономной системой провайдера, выяснил, что это американская компания с дата-центром в ЕС, и задал правильный вопрос: кто кому обработчик. По статье 28 GDPR между нами нужен договор. В коде этого не видно — договор у нас был.

Доступность:

  • запрещён зум на телефоне (user-scalable=0 в viewport, его выводит Divi);
  • белый заголовок и серый подзаголовок прямо на фотографии, без затемнения;
  • кнопки — белый текст на золотом фоне, 2,52:1;
  • кнопка мобильного меню — div, до которой не дойти с клавиатуры, и outline: none на фокусе;
  • иконки Facebook, X и Instagram, ведущие на #.

Отзывы — ложная тревога. На странице меню четыре отзыва с именами. Это потребительское право: в Чехии с 2023 года продавец обязан сообщать, как проверяет подлинность отзывов. Скил вынес это в отдельный раздел «вне охвата» и не стал делать юридических выводов. Отзывы настоящие, так что здесь всё в порядке.

Ни одной cookie. Пусто и в document.cookie, и в заголовках, localStorage тоже пуст. Значит, cookie-баннер не нужен, и скил прямо написал: не добавлять. Баннер «на всякий случай» над пустым местом только мешает посетителю.

AI Act не применяется. ИИ-функций нет, а маркетинговые тексты не относятся к «вопросам общественного интереса» из статьи 50(4). Тексты мы писали сами.

DSA не применяется: комментарии закрыты, пользовательского контента нет.

EAA не применяется: заказ доставки уходит на Foodora, на самом сайте торговли нет, а оператор — микропредприятие. Поэтому доступность здесь рекомендация WCAG, а не юридическая обязанность.

Исправления: шрифты, mu-plugin, логи, политика

После отчёта скил предложил план. Каждый пункт я одобрил отдельно. Перед правками — бэкап базы и wp-content. Файлы я не удалял, а переносил в карантин, недоступный из интернета.

  • Шрифты локально. В Divi выключены Google Fonts. Вариативные woff2 (только latin и latin-ext, 520 КБ) лежат в uploads и подключаются через @font-face.
  • Один mu-plugin на ~100 строк, откат — удалить файл:
    • viewport без запрета зума;
    • затемнение 55% на фото;
    • контрастные цвета кнопок и подвала;
    • видимый фокус;
    • role="button", tabindex и обработка Enter/Space для мобильного меню;
    • 404 для страниц авторов.
  • Уборка: архив WordPress, лишние плагины и старая копия темы — в карантин. Комментарии по умолчанию закрыты.
  • Логи: ротация раз в сутки, 90 файлов.
  • Иконки соцсетей с пустыми ссылками убраны.
  • Политика конфиденциальности на чешском опубликована и открывается из подвала: логи 90 дней, письма 12 месяцев, хостинг и обработчики названы прямо. Новая страница сразу получила от темы две проблемы доступности: бледно-голубые ссылки (2,74:1) и таблицу, которая прокручивается на телефоне без доступа с клавиатуры. Обе я поправил тем же mu-plugin.

До и после: ноль сторонних хостов и ноль нарушений контраста

Шапка на телефоне до исправлений Шапка на телефоне после: затемнение и белый подзаголовок

Блок контактов до: белый текст на золотых кнопках, серый текст оператора Блок контактов после

Мобильное меню открыто с клавиатуры, фокус виден

Состояние «до» на скриншотах я воспроизвёл на живой странице, отключив стили исправлений.

ПроверкаДоПосле
Сторонние хосты при загрузкеfonts.googleapis.com, fonts.gstatic.comнет
Cookiesнетнет
axe-core, главная (правил / узлов)7 / 254 / 5
axe-core, нарушения контраста150
axe-core, меню (правил / узлов)6 / 113 / 3
Зум на телефонезапрещёнразрешён
Мобильное меню с клавиатурынедоступнооткрывается Enter
Заголовок на фото, 375 px, 10-й процентиль контраста1,92 (норма 3:1)7,57
Подзаголовок на фото, 375 px1,39 (норма 4,5:1)5,10
/?author=1раскрывает логин404
Хранение логов20 месяцев90 дней

Четыре ошибки при замерах

axe-core не видит текст на картинках. Контраст заголовка на фото он отправляет в «incomplete», и этот раздел обычно никто не читает. Скил меряет иначе: рисует фото на canvas с тем же background-size и background-position, накладывает затемнение и считает контраст для каждого пикселя под текстом. С нормой сравнивают 10-й процентиль, а не среднее: среднее по тёмной фотографии выглядит прилично, а буквы на светлом пятне не читаются.

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

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

Мелочь, которая съела время. ?w=320 в WordPress — не безобидный параметр для обхода кэша, а номер недели для архива. Страница честно отдала 404.

Дальше: новый сайт вместо доработки старого

Сайт морально устарел, и до конца 2026 года мы переделаем его целиком. Поэтому оставшиеся замечания axe — порядок заголовков и отсутствие <main> в шаблоне темы — я не исправлял: чинить их в старом шаблоне нет смысла. Новую версию я проверю тем же скилом до запуска.

Вывод: браузер и сервер нашли больше, чем чтение кода

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

Скил открытый, лицензия Apache 2.0. Работает в Claude Code и claude.ai. Если проверите свой сайт и найдёте, где он ошибается, — присылайте issue.

Все статьи