Remove the blanket .agent/ gitignore so the phase roadmap, user stories, reports, and PLAN.md are versioned with the code. Only runtime artifacts (.agent/phase-sessions/, .agent/pipeline.log) remain ignored. Update AGENTS.md git protocol rule to match.
4.4 KiB
Phase 60 — Sticky Navbar (stays stuck to the top while scrolling)
Source: TODO.md L3 — "The navbar disappears when you scroll down, should stay stuck to the top of the screen"
Story: n/a (TODO-derived — owner roadmap confirmation 2026-08-31, A1–A3)
Context: The navbar already HAS the sticky CSS: .app-header (frontend/assets/styles.css ~L194 — position: sticky; top: 0; z-index: 20) and the document viewer's two-row .doc-header (~L2201 — also position: sticky; top: 0), both direct children of <body> on every page. The bug: html, body { height: 100% } (~L40) pins the body box to exactly one viewport, and a sticky element's travel range is constrained to its containing block — so after ~1 viewport of scrolling the header un-pins and scrolls away with the body. Verified with headless Chromium during the TODO audit (2026-08-31): with the current rule the header's rect top is −1264px after a 2000px scroll; with height dropped from body (keeping min-height: 100dvh) it is top = 0, and on a short page the footer still lands at the viewport bottom (800/800 at 1280×800). The document must stay the scroll container (phase 52 no-inner-scroller contract, ~L387) — this fix adds no scroller, it only lets the body grow to its content. .agent/ is untracked (owner commit 281f355) — phase commits stage frontend/ tests/ only.
Objective
The navbar — and the document-viewer header — stays stuck to the top of the screen on every page at every scroll position, while the short-page layout (flex stretch, pinned composer, footer) stays exactly as it is today.
Dependencies
59_response_to_docs_push(todo, preceding — no functional dependency; ordering by number)
Tasks
01_sticky_header_css.md— dropheight: 100%frombody(keep it onhtml), refresh the stale phase-12 comment, unit CSS pins intests/unit/test_sticky_header.py.02_e2e_sticky_navbar.md—tests/e2e/test_sticky_navbar.py(rect-top == 0 proofs on Sources + viewer at the bottom of long pages; short-page stretch/composer regressions), regression suites, atomic commit.
Testing & Quality
- Unit CSS pins (house style,
tests/unit/test_save_chat_ui.pypattern):htmlkeepsheight: 100%; thebodyrule carries NOheight:(negative pin) and keepsmin-height: 100dvh;.app-headerand.doc-headerkeepposition: sticky; top: 0. - E2E (mandatory, A3):
tests/e2e/test_sticky_navbar.py, run in isolation. - Coverage: >90% on
app/(validate.sh gate — pure-CSS phase, gate still runs).
Completion Criteria
- Sources page (KB long enough to scroll), 1280×800: after
window.scrollTo(0, 999999)the.app-headerrect top == 0 (±1px) and the header is visible. - Document viewer on a long doc: after full scroll,
.doc-headerrect top == 0 (±1px). - Short page (empty chat, 1280×800): body height == 800,
.app-footerbottom == 800,.composerbottom ≈ 800 (±2px) — the phase-52 pin holds. uv run pytestgreen; coverage TOTAL >90%.uv run pytest tests/e2e/test_sticky_navbar.py -v --no-covgreen in isolation (DB up).- Regression E2E suites green in isolation:
test_pinned_composer.py,test_document_viewer.py,test_responsive_polish.py,test_smoke.py,test_no_reply_autoscroll.py,test_mobile_hamburger_nav.py. uv run ruff check . && uv run pyrightclean.- One
--no-gpg-signcommit; phase dir moved to.agent/phases/complete/(.agent/stays untracked — owner instruction, commit281f355).
Locked decisions
- Owner-locked (2026-08-31, roadmap confirmation, A1–A3):
- A1 (root cause): the sticky travel range is capped by
body { height: 100% }(styles.cssL40) — the body box is pinned to one viewport and sticky elements (.app-header,.doc-header) can only travel within it. - A2 (fix): CSS-only — drop
height: 100%frombody(keep it onhtml); the body's existingmin-height: 100dvhkeeps driving the short-page stretch. No JS changes, no new scroller (the document stays the scroll container). - A3 (E2E): long-scroll surfaces = the seeded Sources table + the document viewer, with KB seeding via
import_sources(thetest_document_viewer.pypattern — fixtures + generated docs). No real LLM involved.
- A1 (root cause): the sticky travel range is capped by
Commit
git add frontend/ tests/ && git commit --no-gpg-sign -m "fix(web): keep the navbar stuck to the top — drop the body height cap on the sticky range"