#!/usr/bin/env python3 """Source-only mobile/observed-backend UI invariants, no browser required.""" from pathlib import Path root=Path(__file__).resolve().parents[2] css=(root/'src/admin/web/style.css').read_text() preferences=(root/'src/admin/web/app/preferences.js').read_text() masonry=(root/'src/admin/web/app/overview-masonry.js').read_text() html=(root/'src/admin/web/index.html').read_text() render=(root/'src/admin/web/vhosts/render.js').read_text() client=(root/'src/upstream/client.rs').read_text() pool=(root/'src/balance/pool_view.rs').read_text() assert 'touch-action: pan-y pinch-zoom' in css assert 'overflow-anchor: none' in css assert 'grid-template-columns: repeat(2, minmax(0, 1fr))' in css assert '@container overview-canvas (max-width: 700px)' in css assert 'overview-canvas (max-width: 440px)' not in css assert '.vhost-backend-protocol-badge' in css assert '.vhost-card' in css[css.index('/* Global shape preference.'):] assert '.draft-dock,' not in css[css.index('/* Global shape preference.'):] assert 'grid.append(...orderedNodes)' in preferences assert 'orderedNodes.some((node, index) => node !== currentNodes[index])' in preferences assert 'if (ordered.some((node, i) => node !== previous[i])) grid.append(...ordered);' in masonry assert html.count('data-dashboard-widget=') >= 62 assert 'function renderUpstreamProtocolBadges(status)' in render assert 'const VHOST_PROTOCOL_FRESH_MS = 5 * 60 * 1000' in render assert 'self.inner.observe_protocol(value.version())' in client assert '"upstream_protocol_observed"' in pool print('PASS: mobile grid, shape, stable reorder and observed backend protocol source contracts')