diff --git a/zebra-report/zebra-spaces.html b/zebra-report/zebra-spaces.html
index 9665390..f2a6c1b 100644
--- a/zebra-report/zebra-spaces.html
+++ b/zebra-report/zebra-spaces.html
@@ -481,20 +481,35 @@
* the pubkey, never wrap a handle mid-word. */
.member {
display: grid;
- grid-template-columns: 5.5rem minmax(0, 1fr) 1.4rem 5rem;
+ /* extra 1.4rem column for the per-speaker stream toggle — lives on the
+ * top row next to the mic icon so it never wraps + never adds row
+ * height (the original 3-row layout is preserved). Single-char button
+ * (○ / ◉) keeps the column tight. */
+ grid-template-columns: 5.5rem minmax(0, 1fr) 1.4rem 1.4rem 5rem;
grid-template-areas:
- "badge handle mic meter"
- "badge pub pub pub"
- "badge acts acts acts";
+ "badge handle mic strm meter"
+ "badge pub pub pub pub"
+ "badge acts acts acts acts";
align-items: center; gap: 0.35rem 0.55rem; padding: 0.35rem 0;
border-bottom: 1px dotted #ccc; font-size: 0.85rem;
}
- .member > .badge { grid-area: badge; align-self: start; }
- .member > .handle { grid-area: handle; }
- .member > .pub-short { grid-area: pub; }
- .member > .mic { grid-area: mic; }
- .member > .meter { grid-area: meter; }
- .member > .mod-actions { grid-area: acts; }
+ .member > .badge { grid-area: badge; align-self: start; }
+ .member > .handle { grid-area: handle; }
+ .member > .pub-short { grid-area: pub; }
+ .member > .mic { grid-area: mic; }
+ .member > .stream-toggle { grid-area: strm; justify-self: center; }
+ .member > .meter { grid-area: meter; }
+ .member > .mod-actions { grid-area: acts; }
+ /* single-char stream toggle: ○ when off, ◉ when on. Keep the button
+ * compact so it fits the 1.4rem column without forcing the row taller. */
+ .stream-toggle {
+ font-size: 0.95rem; line-height: 1; padding: 0.1rem 0.3rem;
+ background: transparent; border: 1px solid #888; cursor: pointer;
+ color: inherit;
+ }
+ .stream-toggle.on { background: #000; color: #fff; border-color: #000; }
+ html.theme-dark .stream-toggle { border-color: #aaa; }
+ html.theme-dark .stream-toggle.on { background: #fff; color: #000; border-color: #fff; }
.member:last-child { border-bottom: none; }
.badge {
font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
@@ -529,28 +544,27 @@
.raised { color: #b00; font-weight: bold; }
.mic { width: 18px; height: 18px; }
.mic svg { width: 18px; height: 18px; display: block; }
- /* mod-actions is a vertical stack of row-groups. Each row-group is its
- * own horizontal auto-fit grid that wraps inside itself when the panel
- * is too narrow. Separating row-groups gives kick/ban their own line
- * beneath the primary mod actions (stream + role transitions) without
- * collapsing the parent auto-fit (the previous grid-column:1/-1 trick
- * forced the entire parent grid to one column → every button stacked
- * vertically). Grid only — no flex per project rule. */
- .mod-actions {
- display: grid;
- grid-auto-rows: max-content;
- row-gap: 0.2rem;
- margin-top: 0.2rem;
- }
+ /* mod-actions: two block-level row-groups stacked vertically
+ * (.acts-primary, .acts-removal); buttons inside flow as
+ * inline-block so they pack horizontally and naturally wrap to a
+ * second line only when the panel is genuinely too narrow.
+ *
+ * Previous attempts used `repeat(auto-fit, max-content)` per row-
+ * group, but that grid template collapses to one column when no
+ * fixed sizing function is provided — every button ended up on
+ * its own row in a stack. Inline-block + text-flow wrap is the
+ * older, more reliable pattern here and doesn't need flex. */
+ .mod-actions { margin-top: 0.2rem; }
.mod-actions:empty { display: none; }
.acts-primary, .acts-removal {
- display: grid;
- grid-template-columns: repeat(auto-fit, max-content);
- column-gap: 0.3rem;
- row-gap: 0.2rem;
- justify-content: start;
+ display: block;
+ margin-top: 0.2rem;
}
.acts-primary:empty, .acts-removal:empty { display: none; }
+ .acts-primary > button, .acts-removal > button {
+ margin: 0 0.3rem 0.2rem 0;
+ vertical-align: middle;
+ }
/* log lives in its own full-width section beneath the .page grid.
* 240px default, vertical resize handle so the user can drag it
* taller when the chatter outpaces the viewport. */
@@ -4683,8 +4697,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');