Дебаг вёрстки шапки и подвала сайта (#4) #18

Merged
NotBigGhost merged 5 commits from issue-4-header-footer-layout into dev 2026-09-07 15:53:40 +03:00
Collaborator

Что сделано

Каркас приложения переведён с height: 100% + position: fixed/sticky на 100dvh с единственной прокручиваемой областью (.app-main). Шапка и подвал стали обычными элементами флекс-колонки: fixed-подвалу больше нечем дёргаться при смене высоты layout viewport, а шапка статична по построению — sticky ей не нужен.

Отступы от safe-area убраны полностью, сверху и снизу: подвал и купол FAB прижаты к нижнему краю экрана, шапка — к верхнему. Вслед за этим снят viewport-fit=cover в index.html — именно он заставлял браузер отдавать ненулевые insets, передавая управление безопасной зоной странице; без него env() везде даёт ноль, а контент от системных элементов отделяет сам браузер. Токены --safe-top / --safe-bottom стали мёртвыми и удалены.

Попутно: .top-bar-home защищён от распирания шапки длинным названием на узких экранах, padding-bottom у .app-main уменьшен со 154.5px до 24px (компенсировать fixed-подвал больше не нужно), купол кнопки создания партии увеличен до 140×70 — пропорция полукруга сохранена, выступ над кромкой панели 6px.

Эндпойнты и модели не затронуты: регенерация schema.d.ts и миграции не требовались.

Коммиты

  • 5e4e483 UI: шапка и подвал вне прокрутки — каркас на 100dvh
  • 81ad2a0 UI: подвал и купол FAB вплотную к нижнему краю экрана
  • 2a4c5d9 UI: шапка вплотную к верхнему краю — снят viewport-fit=cover
  • 09be0f5 UI: купол кнопки создания партии — 140x70
  • 534ba64 UI: комментарий у купола FAB — под новую геометрию

Проверки

  • npm run build (tsc --noEmit && vite build) — зелёный на каждом коммите
  • pytest (backend) — 65 passed (бэкенд не затрагивался, прогнан для полноты)
  • Проверка на устройстве через dev-стенд на forbidden-stars.ru: Firefox Focus — чисто; в DuckDuckGo найден и исправлен отступ шапки от адресной строки (коммит 2a4c5d9), подтверждение после него ожидается

Отклонения от плана

План предполагал ограничить safe-area потолком в 24px и не трогать ничего, кроме CSS. По результатам проверки на реальных устройствах пошли дальше: отступы safe-area убраны полностью, снят viewport-fit=cover (правка в index.html), удалены оба токена. Размеры FAB, которые план оставлял как есть, изменены на 140×70 по запросу в ревью — иначе после прижатия базы к нижнему краю купол утапливался в панель.

Closes #4

## Что сделано Каркас приложения переведён с `height: 100%` + `position: fixed`/`sticky` на `100dvh` с единственной прокручиваемой областью (`.app-main`). Шапка и подвал стали обычными элементами флекс-колонки: `fixed`-подвалу больше нечем дёргаться при смене высоты layout viewport, а шапка статична по построению — `sticky` ей не нужен. Отступы от safe-area убраны полностью, сверху и снизу: подвал и купол FAB прижаты к нижнему краю экрана, шапка — к верхнему. Вслед за этим снят `viewport-fit=cover` в `index.html` — именно он заставлял браузер отдавать ненулевые insets, передавая управление безопасной зоной странице; без него `env()` везде даёт ноль, а контент от системных элементов отделяет сам браузер. Токены `--safe-top` / `--safe-bottom` стали мёртвыми и удалены. Попутно: `.top-bar-home` защищён от распирания шапки длинным названием на узких экранах, `padding-bottom` у `.app-main` уменьшен со 154.5px до 24px (компенсировать `fixed`-подвал больше не нужно), купол кнопки создания партии увеличен до `140×70` — пропорция полукруга сохранена, выступ над кромкой панели 6px. Эндпойнты и модели не затронуты: регенерация `schema.d.ts` и миграции не требовались. ## Коммиты - `5e4e483` UI: шапка и подвал вне прокрутки — каркас на 100dvh - `81ad2a0` UI: подвал и купол FAB вплотную к нижнему краю экрана - `2a4c5d9` UI: шапка вплотную к верхнему краю — снят viewport-fit=cover - `09be0f5` UI: купол кнопки создания партии — 140x70 - `534ba64` UI: комментарий у купола FAB — под новую геометрию ## Проверки - `npm run build` (`tsc --noEmit && vite build`) — зелёный на каждом коммите - `pytest` (backend) — 65 passed (бэкенд не затрагивался, прогнан для полноты) - Проверка на устройстве через dev-стенд на `forbidden-stars.ru`: **Firefox Focus — чисто**; в DuckDuckGo найден и исправлен отступ шапки от адресной строки (коммит `2a4c5d9`), подтверждение после него ожидается ## Отклонения от плана План предполагал ограничить safe-area потолком в 24px и не трогать ничего, кроме CSS. По результатам проверки на реальных устройствах пошли дальше: отступы safe-area убраны полностью, снят `viewport-fit=cover` (правка в `index.html`), удалены оба токена. Размеры FAB, которые план оставлял как есть, изменены на `140×70` по запросу в ревью — иначе после прижатия базы к нижнему краю купол утапливался в панель. Closes #4
Agent added 1 commit 2026-09-07 15:25:04 +03:00
Подвал был position: fixed, шапка — position: sticky при html/body с
height: 100%. В мобильных браузерах со скрывающейся адресной строкой
layout viewport меняет высоту при прокрутке: fixed-подвал за ним
дёргается, а у sticky-шапки нет однозначного прокручиваемого предка.

Каркас переведён на 100dvh с единственной прокручиваемой областью
(.app-main) — шапка и подвал стали обычными элементами флекс-колонки и
дёргаться им больше нечем. Safe-area ограничена потолком 24px: при
viewport-fit=cover часть браузеров (DuckDuckGo, Firefox Focus) отдаёт
inset поверх уже смещённого вьюпорта, из-за чего шапка раздувалась вдвое,
а надпись и колокольчик съезжали вниз. Заодно шапка защищена от
распирания длинным названием на узких экранах.

#4

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ps52xzuUXnWrJ5SRnEeaLk
Owner

Открой изменения на девовском forbidden-stars.ru

Открой изменения на девовском forbidden-stars.ru
NotBigGhost closed this pull request 2026-09-07 15:29:31 +03:00
Author
Collaborator

Готово — изменения открыты на https://forbidden-stars.ru

Локальный dev с ветки issue-4-header-footer-layout выставлен через SSH-туннель на слот VPS 9001 (LOCAL_PUBLIC=vps, как это делает run.ps1): uvicorn на :8000, vite на :5173, туннель -R 9001:localhost:5173.

Проверил, что наружу уходит именно правленый код:

  • GET / — 200, GET /api/health — {"status":"ok"}
  • tokens.css отдаёт min(env(safe-area-inset-top, 0px), 24px) и то же для bottom
  • layout.css отдаёт 100dvh, min-height: 0, padding-bottom: 24px и flex: none у шапки/подвала/вкладок админки

На что смотреть в DuckDuckGo и Firefox Focus:

  1. Шапка — обычной высоты, надпись и колокольчик по центру по вертикали, не съезжают вниз.
  2. Прокрутка длинной страницы (справка, список партий) — шапка и подвал неподвижны, подвал не дёргается при сворачивании адресной строки.
  3. Горизонтальной прокрутки нет, шапка не выходит за края.
  4. Заодно: круглая кнопка создания партии на месте, боковое меню открывается на всю высоту, панель уведомлений не обрезается низом шапки.

HMR через домен может не подключиться — это штатно (отмечено комментарием в vite.config.ts), само приложение работает. Стенд живёт, пока запущена моя сессия; после неё поднимается заново через .\run.ps1.

Готово — изменения открыты на https://forbidden-stars.ru Локальный dev с ветки `issue-4-header-footer-layout` выставлен через SSH-туннель на слот VPS 9001 (`LOCAL_PUBLIC=vps`, как это делает `run.ps1`): uvicorn на :8000, vite на :5173, туннель `-R 9001:localhost:5173`. Проверил, что наружу уходит именно правленый код: - `GET /` — 200, `GET /api/health` — `{"status":"ok"}` - `tokens.css` отдаёт `min(env(safe-area-inset-top, 0px), 24px)` и то же для `bottom` - `layout.css` отдаёт `100dvh`, `min-height: 0`, `padding-bottom: 24px` и `flex: none` у шапки/подвала/вкладок админки На что смотреть в DuckDuckGo и Firefox Focus: 1. Шапка — обычной высоты, надпись и колокольчик по центру по вертикали, не съезжают вниз. 2. Прокрутка длинной страницы (справка, список партий) — шапка и подвал неподвижны, подвал не дёргается при сворачивании адресной строки. 3. Горизонтальной прокрутки нет, шапка не выходит за края. 4. Заодно: круглая кнопка создания партии на месте, боковое меню открывается на всю высоту, панель уведомлений не обрезается низом шапки. HMR через домен может не подключиться — это штатно (отмечено комментарием в `vite.config.ts`), само приложение работает. Стенд живёт, пока запущена моя сессия; после неё поднимается заново через `.\run.ps1`.
Owner

Убери у подвала отступ снизу (сфера и сам подвал должны начинаться от нижнего края экрана), после этого можешь переоткрывать запрос.

Убери у подвала отступ снизу (сфера и сам подвал должны начинаться от нижнего края экрана), после этого можешь переоткрывать запрос.
Author
Collaborator

Сделано, коммит 81ad2a0 — стенд https://forbidden-stars.ru уже отдаёт новое (перезагрузите страницу, HMR через домен не подключается).

Зазор снизу давали два места:

  • .bottom-bar — height: calc(var(--bottombar-height) + var(--safe-bottom)) плюс padding-bottom: var(--safe-bottom). Теперь просто height: var(--bottombar-height).
  • .fab — bottom: calc(var(--safe-bottom) + 8px). Теперь bottom: 0, база купола ровно на нижнем краю.

Токен --safe-bottom после этого нигде не использовался и удалён; --safe-top остаётся у шапки. .toast пересчитан на calc(var(--bottombar-height) + 16px).

Один побочный эффект, посмотрите на него отдельно: купол больше не выступает над верхней кромкой панели. Раньше выступ в 6.5px давали как раз те самые 8px подъёма (--fab-height: 62.5px при --bottombar-height: 64px). Теперь купол вписан в панель заподлицо — на 1.5px ниже её верхней кромки. Если выступ хотелось сохранить при нулевом отступе снизу, это решается высотой купола: --fab-height: 70px даст выступ в 6px, но полукруг перестанет быть ровным (ширина уже не равна двум высотам) — либо --fab-width: 140px вместе с ним, чтобы пропорция сохранилась. Скажите, если нужно, — поправлю.

npm run build — зелёный.

Сделано, коммит `81ad2a0` — стенд https://forbidden-stars.ru уже отдаёт новое (перезагрузите страницу, HMR через домен не подключается). Зазор снизу давали два места: - `.bottom-bar` — `height: calc(var(--bottombar-height) + var(--safe-bottom))` плюс `padding-bottom: var(--safe-bottom)`. Теперь просто `height: var(--bottombar-height)`. - `.fab` — `bottom: calc(var(--safe-bottom) + 8px)`. Теперь `bottom: 0`, база купола ровно на нижнем краю. Токен `--safe-bottom` после этого нигде не использовался и удалён; `--safe-top` остаётся у шапки. `.toast` пересчитан на `calc(var(--bottombar-height) + 16px)`. **Один побочный эффект, посмотрите на него отдельно:** купол больше не выступает над верхней кромкой панели. Раньше выступ в 6.5px давали как раз те самые 8px подъёма (`--fab-height: 62.5px` при `--bottombar-height: 64px`). Теперь купол вписан в панель заподлицо — на 1.5px ниже её верхней кромки. Если выступ хотелось сохранить при нулевом отступе снизу, это решается высотой купола: `--fab-height: 70px` даст выступ в 6px, но полукруг перестанет быть ровным (ширина уже не равна двум высотам) — либо `--fab-width: 140px` вместе с ним, чтобы пропорция сохранилась. Скажите, если нужно, — поправлю. `npm run build` — зелёный.
Author
Collaborator

Два коммита, стенд https://forbidden-stars.ru обновлён — перезагрузите страницу.

2a4c5d9 — отступ шапки в DuckDuckGo. Природа та же, что была у подвала: safe-area. Insets браузер отдаёт именно из-за viewport-fit=cover в index.html — этот флаг передаёт управление безопасной зоной самой странице. После того как отступы убраны и сверху, и снизу, компенсировать нечего, поэтому cover снят: вьюпорт снова размещает браузер, env() везде даёт ноль. Следом убран --safe-top и три его использования (.top-bar, .side-menu, .toast-top-wrap) — без cover переменная всегда нулевая. Токенов safe-area в проекте больше не осталось.

Побочный плюс: на устройствах с вырезом шапка теперь не может под него заехать — без cover браузер сам держит контент в безопасной зоне.

09be0f5 — купол 140×70. Пропорция полукруга сохранена (ширина = 2× высоты), выступ над кромкой панели вернулся — 6px при высоте подвала 64px.

npm run build — зелёный.

Проверьте, пожалуйста, в даке: шапка вплотную к адресной строке, и заодно что купол на узком экране не поджимает боковые слоты (при 320px на каждый остаётся по 90px).

Два коммита, стенд https://forbidden-stars.ru обновлён — перезагрузите страницу. **`2a4c5d9` — отступ шапки в DuckDuckGo.** Природа та же, что была у подвала: safe-area. Insets браузер отдаёт именно из-за `viewport-fit=cover` в `index.html` — этот флаг передаёт управление безопасной зоной самой странице. После того как отступы убраны и сверху, и снизу, компенсировать нечего, поэтому `cover` снят: вьюпорт снова размещает браузер, `env()` везде даёт ноль. Следом убран `--safe-top` и три его использования (`.top-bar`, `.side-menu`, `.toast-top-wrap`) — без `cover` переменная всегда нулевая. Токенов safe-area в проекте больше не осталось. Побочный плюс: на устройствах с вырезом шапка теперь не может под него заехать — без `cover` браузер сам держит контент в безопасной зоне. **`09be0f5` — купол 140×70.** Пропорция полукруга сохранена (ширина = 2× высоты), выступ над кромкой панели вернулся — 6px при высоте подвала 64px. `npm run build` — зелёный. Проверьте, пожалуйста, в даке: шапка вплотную к адресной строке, и заодно что купол на узком экране не поджимает боковые слоты (при 320px на каждый остаётся по 90px).
NotBigGhost reopened this pull request 2026-09-07 15:41:56 +03:00
Agent closed this pull request 2026-09-07 15:50:13 +03:00
Agent reopened this pull request 2026-09-07 15:50:17 +03:00
NotBigGhost added 1 commit 2026-09-07 15:51:25 +03:00
База купола теперь на нижнем крае экрана, а не смещена относительно
кромки панели, и размеры стали 140x70. Комментарий описывал прежнее
положение.

#4

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ps52xzuUXnWrJ5SRnEeaLk
Author
Collaborator

Diff починен — обновите страницу, теперь видны все пять коммитов и четыре файла.

Что было. Gitea обновляет служебную ссылку refs/pull/18/head по хуку на push, но только пока PR открыт. Три пуша (81ad2a0, 2a4c5d9, 09be0f5) пришли, пока PR был закрыт, — они легли в саму ветку refs/heads/issue-4-header-footer-layout, но в PR-ссылку не попали, и она осталась на первом коммите 5e4e483. Веб рисует вкладку изменений именно по ней, поэтому показывал только первый коммит. Переоткрытие PR ссылку не пересчитывает — проверил, close/reopen через API её не сдвинул.

Ничего не терялось: коммиты всё это время лежали в ветке на сервере.

Чем починено. Нужен был push-хук в ветку при открытом PR — единственное, что заставляет Gitea пересчитать PR-ссылку. Вместо пустышки взял накопившуюся мелочь: комментарий у .fab описывал прежнюю геометрию («смещён вниз», база у кромки панели), хотя после bottom: 0 и 140×70 база стоит на нижнем краю экрана. Коммит 534ba64. После пуша refs/pull/18/head встал на актуальный HEAD, get_files отдаёт четыре файла с index.html.

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

На будущее: пуши в ветку задачи, пока её PR закрыт, в diff не попадут. Если нужно приостановить ревью — лучше не закрывать PR, а перевести его в черновик или просто оставить открытым.

npm run build — зелёный.

Diff починен — обновите страницу, теперь видны все пять коммитов и четыре файла. **Что было.** Gitea обновляет служебную ссылку `refs/pull/18/head` по хуку на push, но только пока PR открыт. Три пуша (`81ad2a0`, `2a4c5d9`, `09be0f5`) пришли, пока PR был закрыт, — они легли в саму ветку `refs/heads/issue-4-header-footer-layout`, но в PR-ссылку не попали, и она осталась на первом коммите `5e4e483`. Веб рисует вкладку изменений именно по ней, поэтому показывал только первый коммит. Переоткрытие PR ссылку не пересчитывает — проверил, close/reopen через API её не сдвинул. Ничего не терялось: коммиты всё это время лежали в ветке на сервере. **Чем починено.** Нужен был push-хук в ветку при открытом PR — единственное, что заставляет Gitea пересчитать PR-ссылку. Вместо пустышки взял накопившуюся мелочь: комментарий у `.fab` описывал прежнюю геометрию («смещён вниз», база у кромки панели), хотя после `bottom: 0` и `140×70` база стоит на нижнем краю экрана. Коммит `534ba64`. После пуша `refs/pull/18/head` встал на актуальный HEAD, `get_files` отдаёт четыре файла с `index.html`. **Про «не даёт закрыть».** Через API PR закрылся и переоткрылся штатно, так что состояние самого PR целое — упиралось в веб-интерфейс на битой PR-ссылке. Сейчас ссылка в порядке, кнопка должна работать; если снова упрётся — скажите, закрою через API. **На будущее:** пуши в ветку задачи, пока её PR закрыт, в diff не попадут. Если нужно приостановить ревью — лучше не закрывать PR, а перевести его в черновик или просто оставить открытым. `npm run build` — зелёный.
NotBigGhost merged commit 309e31a49a into dev 2026-09-07 15:53:40 +03:00
NotBigGhost deleted branch issue-4-header-footer-layout 2026-09-07 15:53:40 +03:00
Sign in to join this conversation.