openspec: архив change header-typewriter (спека site-header-typewriter в specs/)

This commit is contained in:
2026-09-19 17:48:38 +00:00
parent 2af0530f8a
commit 64fb3a000f
5 changed files with 85 additions and 0 deletions
@@ -0,0 +1,85 @@
# site-header-typewriter Specification
## Purpose
Логотип `dedinit()` в шапке сайта анимирован эффектом печатной машинки:
внутри скобок блочный курсор печатает темы блога, замирает, стирает их и
переходит к следующей — обыгрывая название как вызов функции `dedinit(...)`.
## Requirements
### Requirement: Анимация «печатная машинка» в логотипе
Система SHALL анимировать текст в скобках логотипа `dedinit()` на всех
страницах сайта: блочный курсор печатает слово по одному символу, удерживает
его ~1 секунду, стирает по одному символу, мигает на пустом месте и печатает
следующее слово — бесконечным циклом по списку тем блога.
#### Scenario: Логотип печатает слова по циклу
- **GIVEN** открыта любая страница сайта (`/` или внутренняя), JS включён
- **WHEN** страница загружена
- **THEN** в `dedinit()` между скобками присутствует контейнер
`#dedinit-typewriter` с блочным мигающим курсором, и текст посимвольно
печатается из списка тем (например, `linux` → `llm` → `politics` → ...)
#### Scenario: Цикл без остановки
- **GIVEN** анимация запущена
- **WHEN** прошло более 3 слов печати/стирания
- **THEN** анимация продолжает цикл (после последнего слова переходит к
первому), не останавливаясь и не накапливая ошибок
### Requirement: Бесшовный вывод (прогрессивное улучшение)
Система SHALL оставаться декоративным улучшением: при выключенном JS логотип
остаётся обычным текстом `dedinit()`; при его включении — анимация
накладывается, не ломая вёрстку и навигацию шапки.
#### Scenario: JS отключён — логотип статичен
- **GIVEN** браузер с отключённым JavaScript
- **WHEN** страница загружена
- **THEN** в шапке отображается обычный текст `dedinit()` без скобочного
контейнера и без ошибок
### Requirement: Доступность (prefers-reduced-motion)
Система SHALL уважать системную настройку `prefers-reduced-motion: reduce`:
при ней показывать первое слово списка статически, без анимации и мигания.
#### Scenario: Уменьшение движения
- **GIVEN** у пользователя включено `prefers-reduced-motion: reduce`
- **WHEN** страница загружена
- **THEN** внутри скобок логотипа отображается первое слово списка статично,
курсор не мигает (CSS `animation: none`), JS-цикл не запускается
### Requirement: Минимальный размер и отсутствие зависимостей
Система SHALL реализовывать эффект без внешних зависимостей (без Alpine.js,
без jQuery): инлайн-скрипт и CSS суммарно не более ~2 КБ.
#### Scenario: Нет внешних библиотек
- **GIVEN** собранный сайт
- **WHEN** просматривается HTML страницы
- **THEN** в `<head>`/футере не подключено никаких сторонних JS-библиотек для
эффекта (только собственный инлайн-скрипт и CSS темы)
### Requirement: Список тем конфигурируется
Система SHALL позволять задавать список тем через `hugo.toml`
(`[params.typewriter] words = [...]`), со встроенным фолбэком по умолчанию
(`linux, llm, politics, homelab, nix`) при его отсутствии.
#### Scenario: Слова из конфига
- **GIVEN** в `hugo.toml` задан `[params.typewriter] words = ["linux","llm","politics"]`
- **WHEN** страница собрана и открыта
- **THEN** анимация печатает именно эти слова, в заданном порядке
#### Scenario: Конфиг не задан
- **GIVEN** в `hugo.toml` нет `[params.typewriter]`
- **WHEN** страница собрана и открыта
- **THEN** используется фолбэк-список по умолчанию, анимация работает