zebra-report: hide-panel toggle + camera PiP overlay — mirror
This commit is contained in:
parent
1e6a6a7c1b
commit
a6de7024e8
1 changed files with 75 additions and 8 deletions
|
|
@ -29,12 +29,14 @@
|
|||
/* buttons + inputs */
|
||||
html.theme-dark button,
|
||||
html.theme-dark .game-tabs button,
|
||||
html.theme-dark .theme-toggle {
|
||||
html.theme-dark .theme-toggle,
|
||||
html.theme-dark .controls-toggle {
|
||||
background: #000; color: #ccc; border-color: #444;
|
||||
}
|
||||
html.theme-dark button:hover:not(:disabled),
|
||||
html.theme-dark .game-tabs button:hover:not(.active),
|
||||
html.theme-dark .theme-toggle:hover { background: #1a1a1a; }
|
||||
html.theme-dark .theme-toggle:hover,
|
||||
html.theme-dark .controls-toggle:hover { background: #1a1a1a; }
|
||||
html.theme-dark button.invert { background: #ccc; color: #000; border-color: #ccc; }
|
||||
html.theme-dark button.invert:hover:not(:disabled) { background: #999; }
|
||||
html.theme-dark .game-tabs button.active { background: #ccc; color: #000; border-color: #ccc; }
|
||||
|
|
@ -83,13 +85,15 @@
|
|||
html.theme-dark footer span { color: #555 !important; }
|
||||
html.theme-dark footer a { color: #777 !important; }
|
||||
|
||||
.theme-toggle {
|
||||
position: fixed; top: 0.6rem; right: 0.8rem; z-index: 9999;
|
||||
.theme-toggle, .controls-toggle {
|
||||
position: fixed; top: 0.6rem; z-index: 9999;
|
||||
background: #fff; color: #000; border: 1px solid #000;
|
||||
padding: 0.2rem 0.55rem; font-family: monospace; font-size: 0.7rem;
|
||||
cursor: pointer; line-height: 1;
|
||||
}
|
||||
.theme-toggle:hover { background: #f0f0f0; }
|
||||
.theme-toggle { right: 0.8rem; }
|
||||
.controls-toggle { right: 4.3rem; }
|
||||
.theme-toggle:hover, .controls-toggle:hover { background: #f0f0f0; }
|
||||
/* two-column page on desktop: left = timeline (1fr, takes remaining
|
||||
* space — hosts screen shares + the running event feed), right =
|
||||
* controls (kept narrow so the screen share gets maximum pixels).
|
||||
|
|
@ -101,9 +105,22 @@
|
|||
gap: 1.25rem;
|
||||
align-items: start;
|
||||
}
|
||||
/* collapsed: right column folds away so the screen share fills the
|
||||
* full viewport width. The timeline column's right border + padding
|
||||
* collapse with it. */
|
||||
.page.controls-collapsed {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 0;
|
||||
}
|
||||
.page.controls-collapsed > .controls { display: none; }
|
||||
.page.controls-collapsed > .timeline { border-right: none; padding-right: 0; }
|
||||
/* honour the pre-paint pref so first-paint matches saved state */
|
||||
html.controls-collapsed-pref .page { grid-template-columns: minmax(0, 1fr); gap: 0; }
|
||||
html.controls-collapsed-pref .page > .controls { display: none; }
|
||||
html.controls-collapsed-pref .page > .timeline { border-right: none; padding-right: 0; }
|
||||
.timeline {
|
||||
border-right: 1px solid #ddd; padding-right: 1.25rem; min-height: 60vh;
|
||||
min-width: 0; display: flex; flex-direction: column;
|
||||
min-width: 0; display: flex; flex-direction: column; position: relative;
|
||||
}
|
||||
.controls { min-width: 0; }
|
||||
.game-tabs { display: flex; gap: 0.4rem; margin-bottom: 0.5rem; flex-wrap: wrap; }
|
||||
|
|
@ -185,6 +202,26 @@
|
|||
}
|
||||
.camera-tile.needs-tap .tap-play { display: flex; }
|
||||
|
||||
/* PiP mode: when a screen is being shared, cameras get out of the way —
|
||||
* they float as a small vertical strip in the bottom-right of the
|
||||
* timeline column, layered over the screen tile. Standard Zoom/Meet
|
||||
* pattern. Scrolls vertically if there are more than fit. The screen
|
||||
* keeps the full timeline width so 1080p screen-share stays huge. */
|
||||
.timeline:has(> #sec-screens:not(.hidden)) > #sec-cameras {
|
||||
position: absolute; right: 0.6rem; bottom: 0.6rem;
|
||||
width: clamp(180px, 22%, 320px);
|
||||
max-height: 70vh; overflow-y: auto;
|
||||
z-index: 50; padding: 0.35rem;
|
||||
background: rgba(0,0,0,0.55);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.timeline:has(> #sec-screens:not(.hidden)) > #sec-cameras > h2 {
|
||||
color: #ddd; font-size: 0.75rem; margin: 0 0 0.3rem; border-bottom: none;
|
||||
}
|
||||
.timeline:has(> #sec-screens:not(.hidden)) #cameras { grid-template-columns: 1fr; gap: 0.3rem; }
|
||||
.timeline:has(> #sec-screens:not(.hidden)) .camera-tile video { max-height: 16vh; }
|
||||
.timeline:has(> #sec-screens:not(.hidden)) .camera-tile .screen-meta { font-size: 0.6rem; padding: 0.15rem 0.3rem; }
|
||||
|
||||
/* latency panel: one row per live PC, fixed-width columns so the numbers
|
||||
* line up vertically as values bounce. lat-good < 50ms, mid < 150ms,
|
||||
* bad ≥ 150ms — colour-tagged so the user can scan at a glance. */
|
||||
|
|
@ -319,10 +356,18 @@ try {
|
|||
document.documentElement.classList.add('theme-dark');
|
||||
}
|
||||
} catch(_){ document.documentElement.classList.add('theme-dark'); }
|
||||
/* sidebar-collapsed pre-paint: apply to <html> so the .page child can
|
||||
* read it via :has() or via a body-level class added on DOMContentLoaded */
|
||||
try {
|
||||
if (localStorage.getItem('zebra-spaces-controls-v1') === 'hidden'){
|
||||
document.documentElement.classList.add('controls-collapsed-pref');
|
||||
}
|
||||
} catch(_){}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<button id="btn-theme" class="theme-toggle" type="button" aria-label="toggle dark mode">dark</button>
|
||||
<button id="btn-controls-toggle" class="controls-toggle" type="button" aria-label="hide side panel" title="hide right side panel">hide panel</button>
|
||||
|
||||
<div class="page">
|
||||
|
||||
|
|
@ -538,6 +583,28 @@ $('btn-theme').addEventListener('click', () => {
|
|||
try { localStorage.setItem(THEME_KEY, goDark ? 'dark' : 'light'); } catch(_){}
|
||||
applyThemeLabel();
|
||||
});
|
||||
|
||||
/* controls-panel collapse — promotes the pre-paint <html> pref onto the
|
||||
* .page element, then keeps both in sync on click. Pre-paint class on
|
||||
* <html> stays so a fresh load with a saved 'hidden' pref still shows
|
||||
* the layout collapsed instantly. */
|
||||
const CONTROLS_KEY = 'zebra-spaces-controls-v1';
|
||||
function applyControlsLabel(){
|
||||
const hidden = document.querySelector('.page').classList.contains('controls-collapsed');
|
||||
const btn = $('btn-controls-toggle'); if (btn) btn.textContent = hidden ? 'show panel' : 'hide panel';
|
||||
}
|
||||
if (document.documentElement.classList.contains('controls-collapsed-pref')){
|
||||
document.querySelector('.page').classList.add('controls-collapsed');
|
||||
}
|
||||
applyControlsLabel();
|
||||
$('btn-controls-toggle').addEventListener('click', () => {
|
||||
const page = document.querySelector('.page');
|
||||
const goHidden = !page.classList.contains('controls-collapsed');
|
||||
page.classList.toggle('controls-collapsed', goHidden);
|
||||
document.documentElement.classList.toggle('controls-collapsed-pref', goHidden);
|
||||
try { localStorage.setItem(CONTROLS_KEY, goHidden ? 'hidden' : 'shown'); } catch(_){}
|
||||
applyControlsLabel();
|
||||
});
|
||||
const VAULT_PREFIX = 'zspc-id-v1|';
|
||||
const PBKDF2_ITER = 600000;
|
||||
|
||||
|
|
@ -2183,8 +2250,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
|
|||
|
||||
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
|
||||
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> · built <span class="stamp-date">2026-06-02</span><br>
|
||||
md5 <span class="stamp-md5">df76b79d099ed55cab1336afdf62e8a8</span><br>
|
||||
sha256 <span class="stamp-sha">f2a8f4316571f5accc3ed4b6be564ab31328c732323f2f64ce62675d3de1701c</span><br>
|
||||
md5 <span class="stamp-md5">016e64ea183b4be1c9803669e0558045</span><br>
|
||||
sha256 <span class="stamp-sha">9ad330fb516bb1e632b1f66511fb840cdcbd2cfc14390101fcb1bb5c362c978b</span><br>
|
||||
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
|
||||
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
|
||||
</footer>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue