feat(frontend): replace emoji with inline Material Symbols icon system

Add a self-contained icon system: vendored Material Symbols registry, an
<Icon> component that references a single <symbol> sprite via <use>, plus
IconButton/IconSprite. Replace every emoji/Unicode glyph (logo, theme
switcher, cover placeholder, like/comment counts, lightbox controls, back
links) and add leading icons to key controls. Decorative icons are
aria-hidden; icon-only buttons get labels; theme toggles expose
aria-pressed; counters get accessible names.

Recorded in openspec change material-icons-ui (all tasks complete).
This commit is contained in:
iu
2026-10-10 13:19:29 +03:00
parent 84ce4d1930
commit 997ec5e6c1
21 changed files with 582 additions and 69 deletions
@@ -0,0 +1,46 @@
# Proposal
## Why
Сейчас все «иконки» в интерфейсе — это эмодзи и юникод-глифы, которые рисует системный
шрифт. Они по-разному выглядят в разных ОС и браузерах (проект self-hosted — парк
устройств непредсказуем), плохо наследуют цвет темы и семантически неточны: 🌾 для
«нейтральной темы», 💻 для «системной», ♥/💬 для метрик. Нужен единый, самодостаточный
набор векторных иконок без внешних запросов, согласованный с тремя темами и доступностью.
## What Changes
- Ввести inline-SVG иконочную систему: спрайт `<symbol>` + `<use>`, реестр иконок
(`registry.ts`), компоненты `Icon`, `IconSprite`, `IconButton`.
- Заменить все эмодзи/юникод-глифы на SVG-иконки: логотип (`📷`), переключатель тем
(`☀️ 🌙 🌾 💻`), плейсхолдер обложки (`🖼️`), лайк/комментарий (`♥ 💬`), закрытие
и стрелки лайтбокса (`✕ ‹ ›`), «назад» (`←`).
- Добавить ведущие иконки ключевым контролам: создать, загрузить, скачать, сохранить,
отправить, удалить, выйти, участники, настройки, share-ссылки, принять инвайт.
- Источник данных — Google Material Symbols (стиль outlined) плюс `*_fill`-варианты для
состояний (например, лайк нажат/не нажат). Данные иконок вендорятся в репозиторий,
новые зависимости не добавляются.
- Проход по доступности: декоративные иконки скрыты от скринридеров (`aria-hidden`),
смысловые/одиночные получают `aria-label`/`role="img"`, тумблеры тем — `aria-pressed`.
## Capabilities
### New Capabilities
- `ui-iconography`: единая inline-SVG система иконок фронтенда, её доступность и
наследование цветовых токенов тем.
### Modified Capabilities
_Нет — существующие спеки описывают доменную логику (albums, auth, photos, …); иконочная
система их требований не меняет._
## Impact
- **Код:** `frontend/src/lib/icons/*`, `frontend/src/lib/components/Icon.svelte`,
`IconSprite.svelte`, `IconButton.svelte`, правки в `+layout.svelte` и во всех
экранах/компонентах (`ThemeSwitcher`, `PhotoGrid`, `Lightbox`, `Uploader`, `Comments`,
список альбомов, страница альбома, участники, настройки, инвайт, публичный share).
- **Зависимости:** без новых — данные иконок вендорятся.
- **Совместимость:** backend, API и БД не затрагиваются; меняется только фронтенд-разметка
и доступность.