website: fix the phone menu and the footer column - both live defects
gates / gates (push) Successful in 6m42s

Reported from a real phone. Both were mine, both shipped in the switch.

1. THE PHONE MENU WAS EMPTY. The drawer slid open correctly but had no items in
   it. site.css's OLD mobile nav was still reaching the shell's sidebar: under
   @media (max-width: 900px) it sets .nav-links to position:fixed; right:-100%,
   which parked the menu off-canvas INSIDE the drawer. Measured at 390px and
   860px: position fixed, right -280px.

   The cause is a hole in my own check. At STOP 1 I diffed the two stylesheets'
   declaration sets and found "exactly six" leaking declarations - but that diff
   EXCLUDED @media blocks. Re-run media-aware, the real number is FORTY, and the
   worst of them only apply below 900px, which is why desktop looked right and a
   phone did not. A check that silently skips part of its subject is not a check;
   this one reported a confident, wrong number.

   Fixed at the source rather than per-property: every selector belonging to the
   website's OLD chrome (nav, .nav-links*, .mobile-overlay, .hamburger, .logo*,
   .lang-globe-li - 29 occurrences) is now scoped `body:not(.shell)`. Scoped, not
   deleted, so a future non-shell page still works. .hamburger-box and
   .hamburger-line are deliberately left unscoped: the shell's burger uses them.
   Leaks after the fix: 40 -> 0.

2. THE FOOTER RENDERED AS A SECOND COLUMN at the top right on 16 pages. body is a
   flex row on a shell page, and my insert only moved the footer inside <main>
   when the page ENDED with </main>; pages with scripts after it fell through and
   left the footer as a direct child of body, i.e. a flex sibling of the sidebar.
   Moved inside <main> on all 16, each move asserted to have landed inside.

Both are now gated: gate 3b requires every shell page's footer to be INSIDE
<main class="content">, red-proofed by putting one outside and watching it convict.

site.css?v=23 / shell.css?v=23.
This commit is contained in:
2026-10-11 16:25:01 +02:00
parent f92e81ee14
commit 5aeb36b5bd
22 changed files with 186 additions and 197 deletions
+11
View File
@@ -278,6 +278,17 @@ for p in sorted(SHELL):
if not f:
fail("%s: no <footer> — the legal pages and the operator's e-mail are reachable only from it" % p)
continue
# ...and it must sit INSIDE the content column. body is a flex row on a shell page, so a footer
# left outside <main> becomes a SECOND COLUMN beside the content (seen live on 16 pages,
# 2026-10-11: the footer rendered at the top right of the page).
_main = re.search(r'<main class="content">.*?</main>', s, re.DOTALL)
if not _main:
fail("%s: no <main class=\"content\"> — a shell page puts its content in one" % p)
continue
if not (_main.start() < f.start() < _main.end()):
fail("%s: <footer> is outside <main class=\"content\"> — on a shell page body is a flex row, "
"so it renders as a second column beside the content" % p)
continue
_shell_by_lang.setdefault(lang_of(p), []).append((p, norm_block(m.group(0)) + norm_block(f.group(0))))
for _lang, _members in sorted(_shell_by_lang.items()):
_ref_p, _ref = _members[0]