Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ <h2>Linux Kernel Ring 0 Visualization</h2>
console.error('❌ RightSemicircleMenuManager class NOT loaded!');
}
</script>
<script src="/static/js/main.js?v=194"></script>
<script src="/static/js/main.js?v=195"></script>
</body>
</html>
16 changes: 15 additions & 1 deletion static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,22 @@ let rightSemicircleMenuManager;
let connectionsManager; // make available for cleanup handlers
let pinnedProcessDossier = null;
const MOBILE_LAYOUT_BREAKPOINT = 900;
const MOBILE_TOUCH_SHORT_SIDE = 820;
function isMobileLayout() {
return window.innerWidth <= MOBILE_LAYOUT_BREAKPOINT;
// Primary signal: narrow viewport.
if (window.innerWidth <= MOBILE_LAYOUT_BREAKPOINT) return true;

// Fallback for touch devices that report a wide viewport (large phones,
// phones in landscape, small tablets, in-app browsers). The desktop
// composition is built for ~1400px and overflows these screens, leaving
// only the central circle visible — so route them to the mobile layout too.
const mm = typeof window.matchMedia === 'function' ? window.matchMedia.bind(window) : null;
const isTouch = (mm && (mm('(pointer: coarse)').matches || mm('(hover: none)').matches))
|| (typeof navigator !== 'undefined' && Number(navigator.maxTouchPoints || 0) > 0);
const shortSide = Math.min(window.innerWidth, window.innerHeight);
if (isTouch && shortSide <= MOBILE_TOUCH_SHORT_SIDE) return true;

return false;
}

function syncRealtimeFeedsForViewport() {
Expand Down
Loading