Sync EventHubFrontSpec and UI-PARITY with mark-only logo + icon-only chip on mobile. Refs EventHub/EventHubFront#45
20 KiB
UI parity: EventHubFront ↔ CalenTIQ board
План визуального выравнивания клиентского фронта с утверждённым бордом.
SoT: boards/calentiq-ui-board-final.png.
Эпик: EventHubSpec#10.
Статус: workstreams 1–5 закрыты в коде Front (Refs Front#25–#29). Stage smoke на https://stage.calentiq.com — done (UI 0.2.29 / 79dadfb21f98, API 0.2.158).
Known deviations from board (Front#29)
Зафиксировано осознанно / пока не делаем (после visual pass ×3 moods + stage):
| Зона | Борд | Сейчас |
|---|---|---|
| Pixel-perfect calendar | denser board mock + Today/Upcoming rail | Agenda rail (§B): title-case Сегодня/Предстоящие + count, time-first rows; month chips/cell wash (§B/D) по mood; не 1:1 Figma |
| Discover cards | soft cards + media thumb + CTA | mood media plane (wash/initials + image_url when present) + soft-card rhythm + CTA; без full photo-hero grid |
| CONTROL booking §E | отдельные mock-карточки «слот/специалист» | EventActionCard / specialists / bookings: steel rail (усилен), avatar, available label, Confirm/Decline; не pixel-perfect board mocks |
| Bookings list §D | список заявок с Confirm/Decline на /bookings |
/bookings = grouped inbox: (A) К подтверждению — pending owner/specialist + Confirm/Decline; (B) Мои записи — participant upcoming/past + Cancel; empty groups hidden. Event card Confirm/Decline остаётся обязательным |
| Login §D phone chrome | три phone frames + (на борде) Google CTA | brand-first hero + mood --auth-*; email/password only; compact mood на auth; taglines — в mood sheet AppShell (не в /more); без Google OAuth |
| Mood placement | board §C switcher cards | Front#40/#45: mood chip в AppShell рядом с BrandWordmark (+ compact auth); mobile icon-only chip + mark-only logo; не в /more, не в toolbar Month/Week/Day; 3 moods, без flip / CREATOR |
| Lens + strip | board Today/Upcoming rail only | Front#39 + controls IA: lens Обзор/На сегодня/Заявки в шапке strip (underline tabs / mobile sheet); view Месяц/Неделя/День рядом с периодом; owner schedule actions отдельным рядом; localStorage only; soft-default по mood |
| Week view headers | — | Front#40: одна строка day-headers (без дубля WeekDayColumn); scroll .eh-cal-week-scroll (mobile ~390) |
| Favicon set | 3 отдельных favicon файла на борде | mood appicon через applyMood |
| Desktop nav | phone bottom tabs на борде | desktop: одна строка chrome — logo + mood | nav (Календарь / Найти / Записи / Ещё) | nickname + logout; bottom nav — mobile |
| Header identity | — | nickname primary (не raw email); email только в title tooltip |
| Bookings past/expired | — | expired бейдж + Cancel скрыт; empty-state с CTA Discover / календари; soft list time |
| Agenda empty copy | — | personal «Нет событий»; commercial «Нет слотов» |
| More invites | пункт меню | скрыт при pending=0; badge счётчика при pending > 0 |
| D9 guest specialist schedule | — | модель B (Front#35): roster карточек → тап → фильтр слотов по event.specialist_id; «Все слоты студии»; book без specialist в body; не chip-filter |
| Confirmed на personal | — | Front-only overlay confirmed чужих commercial на default personal; title событие · студия · спец; клик → /c/:foreignCalId/e/:eventId |
| SpecialistsPanel density | — | mobile: имя/теги сверху, actions снизу full-width (Front#33/#35) |
| Stage | полный smoke на stage | done 2026-07-27: Login×3 / Calendar×3 + agenda / Discover / CONTROL commercial + Confirm·Decline / More moods |
| Домены calentiq.* | — | публичный stage: stage.calentiq.com / admin.stage.calentiq.com (канон STAGE-BROWSER.md) |
IA без sidebar / без Creator mood — совпадает с non-goals (проверено на stage).
Visual pass ×3 moods (local + stage)
Checked (vite preview + Playwright shots + stage HTTPS): Login §D, Calendar grid+agenda, Discover media, CONTROL slot/bookings (Confirm/Decline на event card), More mood cards — FLOW / MOMENTUM / CONTROL.
Polish in this pass: agenda copy/casing/counts + time-first rows; CONTROL steel rail emphasis; neutral Discover cover in mock (не flow-appicon во всех moods).
Front#31 (2026-07-27): desktop one-row chrome (logo|nav|logout); header nickname; bookings expired + soft list time + empty CTA; agenda personal vs commercial empty copy; Discover cover photo/fallback; More invites badge.
Front#35 (2026-07-28, SHA 57cfcf3): D9 модель B (guest roster → schedule filter); confirmed foreign overlay на personal; SpecialistsPanel mobile density; F6 EventActionCard past+pending → expired / no Cancel, Book скрыт на past.
Front#39 (2026-07-28, SHA c2cb754 / d38a927): Mood chip убран из Ещё; Lens Обзор/Сегодня/Записи + strip над сеткой во всех 3 moods; mobile sheets + strip collapsed; mood→DB, lens→localStorage; без flip / CREATOR. (Placement chip уточнён в Front#40.) Controls IA (2026-07-29): lens перенесён в шапку strip (labels: Обзор / На сегодня / Заявки); view рядом с периодом; owner schedule actions отдельным рядом.
Front#40 (2026-07-28, SHA mood 7c092d1 / week db11c41): Mood chip в AppShell рядом с BrandWordmark (не в calendar toolbar Month/Week/Day); 3 moods; PATCH preferences.mood; без дубля в Ещё. Week view: одна строка day-headers + .eh-cal-week-scroll для mobile ~390.
Front#45 (2026-07-29): Mobile mood chrome — chip icon-only (без truncate label) + BrandWordmark mark-only; sm+ полный label + wordmark; sheet без изменений; aria-label на chip.
Remaining intentional: no pixel-perfect phone chrome; Discover без photo-hero grid (cover via image_url when API returns it; broken URL → wash+initials); §E specialist schedule card vs panel — не pixel-perfect board mocks (follow-up). Product flow D9 B — documented; board pixel mock — Future.
Bookings inbox + More invites (locked 2026-07-27)
Продуктовые решения (не deviation — канон):
- Event card Confirm/Decline остаётся обязательным (quick approve на слоте).
/bookings— grouped inbox, не только participant:- Группа A — К подтверждению: pending bookings, где пользователь calendar owner или assigned specialist (
event.specialist_id= user). Confirm/Decline те же, что наEventActionCard. - Группа B — Мои записи: participant bookings (upcoming/past + Cancel) как раньше.
- Пустые группы скрывать (
count=0). - Опционально подпись owner vs specialist внутри A; иначе одна секция «К подтверждению».
- Группа A — К подтверждению: pending bookings, где пользователь calendar owner или assigned specialist (
specialist_inviteв More: скрывать пункт меню, если 0 pending входящих; при pending > 0 — badge со счётчиком. Deep-link/invites?token=работает. Исходящие invite остаются вSpecialistsPanel.- Не класть строки
specialist_inviteв/bookings. - Past-pending /
expired: Back#60 помечает past-pending →expiredи исключает изbooking-requests; Confirm/Decline →409. UI: бейдж «истекла», Cancel скрыт (Bookings + EventActionCard); defensive map past+pending → expired badge. Front#35 F6: на past Book скрыт; past+pending на карточке → expired label.
API: GET /v1/user/booking-requests (Back) + существующий PUT /v1/bookings/:id
(409 на expired / full).
Guest specialist schedule + confirmed overlay (locked Front#35)
- D9 модель B (guest на commercial): roster активных специалистов (карточки) →
тап → сетка только со слотами выбранного
event.specialist_id; CTA «Все слоты студии» сбрасывает фильтр. Не chip-filter на shared grid. Book body без specialist. OwnerSpecialistsPanel(invite/CRUD) не менять этим флоу. - Confirmed на personal (Front-only):
GET /v1/user/bookings(confirmed) + догрузка events/calendars → overlay на default personal grid; titleevent · studio · specialist; клик →/c/:foreignCalId/e/:eventId. Back без изменений. - SpecialistsPanel density (mobile): имя/теги сверху, actions снизу full-width.
Mood + Lens (locked Front#39 / placement Front#40)
- Mood = визуальная атмосфера (
html[data-mood], FLOW/MOMENTUM/CONTROL). Primary UX — chip → sheet в AppShell рядом с BrandWordmark (Front#40); compact на auth. Нет в/more; не в toolbar Month/Week/Day. Persist:preferences.moodчерезPATCH /v1/user/me. Без flip; без CREATOR. Front#45: mobile chip icon-only + mark-only logo; desktop — полный label/wordmark; sheet — icon + label + tagline. - Lens = отдельный контентный режим (
overview/today/bookings), не mood и не view month/week/day. UI: Обзор / На сегодня / Заявки. Переключатель — в шапке strip (underline/text tabs на desktop; chip → sheet на mobile), не рядом с ViewMode. Soft-default при смене mood, если lens не pinned: FLOW→overview, MOMENTUM→today, CONTROL→bookings. - Strip над сеткой (не на HTML-архиве месяца): Front-only derive — free gaps / события сегодня / upcoming bookings. Desktop раскрыт по умолчанию; mobile свёрнут (tap раскрывает). Сетка всегда видна. Workspace toolbar: контекст (селектор) / виджет (период + view) / owner schedule actions (отдельный ряд).
- Persistence: mood → DB; language →
user.language; lens →localStorage(eh.calendar.lens+ pinned). Без нового Back API. - Week view (Front#40): одна строка day-headers (без дубля
WeekDayColumn); горизонтальный скролл.eh-cal-week-scroll(mobile ~390).
Follow-ups (вне этого fix-pass или частично)
| Тема | Статус |
|---|---|
Discover image_url в search serialization |
Back отдаёт поле; upload API нет — только URL field / seed; Front#31: photo vs fallback media classes + onError fallback |
| Stage Popular clutter (e2e calendars) | filter notes: см. EventHubSpec/STAGE-POPULAR-CLEANUP.md; не трогать реальные smoke данные без фильтра по e2e-паттернам |
| §E specialist schedule card vs panel | deviation: EventActionCard + SpecialistsPanel; pixel mock — Future; product D9 B — done Front#35 |
| Desktop one-row chrome | done Front#31; mood chip у logo — Front#40 (7c092d1) |
| D9 B + confirmed personal overlay | done Front#35 (57cfcf3) |
| Mood chip + Lens strip | done Front#39 (c2cb754 / d38a927); chip → AppShell Front#40; mobile icon-only Front#45 |
| Week view single header + scroll | done Front#40 (db11c41) |
Mood concept = product surface
Mood — не переименование calm|energetic|business и не смена primary hex.
Каждый mood — отдельная атмосфера продукта при той же IA:
| Mood | Ощущение | Chrome / surfaces | Discover / booking feel |
|---|---|---|---|
FLOW (calm) |
спокойствие, баланс | soft sage panels, light wash, soft chips | мягкие карточки, спокойный CTA |
MOMENTUM (energetic) |
энергия, скорость | ink #111820, coral #FF6A3D, denser chips |
тёмный discover, яркий CTA |
CONTROL (business) |
бизнес, доступность | steel #324A5F, cool neutrals |
коммерческие карточки слот/специалист/CTA |
Референс на борде: секции B Mood Overview, C Mood Switcher, D Core Screens, NEW Discover, E Booking / Commercial.
Switcher — branded cards (иконка + короткий tagline), не plain list/tabs:
- FLOW — Find balance
- MOMENTUM — Get more done
- CONTROL — Grow the business
Опционально: mood-aware favicon из boards/calentiq-icon-system-final.png / mood-icons/.
Токены сейчас узкие (tokens/colors.json); для parity нужны surfaces, gradients, chip/event styles, chrome — не только primary.
Workstreams (mood-first)
Порядок важен: сначала атмосфера и токены, затем экраны поверх них.
1. Mood system / atmosphere — P0 / first ✅
CSS-токены и chrome на mood beyond primary hex: surfaces, gradients, event chip styles; switcher как branded cards (icon + tagline); опционально mood favicon.
Acceptance
- Per-mood token set: surface / wash / chip / border / CTA (не только primary)
- Mood switcher = 3 branded cards с иконкой и tagline с борда
- Смена mood меняет атмосферу chrome (не только accent button)
- API keys остаются
calm|energetic|business - Опционально: favicon следует активному mood
Design: board §B, §C, §F; mood-icons/; tokens/
Done: EventHubFront#25 — index.css mood tokens + MoodSwitcher cards + favicon via applyMood.
2. Calendar mood-chrome — P0 ✅
Та же сетка/IA; soft panels (FLOW), denser chips (MOMENTUM), mood-tinted cells (CONTROL) — как на борде §B / §D Calendar.
Acceptance
- Month/week выглядят различно по mood при той же навигации
- Event chips / cells тонированы mood-токенами
- Нет sidebar / смены layout ради «красоты»
Design: board §B Mood Overview, §D Calendar
Done: EventHubFront#26 — --cal-* tokens + .eh-cal / .eh-chip в CalendarWidget; IA без изменений.
Follow-up: month grid §B/D — FLOW sage cell wash + chip limit 2; MOMENTUM denser/hotter chips limit 5; CONTROL steel cells + sharper chips limit 3; split time/title chips.
3. Discover mood variants — P1 ✅
Визуальная дифференциация FLOW vs MOMENTUM vs CONTROL: soft cards + CTA; соответствие борду (NEW Discover / §D Discover), не as-is скринам.
Acceptance
- Discover в трёх moods визуально различим (фон, карточки, CTA)
- Soft card + CTA pattern с борда (не плоский as-is list-only)
- IA и фильтры без смены модели; только presentation
Design: board NEW Discover, §D Discover; as-is refs: eventhub-discover-{flow,momentum,control}.png
Done: EventHubFront#27 — --disc-* + .eh-discover-card / .eh-discover-cta; list → card grid.
Follow-up: media hierarchy — .eh-discover-media with per-mood size/radius/washes (FLOW air / MOMENTUM energy / CONTROL steel), optional cover via image_url, display title + soft-card rhythm.
4. CONTROL booking surfaces — P1 ✅
Коммерческие карточки: слот, специалист, CTA — только Control-specific (§E).
Acceptance
- Slot card + specialist card + primary CTA в CONTROL
- Specialists остаются внутри Control (не 4-й mood)
- FLOW/MOMENTUM не получают Control commercial chrome
Design: board §E Booking / Commercial
Done: EventHubFront#28 — .eh-book-slot / .eh-book-specialist / .eh-book-request; steel chrome только под data-mood=business.
Follow-up: §E polish — --book-* tokens; CONTROL steel left-rail + sharper radii; slot duration/available label; specialist/request avatars; mood-token CTA/Decline.
5. Polish + stage smoke — P2 ✅
Мелкие расхождения с бордом, wordmark/lockup consistency, stage smoke трёх moods.
Acceptance
- Mock smoke: calendar → discover → bookings в 3 moods (+ IA без sidebar)
- Нет регрессий IA (top + bottom nav) — покрыто mock e2e
- Известные отклонения от борда зафиксированы в UI-PARITY (Known deviations)
- Visual pass ×3 moods (local preview / Playwright shots) — Login / Calendar / Discover / CONTROL booking
- Stage smoke на живом стенде — UI
0.2.29(79dadfb21f98) @https://stage.calentiq.com(2026-07-27)
Done: EventHubFront#29 — e2e/tests/mood-parity-smoke.spec.ts, brand meta, CONTROL tagline polish.
Follow-up: visual pass polish — agenda Предстоящие + counts/time-first; CONTROL steel rail; mock Discover cover neutral. Stage: seed commercial + slots + pending booking для §E Confirm/Decline.
Non-goals
- Left sidebar / смена IA
- 4-й Creator mood / AI-assistant home
- Rename API keys (
calm|energetic|businessостаются) - Покупка доменов / DNS cutover
- Админский UI (
design/admin/) — не трогать Front-бордами - Полный pixel-perfect каждого пикселя борда (направление + mood atmosphere)
Mapping → issues
| # | Workstream | Issue |
|---|---|---|
| — | Story (родитель) | Spec#11 |
| 1 | Mood system / atmosphere | Front#25 |
| 2 | Calendar mood-chrome | Front#26 |
| 3 | Discover mood variants | Front#27 |
| 4 | CONTROL booking surfaces | Front#28 |
| 5 | Polish + stage smoke | Front#29 |
| — | P1/P2 UX polish + expired + desktop chrome | Front#31 |
| — | Past-pending → expired |
Back#60 |
| — | P2: D9 B + confirmed personal + density/F6 | Front#35 |
| — | Mood chip + Lens strip (workspace) | Front#39 |
| — | Mood chip → AppShell + week scroll | Front#40 |
| — | Mood chip icon-only mobile + mark-only logo | Front#45 |
Эпик: Spec#10.
Suggested start
Кодить с Task 1 (Mood system / atmosphere): без токенов и switcher-as-cards остальные экраны будут «перекраской primary», а не mood product surface.