refactor(agents): migrate .agent/ planning tree to .agents/
Standardize on the .agents/ directory (shared with project skills): phases/, user_stories/, reports/, screenshots/, validate.sh, and phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves history; runtime artifacts move alongside). Updates every reference in AGENTS.md, README.md, .gitignore, app docstrings, and test story headers. Historical KB content in data/ and the runtime pipeline.log transcript are left untouched.
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# 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. `.agents/` 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
|
||||
1. `01_sticky_header_css.md` — drop `height: 100%` from `body` (keep it on `html`), refresh the stale phase-12 comment, unit CSS pins in `tests/unit/test_sticky_header.py`.
|
||||
2. `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.py` pattern): `html` keeps `height: 100%`; the `body` rule carries NO `height:` (negative pin) and keeps `min-height: 100dvh`; `.app-header` and `.doc-header` keep `position: 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-header` rect top == 0 (±1px) and the header is visible.
|
||||
- [ ] Document viewer on a long doc: after full scroll, `.doc-header` rect top == 0 (±1px).
|
||||
- [ ] Short page (empty chat, 1280×800): body height == 800, `.app-footer` bottom == 800, `.composer` bottom ≈ 800 (±2px) — the phase-52 pin holds.
|
||||
- [ ] `uv run pytest` green; coverage TOTAL >90%.
|
||||
- [ ] `uv run pytest tests/e2e/test_sticky_navbar.py -v --no-cov` green 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 pyright` clean.
|
||||
- [ ] One `--no-gpg-sign` commit; phase dir moved to `.agents/phases/complete/` (`.agents/` stays untracked — owner instruction, commit 281f355).
|
||||
|
||||
## Locked decisions
|
||||
- **Owner-locked (2026-08-31, roadmap confirmation, A1–A3):**
|
||||
1. **A1 (root cause):** the sticky travel range is capped by `body { height: 100% }` (`styles.css` L40) — the body box is pinned to one viewport and sticky elements (`.app-header`, `.doc-header`) can only travel within it.
|
||||
2. **A2 (fix):** CSS-only — drop `height: 100%` from `body` (keep it on `html`); the body's existing `min-height: 100dvh` keeps driving the short-page stretch. No JS changes, no new scroller (the document stays the scroll container).
|
||||
3. **A3 (E2E):** long-scroll surfaces = the seeded Sources table + the document viewer, with KB seeding via `import_sources` (the `test_document_viewer.py` pattern — fixtures + generated docs). No real LLM involved.
|
||||
|
||||
## Commit
|
||||
```bash
|
||||
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"
|
||||
```
|
||||
Reference in New Issue
Block a user