index.html (44398B)
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>Bzl - Hives</title> 7 <link rel="stylesheet" href="/styles.css?v=136" /> 8 </head> 9 <body> 10 <div id="bzlSplash" class="bzlSplash"> 11 <div class="bzlSplashFx" aria-hidden="true"></div> 12 <div class="bzlSplashCore"> 13 <div class="bzlSplashRing"></div> 14 <img class="bzlSplashLogo" src="/assets/logobzl.png" alt="Bzl logo" /> 15 <div class="bzlSplashWord">Bzl</div> 16 <div id="bzlSplashTip" class="bzlSplashTag small muted">Loading your hive...</div> 17 <div class="bzlSplashProgress" aria-hidden="true"> 18 <div id="bzlSplashProgressFill" class="bzlSplashProgressFill"></div> 19 </div> 20 <button id="bzlSplashStartBtn" class="primary smallBtn bzlSplashStartBtn hidden" type="button">Click to enter</button> 21 </div> 22 </div> 23 <div class="app"> 24 <button id="showSidebar" class="ghost smallBtn sidebarToggle hidden" type="button" title="Show sidebar">Show</button> 25 <button id="togglePeople" class="ghost smallBtn peopleToggle" type="button" title="Show members list">Members</button> 26 <button id="showRightRack" class="ghost smallBtn rightRackToggle hidden" type="button" title="Show members list">Members</button> 27 <aside class="sidebar"> 28 <div class="sidebarScroll"> 29 <div class="brand"> 30 <div id="instanceTitle" class="logo">Bzl</div> 31 <div id="instanceSubtitle" class="subtitle">Ephemeral hives + chat</div> 32 </div> 33 34 <div class="statusBlock"> 35 <div id="connBadge" class="badge badge-warn">Connecting...</div> 36 <div class="row"> 37 <button id="enableNotifs" class="ghost smallBtn grow" type="button">Enable notifications</button> 38 </div> 39 <div id="notifStatus" class="small muted"></div> 40 <div class="notifOptions"> 41 <label class="checkRow notifCheckRow"> 42 <span>Alert sound (B7)</span> 43 <input id="notifSoundToggle" type="checkbox" /> 44 </label> 45 <label class="checkRow notifCheckRow"> 46 <span>Any new hive</span> 47 <input id="notifNewHiveToggle" type="checkbox" /> 48 </label> 49 <label class="checkRow notifCheckRow"> 50 <span>Replies and pings</span> 51 <input id="notifReplyPingToggle" type="checkbox" /> 52 </label> 53 <label class="checkRow notifCheckRow"> 54 <span>Chats on my hives</span> 55 <input id="notifMyHiveChatsToggle" type="checkbox" /> 56 </label> 57 <label class="checkRow notifCheckRow"> 58 <span>Chats where I posted recently</span> 59 <input id="notifRecentHiveChatsToggle" type="checkbox" /> 60 </label> 61 </div> 62 </div> 63 64 <section id="viewPanel" class="panel"> 65 <div class="panelTitle">View</div> 66 <div class="uiHint">Use layout presets for quick panel setups. Shortcuts: <b>[</b>/<b>]</b> cycle presets, <b>-</b>/<b>=</b> cycle hives/chats in the active panel, <b>R</b> toggles Members list, <b>?</b> opens shortcut help.</div> 67 <label class="checkRow" style="margin-top:8px;"> 68 <span>Rack layout (experimental)</span> 69 <input id="toggleRackLayout" type="checkbox" /> 70 </label> 71 <label style="margin-top:10px;"> 72 <span>Layout preset</span> 73 <select id="layoutPreset"> 74 <option value="discordLike">Discord-like</option> 75 <option value="chat">Chat</option> 76 <option value="browsing">Browsing</option> 77 <option value="maps">Maps</option> 78 <option value="moderation">Moderation</option> 79 <option value="focus">Focus</option> 80 <option value="clean">Clean</option> 81 <option value="ops">Ops</option> 82 </select> 83 </label> 84 <label class="checkRow" style="margin-top:8px;"> 85 <span>Side panels</span> 86 <input id="toggleSideRack" type="checkbox" checked /> 87 </label> 88 <label class="checkRow" style="margin-top:8px;"> 89 <span>Members list</span> 90 <input id="toggleRightRack" type="checkbox" checked /> 91 </label> 92 <label class="checkRow" style="margin-top:8px;"> 93 <span>Show reactions bar</span> 94 <input id="toggleReactions" type="checkbox" /> 95 </label> 96 <label class="checkRow" style="margin-top:8px;"> 97 <span>Stay connected</span> 98 <input id="stayConnected" type="checkbox" /> 99 </label> 100 <label class="checkRow" style="margin-top:8px;"> 101 <span>Enable hints</span> 102 <input id="enableHints" type="checkbox" /> 103 </label> 104 <label style="margin-top:10px;"> 105 <span>Chat send key</span> 106 <select id="chatEnterMode"> 107 <option value="ctrlEnter">Ctrl/Cmd + Enter sends</option> 108 <option value="enter">Enter sends (Shift+Enter newline)</option> 109 </select> 110 </label> 111 <div class="row" style="margin-top:8px; gap:8px; flex-wrap:wrap;"> 112 <button id="openShortcutHelp" class="ghost smallBtn" type="button">Shortcut help</button> 113 <button id="resetCurrentLayout" class="ghost smallBtn" type="button">Reset layout</button> 114 </div> 115 116 <details style="margin-top:10px;"> 117 <summary class="small muted" style="cursor:pointer;user-select:none;">Advanced display</summary> 118 <div style="margin-top:10px;"> 119 <label> 120 <span>Text size</span> 121 <select id="uiScale"> 122 <option value="auto" selected>Auto</option> 123 <option value="xs">Compact</option> 124 <option value="sm">Small</option> 125 <option value="md">Default</option> 126 <option value="lg">Large</option> 127 </select> 128 </label> 129 <div class="appearanceWorkbench"> 130 <div class="appearanceWorkbenchHeader"> 131 <div class="small">Look & feel</div> 132 <div class="small muted">Personal (this browser)</div> 133 </div> 134 <div class="appearanceWorkbenchRow"> 135 <label class="grow"> 136 <span>Theme preset</span> 137 <select id="appearancePreset"> 138 <option value="">(choose...)</option> 139 </select> 140 </label> 141 <div class="row" style="align-items:flex-end;gap:8px;"> 142 <button id="appearanceApplyPreset" class="ghost smallBtn" type="button">Apply</button> 143 <button id="appearanceResetPreview" class="ghost smallBtn" type="button">Reset</button> 144 </div> 145 </div> 146 <div class="appearanceColorGrid"> 147 <label> 148 <span>Background</span> 149 <input id="appearanceBg" type="color" /> 150 </label> 151 <label> 152 <span>Panel</span> 153 <input id="appearancePanel" type="color" /> 154 </label> 155 <label> 156 <span>Text</span> 157 <input id="appearanceText" type="color" /> 158 </label> 159 <label> 160 <span>Accent</span> 161 <input id="appearanceAccent" type="color" /> 162 </label> 163 <label> 164 <span>Accent 2</span> 165 <input id="appearanceAccent2" type="color" /> 166 </label> 167 <label> 168 <span>Success</span> 169 <input id="appearanceGood" type="color" /> 170 </label> 171 <label> 172 <span>Danger</span> 173 <input id="appearanceBad" type="color" /> 174 </label> 175 </div> 176 <div class="appearanceWorkbenchRow"> 177 <label> 178 <span>Muted %</span> 179 <input id="appearanceMutedPct" type="number" min="0" max="100" /> 180 </label> 181 <label> 182 <span>Divider %</span> 183 <input id="appearanceLinePct" type="number" min="0" max="100" /> 184 </label> 185 <label> 186 <span>Panel tint %</span> 187 <input id="appearancePanel2Pct" type="number" min="0" max="100" /> 188 </label> 189 </div> 190 <div class="appearanceWorkbenchRow"> 191 <label class="grow"> 192 <span>Body font</span> 193 <select id="appearanceFontBody"> 194 <option value="system">System (sans)</option> 195 <option value="clean">Clean sans</option> 196 <option value="humanist">Humanist</option> 197 <option value="rounded">Rounded</option> 198 <option value="condensed">Condensed</option> 199 <option value="serif">Serif</option> 200 <option value="slab">Slab serif</option> 201 <option value="mono">Monospace</option> 202 <option value="lcd">LCD / Digital</option> 203 </select> 204 </label> 205 <label class="grow"> 206 <span>Mono font</span> 207 <select id="appearanceFontMono"> 208 <option value="mono">Monospace</option> 209 <option value="system">System</option> 210 <option value="clean">Clean sans</option> 211 <option value="humanist">Humanist</option> 212 <option value="rounded">Rounded</option> 213 <option value="lcd">LCD / Digital</option> 214 </select> 215 </label> 216 </div> 217 <div class="appearanceWorkbenchActions"> 218 <button id="appearanceSave" class="primary smallBtn" type="button">Save look</button> 219 <button id="appearanceClear" class="ghost smallBtn" type="button">Use server default</button> 220 </div> 221 <div id="appearanceStatus" class="small muted"></div> 222 </div> 223 </div> 224 </details> 225 </section> 226 227 <section id="accountPanel" class="panel"> 228 <div class="panelTitle">Account</div> 229 <div class="small muted" id="authHint">Sign in to post, chat, and boost.</div> 230 <div class="uiHint">New here: create an account, then open a hive and tap <b>Chat</b> to join a conversation.</div> 231 232 <div class="small muted">Signed in as</div> 233 <div id="userLabel" class="userLine">Signed out</div> 234 235 <form id="authForm" class="form"> 236 <label> 237 <span>Username</span> 238 <input id="authUser" autocomplete="username" /> 239 </label> 240 <label> 241 <span>Password</span> 242 <input id="authPass" type="password" autocomplete="current-password" /> 243 </label> 244 <label id="codeRow" class="hidden"> 245 <span>Registration code</span> 246 <input id="authCode" autocomplete="one-time-code" /> 247 </label> 248 <div class="row"> 249 <button class="primary grow" type="submit">Sign in</button> 250 <button id="registerBtn" class="ghost" type="button">Create account</button> 251 </div> 252 <button id="tourBtn" class="ghost" type="button">Tour</button> 253 <button id="logoutBtn" class="ghost hidden" type="button">Sign out</button> 254 <div class="small muted"> 255 Note: this is a prototype; don't reuse important passwords. 256 </div> 257 </form> 258 <div id="onboardingCard" class="onboardingCard hidden"> 259 <div class="panelTitle">Onboarding</div> 260 <div id="onboardingBody" class="small muted"></div> 261 <div class="row" style="margin-top:8px;"> 262 <button id="onboardingAccept" class="primary grow hidden" type="button">Accept and continue</button> 263 <button id="onboardingRefresh" class="ghost" type="button">Refresh</button> 264 </div> 265 </div> 266 </section> 267 268 <section id="profilePanel" class="panel"> 269 <div class="panelTitle">Profile</div> 270 <div class="small muted">Set how your name appears.</div> 271 <div class="uiHint">Your profile card appears in People and when someone opens your profile from a post or chat.</div> 272 <label> 273 <span>Profile picture</span> 274 <input id="profileImage" type="file" accept="image/*" /> 275 </label> 276 <div class="row"> 277 <div class="pfpBox"> 278 <img id="profilePreview" alt="Profile preview" /> 279 </div> 280 <div class="grow"> 281 <label> 282 <span>Color</span> 283 <input id="nameColor" type="color" value="#ff3ea5" /> 284 </label> 285 <button id="removeProfileImage" class="ghost" type="button">Remove picture</button> 286 </div> 287 </div> 288 <button id="saveProfile" class="primary" type="button">Save profile</button> 289 <div id="profileStatus" class="small muted"></div> 290 </section> 291 292 </div> 293 294 <div class="sidebarFooter"> 295 <a 296 id="poweredByTileLink" 297 class="poweredByTile" 298 aria-label="Powered by Bzl" 299 href="https://bzl.one" 300 target="_blank" 301 rel="noopener noreferrer" 302 title="Visit bzl.one" 303 > 304 <img class="poweredByLogo" src="/assets/logobzl.png" alt="Bzl logo" /> 305 <div class="poweredByText"> 306 <div class="poweredByTitle">Powered by Bzl</div> 307 <div class="poweredByByline">by Azakaela Erin Redfire</div> 308 <div class="poweredByVersion" id="poweredByVersion"></div> 309 </div> 310 </a> 311 <button id="toggleSidebar" class="ghost smallBtn" type="button" title="Hide sidebar">Hide</button> 312 </div> 313 </aside> 314 315 <div id="sidebarResizeHandle" class="panelResizeHandle sidebarResizeHandle" title="Drag to resize sidebar" aria-hidden="true"></div> 316 317 <main class="main"> 318 <div id="mainRack" class="mainRack"> 319 <button id="showSideRack" class="ghost smallBtn sideRackToggle hidden" type="button" title="Show side panels">Side</button> 320 <div id="mainWorkspaceRack" class="workspaceRack" aria-label="Workspace"> 321 <section id="hivesPanel" class="panel panelFill"> 322 <div class="panelHeader"> 323 <div class="panelTitle">Hives</div> 324 <div class="filters"> 325 <input id="filterAuthor" placeholder="Filter by author (@name)" /> 326 <input id="filterKeywords" placeholder="Filter by keywords (comma separated)" /> 327 <select id="sortBy"> 328 <option value="activity">Most recent activity</option> 329 <option value="popular">Most popular</option> 330 <option value="expiring">About to expire</option> 331 </select> 332 <button id="mobileHiveSearch" class="ghost smallBtn mobileOnlyHiveControl" type="button" title="Search hives">🔎</button> 333 <button id="mobileSortCycle" class="ghost smallBtn mobileOnlyHiveControl" type="button" title="Cycle sort">Recent</button> 334 <button id="clearFilter" type="button">Clear</button> 335 <button id="toggleComposer" class="mobileComposerToggle" type="button">New Hive</button> 336 </div> 337 </div> 338 <div class="uiHint">Use filters to narrow posts, then tap <b>Chat</b> on a hive card. Cards now show latest chat/typing. Shortcut: <b>-</b>/<b>=</b> cycles collections/views.</div> 339 <div id="onboardingGateHint" class="onboardingGateHint hidden"></div> 340 <div class="hiveTabs" id="hiveTabs"> 341 <button type="button" data-hiveview="all" class="primary">All</button> 342 <button type="button" data-hiveview="starred" class="ghost">Starred</button> 343 <button type="button" data-hiveview="hidden" class="ghost">Hidden</button> 344 </div> 345 <div id="feed" class="feed"></div> 346 </section> 347 348 <section id="onboardingPanel" class="panel panelFill hidden"> 349 <div class="panelHeader"> 350 <div> 351 <div class="panelTitle">Onboarding</div> 352 <div class="small muted">About, rules, and first steps.</div> 353 </div> 354 </div> 355 <div class="panelBody onboardingPanelBody"> 356 <div class="uiHint">Read About and Rules first. If required, accept rules to unlock posting and chat.</div> 357 <div id="onboardingPanelBody" class="small muted"></div> 358 <div class="row" style="margin-top:10px;"> 359 <button id="onboardingPanelAccept" class="primary grow hidden" type="button">Accept and continue</button> 360 <button id="onboardingPanelRefresh" class="ghost" type="button">Refresh</button> 361 </div> 362 </div> 363 </section> 364 365 <section id="profileViewPanel" class="panel panelFill hidden"> 366 <div class="panelHeader"> 367 <div> 368 <div class="panelTitle" id="profileViewTitle">Profile</div> 369 <div id="profileViewMeta" class="small muted"></div> 370 </div> 371 <div class="row"> 372 <button id="profileBackBtn" class="ghost smallBtn" type="button">Back to hives</button> 373 <button id="profileEditToggleBtn" class="ghost smallBtn hidden" type="button">Edit profile</button> 374 </div> 375 </div> 376 <div class="uiHint">Tip: open someone from People, a hive card, or a chat message to view their profile here.</div> 377 <div id="profileViewBody" class="profileViewBody"> 378 <div id="profileCard" class="profileCard"></div> 379 </div> 380 <div id="profileEditPanel" class="profileEditPanel hidden"> 381 <label> 382 <span>Pronouns</span> 383 <input id="profilePronouns" maxlength="40" placeholder="she/her, they/them, etc" /> 384 </label> 385 <label> 386 <span>Theme song</span> 387 <div class="row"> 388 <input id="profileThemeSongUrl" placeholder="Upload audio for your theme song" readonly /> 389 <button id="profileThemeSongUploadBtn" class="ghost" type="button">Upload audio</button> 390 <button id="profileThemeSongClearBtn" class="ghost" type="button">Remove</button> 391 </div> 392 <audio id="profileThemeSongPreview" controls preload="none" class="hidden"></audio> 393 <input id="profileThemeSongFile" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 394 </label> 395 <div class="editorShell"> 396 <div class="toolbar" id="profileBioToolbar" role="toolbar" aria-label="Profile bio formatting"> 397 <button type="button" data-profilecmd="bold"><b>B</b></button> 398 <button type="button" data-profilecmd="italic"><i>I</i></button> 399 <button type="button" data-profilecmd="underline"><u>U</u></button> 400 <button type="button" data-profilecmd="strikeThrough"><s>S</s></button> 401 <span class="sep"></span> 402 <button type="button" data-profilecmd="insertUnorderedList">List</button> 403 <button type="button" data-profilecmd="insertOrderedList">1. List</button> 404 <button type="button" data-profilelink="1">Link</button> 405 <button type="button" data-profileimg="1">GIF/Image</button> 406 <button type="button" data-profileaudio="1">Audio</button> 407 <button type="button" data-profileemoji="1">Emoji</button> 408 <button type="button" data-profilecmd="removeFormat">Clear</button> 409 </div> 410 <div id="profileBioEditor" class="editor profileBioEditor" contenteditable="true" aria-label="Profile bio editor"></div> 411 <input id="profileBioImageFile" class="hidden" type="file" accept="image/*,.gif" /> 412 <input id="profileBioAudioFile" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 413 </div> 414 <div class="profileLinksHead"> 415 <span>Social links</span> 416 <button id="profileAddLinkBtn" class="ghost smallBtn" type="button">Add link</button> 417 </div> 418 <div id="profileLinksEditor" class="profileLinksEditor"></div> 419 <div class="row"> 420 <button id="profileSaveBtn" class="primary" type="button">Save profile</button> 421 <button id="profileCancelBtn" class="ghost" type="button">Cancel</button> 422 </div> 423 </div> 424 </section> 425 426 <section id="pollinatePanel" class="panel composerCollapsed"> 427 <div class="panelHeader"> 428 <div class="panelTitle">Create Hive</div> 429 <button id="toggleComposerInline" class="ghost smallBtn" type="button">Hide</button> 430 </div> 431 <div class="uiHint">Keep titles short and clear. Add keywords so others can find your hive faster.</div> 432 <form id="newPostForm" class="form"> 433 <label> 434 <span>Title (max 96 chars)</span> 435 <input id="postTitle" maxlength="96" placeholder="Short title for this hive" /> 436 </label> 437 <div class="editorShell"> 438 <div class="toolbar" role="toolbar" aria-label="Formatting"> 439 <button type="button" data-cmd="bold"><b>B</b></button> 440 <button type="button" data-cmd="italic"><i>I</i></button> 441 <button type="button" data-cmd="underline"><u>U</u></button> 442 <button type="button" data-cmd="strikeThrough"><s>S</s></button> 443 <span class="sep"></span> 444 <button type="button" data-cmd="insertUnorderedList">List</button> 445 <button type="button" data-cmd="insertOrderedList">1. List</button> 446 <button type="button" data-link="1">Link</button> 447 <button type="button" data-postimg="1">GIF/Image</button> 448 <button type="button" data-postaudio="1">Audio</button> 449 <button type="button" data-postemoji="1">Emoji</button> 450 <button type="button" data-cmd="removeFormat">Clear</button> 451 </div> 452 <div id="editor" class="editor" contenteditable="true" aria-label="Post editor"></div> 453 <input id="postImage" class="hidden" type="file" accept="image/*,.gif" /> 454 <input id="postAudio" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 455 </div> 456 457 <div class="row"> 458 <label class="grow"> 459 <span>Collection</span> 460 <select id="postCollection"></select> 461 </label> 462 <label class="grow"> 463 <span>Keywords (comma separated, up to 6)</span> 464 <input id="keywords" placeholder="hive, code, idea" /> 465 </label> 466 <label> 467 <span>Post duration</span> 468 <input id="ttlMinutes" type="number" min="1" max="2880" value="60" /> 469 </label> 470 <label> 471 <span>Quick duration</span> 472 <select id="ttlPreset"> 473 <option value="5">5 min</option> 474 <option value="30">30 min</option> 475 <option value="60" selected>1 hour</option> 476 <option value="120">2 hours</option> 477 <option value="720">12 hours</option> 478 <option value="1440">24 hours</option> 479 </select> 480 </label> 481 <label class="checkRow"> 482 <span>Keep forever</span> 483 <input id="ttlPermanent" type="checkbox" /> 484 </label> 485 </div> 486 487 <button class="primary" type="submit">Send</button> 488 <div class="row"> 489 <label class="grow"> 490 <span>Protected</span> 491 <input id="isProtected" type="checkbox" /> 492 </label> 493 <label class="grow"> 494 <span>Hive mode</span> 495 <select id="postMode"> 496 <option value="text" selected>Text</option> 497 <option value="walkie">Walkie Talkie</option> 498 <option value="stream">Stream</option> 499 </select> 500 </label> 501 <label id="streamKindRow" class="grow hidden"> 502 <span>Stream type</span> 503 <select id="streamKind"> 504 <option value="screen">Screen share</option> 505 <option value="webcam" selected>Webcam</option> 506 <option value="audio">Audio only</option> 507 </select> 508 </label> 509 <label class="grow"> 510 <span>Post password</span> 511 <input id="postPassword" type="password" autocomplete="new-password" placeholder="Required if protected" disabled /> 512 </label> 513 </div> 514 </form> 515 </section> 516 </div> 517 <div id="mainSideRack" class="sideRack" aria-label="Side panels"></div> 518 </div> 519 </main> 520 521 <div id="chatResizeHandle" class="panelResizeHandle chatResizeHandle" title="Drag to resize chat" aria-hidden="true"></div> 522 523 <aside class="chat"> 524 <div class="panelHeader"> 525 <div> 526 <div class="panelTitle" id="chatTitle">Chat</div> 527 <div id="chatMeta" class="small muted">Select a post to chat.</div> 528 </div> 529 <div class="row chatHeaderActions"> 530 <select id="chatContextSelect" class="chatContextSelect" aria-label="Open chats"></select> 531 <button id="chatBackToList" class="ghost smallBtn hidden" type="button">Back</button> 532 </div> 533 </div> 534 <div class="uiHint">Select a hive chat or DM first, then type your message and press Send. Shortcut in Chat: <b>-</b>/<b>=</b> cycles chat list entries.</div> 535 <section id="streamStage" class="streamStage hidden" aria-label="Live stream stage"> 536 <div class="streamStageHeader"> 537 <div id="streamStageTitle" class="streamStageTitle">Stream</div> 538 <button id="streamStagePrimary" class="ghost smallBtn" type="button">Join stream</button> 539 </div> 540 <div id="streamStageStatus" class="small muted">Stream is offline.</div> 541 <div id="streamVoiceControls" class="streamVoiceControls hidden" aria-label="Voice controls"> 542 <label class="checkRow streamVoiceToggleRow"> 543 <span>Join voice</span> 544 <input id="streamVoiceJoinToggle" type="checkbox" /> 545 </label> 546 <div class="row streamVoiceButtonsRow"> 547 <button id="streamVoiceMuteBtn" class="ghost smallBtn" type="button">Mute mic</button> 548 <button id="streamVoiceDeafenBtn" class="ghost smallBtn" type="button">Deafen</button> 549 </div> 550 <div id="streamVoiceUsers" class="streamVoiceUsers small muted"></div> 551 </div> 552 <video id="streamStageVideo" class="streamStageVideo hidden" playsinline autoplay controls muted></video> 553 <audio id="streamStageAudio" class="streamStageAudio hidden" autoplay controls></audio> 554 <div id="streamStagePlaceholder" class="streamStagePlaceholder small muted">Open a stream hive to watch, or start a stream if you own the post.</div> 555 </section> 556 <div id="chatMessages" class="chatMessages"></div> 557 <div id="typingIndicator" class="typingIndicator small muted"></div> 558 <div id="walkieBar" class="walkieBar hidden" aria-label="Walkie talkie controls"> 559 <button id="walkieRecordBtn" class="primary" type="button">Hold to talk</button> 560 <div class="walkieHint small muted"> 561 Hold <span class="tag">~</span> or press-and-hold this button to record. Release to send. 562 </div> 563 <div id="walkieStatus" class="small muted"></div> 564 </div> 565 <form id="chatForm" class="chatForm"> 566 <div id="chatReplyBanner" class="chatReplyBanner hidden"> 567 <div class="small"> 568 Replying to <span id="chatReplyWho"></span> 569 <span id="chatReplyText" class="muted"></span> 570 </div> 571 <button id="chatReplyCancel" class="ghost smallBtn" type="button">Cancel</button> 572 </div> 573 <div class="chatComposer"> 574 <div class="toolbar" role="toolbar" aria-label="Chat formatting"> 575 <button type="button" data-chatcmd="bold"><b>B</b></button> 576 <button type="button" data-chatcmd="italic"><i>I</i></button> 577 <button type="button" data-chatcmd="underline"><u>U</u></button> 578 <button type="button" data-chatcmd="strikeThrough"><s>S</s></button> 579 <span class="sep"></span> 580 <button type="button" data-chatcmd="insertUnorderedList">List</button> 581 <button type="button" data-chatcmd="insertOrderedList">1. List</button> 582 <button type="button" data-chatlink="1">Link</button> 583 <button type="button" data-chatimg="1">GIF/Image</button> 584 <button type="button" data-chataudio="1">Audio</button> 585 <button type="button" data-chatemoji="1">Emoji</button> 586 <button type="button" data-chatcmd="removeFormat">Clear</button> 587 <label id="chatModToggleWrap" class="checkRow chatModToggle hidden" title="Send as moderator/system message (left rail)"> 588 <span>Mod</span> 589 <input id="chatModToggle" type="checkbox" /> 590 </label> 591 </div> 592 <div id="chatEditor" class="editor chatEditor" contenteditable="true" aria-label="Chat editor"></div> 593 <div id="mentionMenu" class="mentionMenu hidden" role="listbox" aria-label="Mention suggestions"></div> 594 <input id="chatImage" class="hidden" type="file" accept="image/*" /> 595 <input id="chatAudio" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 596 </div> 597 <div class="uiHint">Use Link, GIF/Image, and Audio to attach media quickly.</div> 598 <button class="primary" type="submit">Send</button> 599 </form> 600 </aside> 601 602 <div id="mainResizeHandle" class="panelResizeHandle mainResizeHandle" title="Drag to resize moderation panel" aria-hidden="true"></div> 603 604 <aside id="modPanel" class="moderation hidden"> 605 <div class="panelHeader"> 606 <div class="panelTitle">Moderation</div> 607 </div> 608 <div class="uiHint">Use tabs to review reports, manage users/hives, configure server settings, and publish onboarding content.</div> 609 <div class="modTabs"> 610 <button type="button" class="ghost" data-modtab="reports">Reports</button> 611 <button type="button" class="ghost" data-modtab="users">Users</button> 612 <button type="button" class="ghost" data-modtab="hives">Hives</button> 613 <button type="button" class="ghost" data-modtab="server">Server</button> 614 <button type="button" class="ghost" data-modtab="onboarding">Onboarding</button> 615 <button type="button" class="ghost" data-modtab="log">Log</button> 616 </div> 617 <div class="modFilters"> 618 <select id="modReportStatus"> 619 <option value="open">Open reports</option> 620 <option value="resolved">Resolved reports</option> 621 <option value="dismissed">Dismissed reports</option> 622 <option value="">All reports</option> 623 </select> 624 <button id="modRefresh" class="ghost" type="button">Refresh</button> 625 </div> 626 <div id="modBody" class="modBody small"></div> 627 </aside> 628 629 <div id="mobileScreenHost" class="mobileScreenHost" aria-label="Mobile screen host"></div> 630 </div> 631 <aside id="peopleDrawer" class="peopleDrawer hidden"> 632 <div id="peopleResizeHandle" class="peopleResizeHandle" title="Drag to resize people panel" aria-hidden="true"></div> 633 <div class="panelHeader"> 634 <div class="panelTitle">Members list</div> 635 <button id="closePeople" class="ghost smallBtn" type="button">Close</button> 636 </div> 637 <div class="peopleTabs"> 638 <button id="peopleMembersTab" class="primary" type="button">Members</button> 639 <button id="peopleDmsTab" class="ghost" type="button">DMs</button> 640 </div> 641 <div id="peopleMembersView"> 642 <div class="uiHint">Members list lets you open profiles and start DMs. Mods can also send <b>Mod DM</b> from member/profile actions.</div> 643 <div class="peopleFilters"> 644 <input id="peopleSearch" placeholder="Search members" /> 645 </div> 646 <div id="peopleList" class="peopleList small"></div> 647 </div> 648 <div id="peopleDmsView" class="peopleDms small hidden"> 649 <div class="uiHint">DM requests must be accepted before chat opens. Active threads show <b>Open</b>, and mods get a <b>Mod DM</b> action.</div> 650 DMs coming soon. 651 </div> 652 </aside> 653 <div id="mobileNav" class="mobileNav hidden" aria-label="Mobile navigation"> 654 <button type="button" data-mobilescreen="account">Account</button> 655 <button type="button" data-mobilescreen="hives">Hives</button> 656 <button type="button" data-mobilescreen="chat">Chat</button> 657 <button id="mobileFourthBtn" type="button" data-mobilescreen="people">Members</button> 658 <button type="button" data-mobilescreen="profile">Profile</button> 659 <button type="button" data-mobilescreen="more">More</button> 660 </div> 661 662 <div id="mobileMoreSheet" class="mobileMoreSheet hidden" role="dialog" aria-modal="true" aria-label="More"> 663 <div class="mobileMoreBackdrop" data-mobilemoreclose="1"></div> 664 <div class="mobileMoreCard panel"> 665 <div class="panelHeader"> 666 <div class="panelTitle">More</div> 667 <div class="row"> 668 <button id="mobileMoreClose" class="ghost smallBtn" type="button">Close</button> 669 </div> 670 </div> 671 <div class="mobileMoreBody"> 672 <input id="mobileMoreSearch" placeholder="Search…" /> 673 <div id="mobileMoreList" class="mobileMoreList"></div> 674 </div> 675 </div> 676 </div> 677 678 <div id="editModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Edit content"> 679 <div class="modalBackdrop" data-modalclose="1"></div> 680 <div class="modalCard panel"> 681 <div class="panelHeader"> 682 <div class="panelTitle" id="editModalTitle">Edit</div> 683 <div class="row"> 684 <button id="editModalClose" class="ghost smallBtn" type="button">Close</button> 685 </div> 686 </div> 687 <div class="modalBody"> 688 <label id="editModalPostTitleRow" class="hidden"> 689 <span>Title</span> 690 <input id="editModalPostTitle" maxlength="96" /> 691 </label> 692 693 <div id="editModalPostMeta" class="hidden editMetaGrid" aria-label="Post settings"> 694 <label> 695 <span>Keywords</span> 696 <input id="editModalKeywords" maxlength="120" placeholder="comma separated (max 6)" /> 697 </label> 698 <label> 699 <span>Collection</span> 700 <select id="editModalCollection"></select> 701 </label> 702 <label class="checkRow"> 703 <span>Password protected</span> 704 <input id="editModalProtected" type="checkbox" /> 705 </label> 706 <label> 707 <span>Mode</span> 708 <select id="editModalMode"> 709 <option value="text" selected>Text</option> 710 <option value="walkie">Walkie Talkie</option> 711 <option value="stream">Stream</option> 712 </select> 713 </label> 714 <label id="editModalStreamKindRow" class="hidden"> 715 <span>Stream type</span> 716 <select id="editModalStreamKind"> 717 <option value="screen">Screen share</option> 718 <option value="webcam" selected>Webcam</option> 719 <option value="audio">Audio only</option> 720 </select> 721 </label> 722 <label id="editModalPasswordRow" class="hidden"> 723 <span>Password</span> 724 <input 725 id="editModalPassword" 726 type="password" 727 minlength="4" 728 maxlength="80" 729 placeholder="Leave blank to keep current" 730 autocomplete="new-password" 731 /> 732 </label> 733 </div> 734 735 <div class="editorShell"> 736 <div class="toolbar" id="editModalToolbar" role="toolbar" aria-label="Edit formatting"> 737 <button type="button" data-editcmd="bold"><b>B</b></button> 738 <button type="button" data-editcmd="italic"><i>I</i></button> 739 <button type="button" data-editcmd="underline"><u>U</u></button> 740 <button type="button" data-editcmd="strikeThrough"><s>S</s></button> 741 <span class="sep"></span> 742 <button type="button" data-editcmd="insertUnorderedList">List</button> 743 <button type="button" data-editcmd="insertOrderedList">1. List</button> 744 <button type="button" data-editlink="1">Link</button> 745 <button type="button" data-editimg="1">GIF/Image</button> 746 <button type="button" data-editaudio="1">Audio</button> 747 <button type="button" data-editemoji="1">Emoji</button> 748 <button type="button" data-editcmd="removeFormat">Clear</button> 749 </div> 750 <div id="editModalEditor" class="editor editModalEditor" contenteditable="true" aria-label="Edit content"></div> 751 <input id="editModalImage" class="hidden" type="file" accept="image/*,.gif" /> 752 <input id="editModalAudio" class="hidden" type="file" accept="audio/*,.mp3,.wav,.ogg,.m4a,.webm" /> 753 </div> 754 755 <div class="row modalActions"> 756 <button id="editModalSave" class="primary" type="button">Save</button> 757 <button id="editModalCancel" class="ghost" type="button">Cancel</button> 758 </div> 759 <div id="editModalStatus" class="small muted"></div> 760 </div> 761 </div> 762 </div> 763 764 <div id="modModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Moderation"> 765 <div class="modalBackdrop" data-modmodalclose="1"></div> 766 <div class="modalCard panel"> 767 <div class="panelHeader"> 768 <div class="panelTitle" id="modModalTitle">Moderation</div> 769 <div class="row"> 770 <button id="modModalClose" class="ghost smallBtn" type="button">Close</button> 771 </div> 772 </div> 773 <div class="modalBody" id="modModalBody"></div> 774 <div class="row modalActions"> 775 <button id="modModalPrimary" class="primary" type="button">Save</button> 776 <button id="modModalCancel" class="ghost" type="button">Cancel</button> 777 </div> 778 <div id="modModalStatus" class="small muted" style="padding:0 12px 12px"></div> 779 </div> 780 </div> 781 782 <div id="mediaModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Media preview"> 783 <div class="modalBackdrop" data-mediamodalclose="1"></div> 784 <div class="modalCard panel"> 785 <div class="panelHeader"> 786 <div class="panelTitle" id="mediaModalTitle">Media</div> 787 <div class="row"> 788 <button id="mediaModalClose" class="ghost smallBtn" type="button">Close</button> 789 </div> 790 </div> 791 <div class="modalBody" id="mediaModalBody"> 792 <img id="mediaModalImg" alt="Expanded media" /> 793 <div class="row modalActions" style="justify-content:flex-start"> 794 <a id="mediaModalOpenLink" class="ghost" href="#" target="_blank" rel="noreferrer">Open original</a> 795 <button id="mediaModalCopyLink" class="ghost" type="button">Copy link</button> 796 </div> 797 <div id="mediaModalStatus" class="small muted"></div> 798 </div> 799 </div> 800 </div> 801 802 <div id="shortcutHelpModal" class="modal hidden" role="dialog" aria-modal="true" aria-label="Keyboard shortcuts"> 803 <div class="modalBackdrop" data-shortcutclose="1"></div> 804 <div class="modalCard panel"> 805 <div class="panelHeader"> 806 <div class="panelTitle">Keyboard Shortcuts</div> 807 <div class="row"> 808 <button id="shortcutHelpClose" class="ghost smallBtn" type="button">Close</button> 809 </div> 810 </div> 811 <div class="modalBody shortcutHelpBody"> 812 <div><span class="tag">[ / ]</span> Cycle layout presets</div> 813 <div><span class="tag">- / =</span> Cycle hives or chats in active panel</div> 814 <div><span class="tag">Arrows</span> Hover panel: Up size, Left/Right move, Down dock. Hover hotbar: Up restore.</div> 815 <div><span class="tag">R</span> Toggle Members list rail</div> 816 <div><span class="tag">?</span> Open this shortcut help</div> 817 <div><span class="tag">`</span> Hold for walkie talkie (when enabled)</div> 818 <div><span class="tag">Esc</span> Close menus/modals</div> 819 </div> 820 </div> 821 </div> 822 823 <div id="dockHotbar" class="dockHotbar hidden" aria-label="Docked panels"></div> 824 <div id="authGate" class="authGate hidden" aria-hidden="true"> 825 <div class="authGateInner"> 826 <section class="authGateCard"> 827 <div class="panelTitle">Sign in to continue</div> 828 <div id="authGateHint" class="small muted"> 829 Create an account or sign in to enter this server. 830 </div> 831 <form id="authGateForm" class="form authGateForm"> 832 <label> 833 <span>Username</span> 834 <input id="authGateUser" autocomplete="username" /> 835 </label> 836 <label> 837 <span>Password</span> 838 <input id="authGatePass" type="password" autocomplete="current-password" /> 839 </label> 840 <label id="authGateCodeRow" class="hidden"> 841 <span>Registration code</span> 842 <input id="authGateCode" autocomplete="one-time-code" /> 843 </label> 844 <div class="row"> 845 <button class="primary grow" type="submit">Sign in</button> 846 <button id="authGateRegister" class="ghost" type="button">Create account</button> 847 </div> 848 </form> 849 </section> 850 <section class="authGateOnboarding"> 851 <div class="panelTitle">Server onboarding</div> 852 <div class="small muted">Read About and Rules before entering.</div> 853 <div class="row" style="margin-top:8px;gap:8px;flex-wrap:wrap;"> 854 <button type="button" class="primary smallBtn" data-authgate-tab="about">About</button> 855 <button type="button" class="ghost smallBtn" data-authgate-tab="rules">Rules</button> 856 <button type="button" class="ghost smallBtn" data-authgate-tab="roles">Roles</button> 857 </div> 858 <div id="authGateOnboardingBody" class="small muted" style="margin-top:8px;"></div> 859 <div class="row" style="margin-top:10px;"> 860 <button id="authGateAccept" class="primary grow hidden" type="button">Accept rules and continue</button> 861 <button id="authGateRefresh" class="ghost" type="button">Refresh</button> 862 </div> 863 </section> 864 </div> 865 </div> 866 <script src="/app.js?v=158"></script> 867 </body> 868 </html>