css: grid-only layout — convert every flex container to grid + pin column widths
Two fixes in one — the immediate layout bug from the screenshot (timeline sliding into column 1 with controls eating ~80% of the viewport) and the architectural rule that all zebra page layout uses grid. Layout bug (was: when cameras-col gets .hidden + the global .hidden utility's display:none !important, the grid auto-placement promoted .timeline into column 1 and .controls into column 2 → controls took the 1fr middle track). Fix: - explicit grid-column: 1/2/3 on cameras-col / timeline / controls so each child stays in its assigned column regardless of siblings going display:none - .cameras-col uses 'display: grid !important' to override the global .hidden util, then only its content (h2 + #cameras) goes display:none via separate selectors when the .hidden class is present - controls track clamped to min(360px, 50vw) so a wide window can't let the side panel eat the screen-share area Grid-only refactor: - every flex container converted: .timeline, .cameras-col, .game-tabs, .screen-tile, .screen-meta, .tap-play, .camera-tile, .row, .mod-actions, .invite-banner, .invite-actions, .notice-banner - chat.html + zebra-audio.html same treatment (.row, .field-row, .share-box .copy-row, the inline H2 style, .mode-toggle, .dot) - inline 'style=flex:1' on inputs/meters in chat.html replaced with 'style=width:100%' - now zero 'display: flex' / 'inline-flex' across all five zebra pages - CLAUDE.md documents the grid-only rule under web-page authoring
This commit is contained in:
parent
95851371bc
commit
eed5348567
4 changed files with 137 additions and 55 deletions
|
|
@ -53,11 +53,16 @@
|
|||
button:disabled { opacity: 0.3; cursor: default; }
|
||||
button.invert { background: #000; color: #fff; }
|
||||
button.invert:hover:not(:disabled) { background: #333; }
|
||||
.row { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.75rem; flex-wrap: wrap; }
|
||||
.row {
|
||||
display: grid; grid-auto-flow: column;
|
||||
grid-template-columns: max-content minmax(0, 1fr);
|
||||
grid-auto-columns: max-content;
|
||||
align-items: center; gap: 0.75rem; margin-bottom: 0.75rem;
|
||||
}
|
||||
.dot {
|
||||
width: 9px; height: 9px; border-radius: 50%;
|
||||
border: 1px solid #000; background: #fff;
|
||||
flex-shrink: 0; transition: background 0.15s;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
.dot.on { background: #000; }
|
||||
.dot.warn { background: #888; }
|
||||
|
|
@ -71,8 +76,11 @@
|
|||
}
|
||||
input[type=text], input[type=password], select { width: 100%; }
|
||||
textarea { width: 100%; resize: vertical; min-height: 4.5rem; }
|
||||
.field-row { display: flex; gap: 0.5rem; margin-bottom: 0.5rem; }
|
||||
.field-row > input, .field-row > textarea { flex: 1; }
|
||||
.field-row {
|
||||
display: grid; grid-template-columns: minmax(0, 1fr) max-content;
|
||||
gap: 0.5rem; margin-bottom: 0.5rem;
|
||||
}
|
||||
.field-row > input, .field-row > textarea { width: 100%; min-width: 0; }
|
||||
.key-display {
|
||||
border: 1px solid #ccc; padding: 0.5rem;
|
||||
font-family: monospace; font-size: 0.7rem;
|
||||
|
|
@ -127,7 +135,8 @@
|
|||
}
|
||||
details[open] > summary { margin-bottom: 0.5rem; }
|
||||
.mode-toggle {
|
||||
display: inline-flex; border: 1px solid #000;
|
||||
display: inline-grid; grid-auto-flow: column; grid-auto-columns: max-content;
|
||||
border: 1px solid #000;
|
||||
font-size: 0.78rem; user-select: none;
|
||||
}
|
||||
.mode-toggle > label {
|
||||
|
|
@ -152,11 +161,14 @@
|
|||
.share-box .qr-canvas {
|
||||
width: 320px; height: 320px;
|
||||
border: 1px solid #ccc; background: #fff;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
display: grid; place-items: center;
|
||||
font-size: 0.65rem; color: #999;
|
||||
}
|
||||
.share-box input { width: 100%; font-size: 0.7rem; }
|
||||
.share-box .copy-row { display: flex; gap: 0.4rem; margin-top: 0.3rem; }
|
||||
.share-box .copy-row {
|
||||
display: grid; grid-template-columns: minmax(0, 1fr) max-content;
|
||||
gap: 0.4rem; margin-top: 0.3rem;
|
||||
}
|
||||
.share-box .copy-row button { font-size: 0.75rem; padding: 0.25rem 0.7rem; }
|
||||
@media (max-width: 600px) {
|
||||
.share-box { grid-template-columns: 1fr; }
|
||||
|
|
@ -250,7 +262,7 @@ try {
|
|||
<h2>identity</h2>
|
||||
<div class="row">
|
||||
<label for="handle-in">handle:</label>
|
||||
<input type="text" id="handle-in" style="flex:1; min-width:0" placeholder="your handle">
|
||||
<input type="text" id="handle-in" style="width:100%; min-width:0" placeholder="your handle">
|
||||
<span class="status-line" id="id-status"></span>
|
||||
</div>
|
||||
<div class="row" style="margin-top:0.5rem">
|
||||
|
|
@ -269,7 +281,7 @@ try {
|
|||
<h2>room (passphrase mode)</h2>
|
||||
<div class="row">
|
||||
<input type="password" id="passphrase-in" placeholder="room passphrase — everyone in the room types the same one"
|
||||
style="flex:1; min-width:0">
|
||||
style="width:100%; min-width:0">
|
||||
</div>
|
||||
<div class="row">
|
||||
<button id="btn-pp-join" class="invert">enter room</button>
|
||||
|
|
@ -307,12 +319,12 @@ try {
|
|||
</div>
|
||||
<div class="row" style="margin-top:0.4rem">
|
||||
<span class="note" style="min-width:3rem">tx</span>
|
||||
<div class="meter" style="flex:1"><div class="meter-fill" id="meter-tx"></div></div>
|
||||
<div class="meter" style="width:100%"><div class="meter-fill" id="meter-tx"></div></div>
|
||||
<span class="note" id="gain-label" style="min-width:3rem; text-align:right">0%</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="note" style="min-width:3rem">rx</span>
|
||||
<div class="meter" style="flex:1"><div class="meter-fill" id="meter-rx"></div></div>
|
||||
<div class="meter" style="width:100%"><div class="meter-fill" id="meter-rx"></div></div>
|
||||
<span class="note" id="rx-label" style="min-width:3rem; text-align:right">—</span>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1720,8 +1732,8 @@ logLine('sys', 'chat content lives in encrypted SRTP audio. no IP packets carry
|
|||
</script>
|
||||
<footer style="max-width:820px;margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
|
||||
<span style="color:#777">page integrity</span> · built <span class="stamp-date">2026-06-02</span><br>
|
||||
md5 <span class="stamp-md5">0fb2dca42673efdde9164f5bc24d0200</span><br>
|
||||
sha256 <span class="stamp-sha">ba3b4ce8b96e2649f76f9b0338bde38ddcdbea148adbdfb0e23094a85999ee2b</span><br>
|
||||
md5 <span class="stamp-md5">5ae64bcf96a54da7ea55a0df88548920</span><br>
|
||||
sha256 <span class="stamp-sha">06a3c011ec9670d85c6ab27b8decbfcc4f78e8a9be8186407670fdf4e4cc8dfd</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 it against these hashes; point it 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