Convert the two TODO items into append-mode phases (Protocol B): 18_nav_hamburger (TODO L3) and 19_ups_events_expandable (TODO L4), numbered after the existing todo phases. TODO.md is cleared to an empty list; its items now live in .agents/phases/todo/. LLM-Generated: true
3.8 KiB
3.8 KiB
Task 02 — The ≤640px dropdown CSS
Phase: 18_nav_hamburger · Source: TODO.md:3 — "The nav bar needs to collapse into a hamburger like brain of reese does"
Story: n/a
Objective
The CSS that makes the hamburger real at ≤640px: the toggle button visible, the inline tab nav hidden, the .is-open nav rendered as a dropdown under the sticky masthead, and the masthead wrapping to two rows so the masthead-right cluster does not overflow a phone. Above 640px nothing changes.
Work
src/dashboards/web/static/dash.css— the base.nav-toggle { display: none; }rule already landed with task 01's markup (the button is invisible on every width until this task's block). Extend the existing@media (max-width: 640px)block at line 286 (or add a sibling block — the file's convention is one block per concern; a/* mobile nav */-commented block beside the masthead section is the cleaner home):.masthead { height: auto; min-height: var(--header-h); flex-wrap: wrap; }— the single-row fixed-height masthead cannot hold brand + toggle + the wholemasthead-rightcluster at 360px; two rows, first row brand + toggle, second row the cluster..nav-toggle { display: inline-flex; align-items: center; }(it is abutton.ghost, so the outlined style is inherited — no second palette, the file's rule).nav.tabs { display: none; }andnav.tabs.is-open { display: flex; flex-direction: column; gap: 0; position: absolute; top: 100%; left: 0; right: 0; background: var(--bg-raised); border-bottom: 1px solid var(--border); box-shadow: 0 8px 24px rgba(0, 0, 0, .35); padding: .4rem; z-index: 41; }— the dropdown. The masthead isposition: sticky, which is a non-static containing block for its absolute descendants, sotop: 100%pins it directly under the (wrapped, two-row) masthead.z-index: 41is one above the masthead's 40 so the dropdown sits on the page content.nav.tabs.is-open a { padding: .6rem .7rem; border-radius: var(--radius-sm); }— touch-sized rows; the existing:hover/[aria-current="page"]rules carry over unchanged.- Optional at most: a 120ms opacity/translateY transition on
nav.tabs.is-open, disabled inside the existing@media (prefers-reduced-motion: reduce)block at line 938 (add the dropdown selector to that block's list of motion-killers if used). If in doubt, ship without the transition.
ASSUMPTION:the dropdown is a single full-width column under the masthead (brain's shape, adapted: brain hides the nav in a#app-navcontainer; here thenavelement itself is the container and getsid="nav-tabs"+.is-open). No separate menu panel element.ASSUMPTION:nobody-level marker class (brain'snav-menu-openexists for its sticky bottom chat cluster, which the dashboards do not have — the dropdown competes with nothing; do not copy a side effect nobody needs).
Testing & Quality
- Integration: the served-stylesheet pins land in task 04 (base rule present, ≤640px block contains the toggle-visible + tabs-hidden +
.is-openrules); the untouchednode --checkgate passes (CSS is not checked, but confirm no syntax error by loading the page in the browser — task 04's verification) - Coverage: >90% on modified code (CSS only; the gate's pytest/ruff/pyright must stay green)
Completion Criteria
- at a 360px-wide browser window: the tab links are gone from the row, the
☰button is visible, and toggling.is-open(by hand in devtools) shows the full-width dropdown under the masthead with the five links stacked and thearia-currenttab highlighted - at 700px and 1200px the masthead is byte-identical in layout to before (one row, inline tabs, no button)
- the dropdown does not trap or cover the
masthead-rightcluster, and the page content scrolls under it bash .agents/validate.shgreen