zebra-spaces: games move to left column as persistent tiles — cameras+screens push them down
Per fox: 'make unmario and cake murder adventure as tiles on the left which always push down as stuff joins. this will allow people to play games during a meeting.' Layout change: - game-tabs + iframe moved out of <main class="timeline"> and into <aside id="sec-cameras"> as a third group (cameras → screens-thumbs → games), DOM order = stacking order, so a new camera or screen thumbnail naturally pushes the games further down the column - iframe sized to fit the 220px column (aspect-ratio: 4/3, ~165px tall), tabs stack vertically as full-width buttons - removed the timeline:has(> #sec-spotlight:not(.hidden)) → hide-games rules — no longer needed since games aren't in the timeline anymore - sec-cameras is always visible now (games live there permanently); the 'cameras' h2 hides when no live cameras to avoid an empty header - :has(> .cameras-col.hidden) page-grid rules stay as harmless dead code Games + screen-share + cameras now coexist: someone can play unmario in the corner while a colleague shares their screen at full size in the middle.
This commit is contained in:
parent
44ac92984c
commit
a2dda2d586
1 changed files with 40 additions and 32 deletions
|
|
@ -26,7 +26,7 @@
|
||||||
html.theme-dark .status-line { color: #888; }
|
html.theme-dark .status-line { color: #888; }
|
||||||
html.theme-dark .timeline,
|
html.theme-dark .timeline,
|
||||||
html.theme-dark .cameras-col { border-right-color: #222; }
|
html.theme-dark .cameras-col { border-right-color: #222; }
|
||||||
html.theme-dark .timeline-frame { background: #000; border-color: #222; }
|
html.theme-dark .game-tile-frame { background: #000; border-color: #222; }
|
||||||
/* buttons + inputs */
|
/* buttons + inputs */
|
||||||
html.theme-dark button,
|
html.theme-dark button,
|
||||||
html.theme-dark .game-tabs button,
|
html.theme-dark .game-tabs button,
|
||||||
|
|
@ -176,19 +176,25 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.controls { min-width: 0; }
|
.controls { min-width: 0; }
|
||||||
|
/* games live in the LEFT column now (under cameras + screens-thumbs)
|
||||||
|
* so people can play casually during a meeting without competing
|
||||||
|
* with screen-shares for the middle slot. The tabs wrap if the
|
||||||
|
* column is narrow; the iframe is sized for the column. */
|
||||||
|
.games-h2 { margin-top: 0.5rem; }
|
||||||
.game-tabs {
|
.game-tabs {
|
||||||
display: grid; grid-auto-flow: column; grid-auto-columns: max-content;
|
display: grid; grid-auto-columns: minmax(0, 1fr); grid-auto-flow: row;
|
||||||
gap: 0.4rem; margin-bottom: 0.5rem;
|
gap: 0.25rem; margin-bottom: 0.35rem;
|
||||||
}
|
}
|
||||||
.game-tabs button {
|
.game-tabs button {
|
||||||
background: #fff; color: #000; border: 1px solid #000;
|
background: #fff; color: #000; border: 1px solid #000;
|
||||||
padding: 0.3rem 0.8rem; font-family: monospace; font-size: 0.8rem; cursor: pointer;
|
padding: 0.25rem 0.5rem; font-family: monospace; font-size: 0.72rem;
|
||||||
|
cursor: pointer; text-align: left;
|
||||||
}
|
}
|
||||||
.game-tabs button.active { background: #000; color: #fff; }
|
.game-tabs button.active { background: #000; color: #fff; }
|
||||||
.game-tabs button:hover:not(.active) { background: #f0f0f0; }
|
.game-tabs button:hover:not(.active) { background: #f0f0f0; }
|
||||||
.timeline-frame {
|
.game-tile-frame {
|
||||||
min-height: 80vh; width: 100%;
|
width: 100%; aspect-ratio: 4 / 3;
|
||||||
border: 1px solid #ddd; background: #fff;
|
border: 1px solid #ddd; background: #fff; display: block;
|
||||||
}
|
}
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
body { padding: 1.25rem; }
|
body { padding: 1.25rem; }
|
||||||
|
|
@ -280,8 +286,7 @@
|
||||||
}
|
}
|
||||||
.screen-tile.needs-tap .tap-play { display: grid; }
|
.screen-tile.needs-tap .tap-play { display: grid; }
|
||||||
/* spotlight active → hide the game iframe so the spotlight tile owns the column */
|
/* spotlight active → hide the game iframe so the spotlight tile owns the column */
|
||||||
.timeline:has(> #sec-spotlight:not(.hidden)) > .game-tabs,
|
/* (games live in sec-cameras now — no timeline-side hide rule needed) */
|
||||||
.timeline:has(> #sec-spotlight:not(.hidden)) > #game-frame { display: none; }
|
|
||||||
|
|
||||||
/* camera tiles live in the LEFT column now — single column, stacked
|
/* camera tiles live in the LEFT column now — single column, stacked
|
||||||
* vertically. Each tile keeps a 16:9 letterbox so faces don't squash. */
|
* vertically. Each tile keeps a 16:9 letterbox so faces don't squash. */
|
||||||
|
|
@ -497,14 +502,28 @@ try {
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
|
|
||||||
<!-- left column: cameras stacked vertically so face-cams stay visible
|
<!-- left column: cameras at top, then screen-thumbs, then games at the
|
||||||
during a screen share without dwarfing the screen itself. Hidden
|
bottom. Games are persistent (always visible) so the column is
|
||||||
when nobody has a camera on. -->
|
always on; cameras + screens push the games further down as people
|
||||||
<aside id="sec-cameras" class="cameras-col hidden">
|
join + share. People can play during the meeting without the games
|
||||||
|
ever competing with a live screen-share for the middle slot. -->
|
||||||
|
<aside id="sec-cameras" class="cameras-col">
|
||||||
<h2>cameras</h2>
|
<h2>cameras</h2>
|
||||||
<div id="cameras"></div>
|
<div id="cameras"></div>
|
||||||
<h2 class="screens-thumbs-h2 hidden">screens</h2>
|
<h2 class="screens-thumbs-h2 hidden">screens</h2>
|
||||||
<div id="screens-thumbs"></div>
|
<div id="screens-thumbs"></div>
|
||||||
|
<h2 class="games-h2">games</h2>
|
||||||
|
<div class="game-tabs" id="game-tabs">
|
||||||
|
<button type="button" class="active" data-game="unmario"
|
||||||
|
data-src="https://unmario.com/">unmario</button>
|
||||||
|
<button type="button" data-game="cake"
|
||||||
|
data-src="https://cuppcb.com/games/cake-murder-adventure/">cake murder adventure</button>
|
||||||
|
</div>
|
||||||
|
<iframe id="game-frame" class="game-tile-frame"
|
||||||
|
src="https://unmario.com/"
|
||||||
|
title="game"
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"></iframe>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<main class="timeline">
|
<main class="timeline">
|
||||||
|
|
@ -514,22 +533,6 @@ try {
|
||||||
<section id="sec-spotlight" class="hidden">
|
<section id="sec-spotlight" class="hidden">
|
||||||
<div id="spotlight"></div>
|
<div id="spotlight"></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- placeholder content until the v0.3 event timeline lands: a game switcher
|
|
||||||
framing an external playable. Iframes load unsandboxed so the game JS can
|
|
||||||
run; if a target refuses framing (X-Frame-Options / CSP frame-ancestors)
|
|
||||||
the iframe goes blank — no impact on the controls column. -->
|
|
||||||
<div class="game-tabs" id="game-tabs">
|
|
||||||
<button type="button" class="active" data-game="unmario"
|
|
||||||
data-src="https://unmario.com/">unmario</button>
|
|
||||||
<button type="button" data-game="cake"
|
|
||||||
data-src="https://cuppcb.com/games/cake-murder-adventure/">cake murder adventure</button>
|
|
||||||
</div>
|
|
||||||
<iframe id="game-frame" class="timeline-frame"
|
|
||||||
src="https://unmario.com/"
|
|
||||||
title="game"
|
|
||||||
loading="lazy"
|
|
||||||
referrerpolicy="no-referrer"></iframe>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<aside class="controls">
|
<aside class="controls">
|
||||||
|
|
@ -1546,9 +1549,14 @@ function logSpotlightChange(uuid, key){
|
||||||
|
|
||||||
function updateContainerVisibility(){
|
function updateContainerVisibility(){
|
||||||
$('sec-spotlight').classList.toggle('hidden', !spotlight);
|
$('sec-spotlight').classList.toggle('hidden', !spotlight);
|
||||||
|
/* sec-cameras is ALWAYS visible now — the games tiles live there as
|
||||||
|
* persistent residents that get pushed down by arriving cameras +
|
||||||
|
* screens. Only the cameras-header and screens-header toggle. */
|
||||||
const anyCam = cameraVideos.size > 0;
|
const anyCam = cameraVideos.size > 0;
|
||||||
const anyScreen = screenVideos.size > 0;
|
const anyScreen = screenVideos.size > 0;
|
||||||
$('sec-cameras').classList.toggle('hidden', !(anyCam || anyScreen));
|
/* hide the 'cameras' h2 when no live cameras to avoid an empty header */
|
||||||
|
const camH2 = document.querySelector('#sec-cameras > h2:first-of-type');
|
||||||
|
if (camH2) camH2.classList.toggle('hidden', !anyCam);
|
||||||
document.querySelector('.screens-thumbs-h2').classList.toggle('hidden', !anyScreen);
|
document.querySelector('.screens-thumbs-h2').classList.toggle('hidden', !anyScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3218,8 +3226,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">
|
<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>
|
<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">5b160894e031e4a9362e8fdb09bc6905</span><br>
|
md5 <span class="stamp-md5">947c4c514376d2995517d8576ac3e3a4</span><br>
|
||||||
sha256 <span class="stamp-sha">80bdc123f6e3b3297af300b3a2076498a389bbff63042926373aa9eae7fa0a27</span><br>
|
sha256 <span class="stamp-sha">583d56867cce3995325c8f35b83388dcbd6fb14584f64dfcac3a7dcb28556f1c</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">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>
|
<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>
|
</footer>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue