Files
dashboards/.agents/phases/todo/20_masthead_nav_polish/00_phase.md
T
ducoterra f9b1565abb chore(agent): phase roadmap from TODO.md, 5 phases
Convert the 11 TODO items to phases 20-24 (masthead/nav polish,
page cleanups, /disks hiding unconfigured hosts, LLM rate window,
dev mTLS rollout). TODO.md cleared; items now live in
.agents/phases/todo/.

LLM-Generated: true
2026-10-20 18:06:46 -04:00

5.0 KiB
Raw Blame History

Phase 20 — Masthead & navigation polish

Source: TODO.md L4, L5, L6, L10, L11 — "masthead row layout, un-sticky bar, hamburger animation, always-visible admin links" Story: n/a Context: src/dashboards/web/static/dash.css (.masthead at line 99 — position: sticky; top: 0; z-index: 40; display: flex; height: var(--header-h); .masthead-right at line 148 — margin-inline-start: auto; #nav-toggle at line 190 — the --nav-toggle-display token reveal; the ≤640px block at lines 208–280 — masthead wrap, masthead-right { justify-content: flex-end }, the nav.tabs dropdown at top: 100% under the sticky bar, the env(safe-area-inset-top, 0px) padding line), src/dashboards/web/static/app.js (the setNavMenu() funnel at lines 695–722 — four close paths, matchMedia('(max-width: 640px)')), src/dashboards/web/pages/*.html (the masthead in every page: brand, #nav-toggle, nav.tabs#nav-tabs, .masthead-right holding #nav-status + clock + ⚷ Certs + ⚙ Account + theme toggle; certs.html lacks ⚷ Certs, settings.html lacks ⚙ Account — the phase-15 "no self-link" rule this phase inverts), tests/test_api.py (test_every_page_links_to_both_admin_pages at line 999, test_the_disks_tab_is_in_the_masthead_of_every_page at line 3913, test_the_nav_toggle_is_in_the_masthead_of_every_tabbed_page at line 3957)

Objective

The masthead becomes a three-row bar at all widths — row 1 the brand and the five dashboard tabs, row 2 the per-source status indicators left-justified in their own row, row 3 the ⚷ Certs / ⚙ Account / ☾ Dark controls left-justified in their own row under the indicators — the bar stops being sticky (it scrolls away, maximising data screen space), the hamburger menu slides out and back in (180 ms, the brain_of_reese pattern, stilled under prefers-reduced-motion), and both admin links stay visible on every page including the two admin pages themselves. The served page markup is unchanged except the two added admin links; the tab structure (five links, one aria-current), the #nav-toggle token reveal, the safe-area padding line and the four close paths all stay exactly as phase 18 pinned them.

Dependencies

  • 19_ups_events_expandable (todo) — both phases touch ups.html (the masthead, the events card); landing 19 first keeps this phase's diff confined to the masthead.

Tasks

  1. 01_two_row_masthead.md — the three-row left-justified masthead at all widths (CSS-only reflow; the mobile block re-cut for the new rows)
  2. 02_unsticky_masthead.md — the bar scrolls away: sticky → relative, the dropdown anchor kept
  3. 03_hamburger_slide.md — the 180 ms slide+fade on the ≤640px dropdown, stilled under prefers-reduced-motion
  4. 04_admin_links_visible.md — ⚷ Certs on /certs, ⚙ Account on /settings; the "no self-link" pin inverted to "all eight pages link to both"

Testing & Quality

  • Unit/integration: tests/test_api.py — the served-page pins (task 04's rewritten admin-link test over all eight non-login pages, the unchanged tab-structure pins at lines 3913/3957, the CSS pins for the row layout and the un-sticky change), the unchanged setNavMenu behaviour
  • Coverage: >90% on new/modified code (the phase is markup + JS + CSS; the gate applies to the changed Python test files)
  • The phase is "Complete" only when the entire project test suite passes 100% (every test in the project, not just this phase's)

Documentation & Consistency

  • The final pass reviews README.md and AGENTS.md in full against the project as it stands after this phase — fixing every inconsistency found, including pre-existing ones not caused by this phase. AGENTS.md's masthead paragraph (the phase-18 "specificity ladder" and the top: 100%-under-the-sticky-bar wording) and the phase-15 "neither admin page links to itself" sentence (gap 12's "now questioned" item — this phase is the decision) both get rewritten to the new state in the section's voice.

Completion Criteria

  • at 1280 px and at 360 px, every tabbed page and both admin pages render the three-row masthead: brand + tabs, left-justified indicators row, left-justified controls row under it (screenshots in data/logs/, invariant 10)
  • scrolling any page at 1280 px and 360 px leaves the bar behind (no sticky offset), while the mobile dropdown still opens directly under the bar
  • at 360 px the hamburger menu slides out and back in (180 ms); with prefers-reduced-motion it snaps
  • /certs renders ⚷ Certs and /settings renders ⚙ Account, before the theme toggle and outside .tabs, exactly like the five dashboards
  • uv run pytest green, coverage not down, ruff + pyright clean
  • bash .agents/validate.sh green (including node --check of the modified app.js)
  • no behavior change in completed work: the tab structure, the token reveal, the safe-area padding line, the four close paths, the status dots and the theme toggle are all unchanged