<!-- SOLUV · part 462 -->
(--sr-wax); border-color:var(--sr-wax-dark); color:#fff; min-width:72px; }
.sr-mic[aria-pressed="true"]{ background:var(--sr-bad); border-color:#fff; }
.sr-foot{ display:flex; flex-wrap:wrap; gap:4px 12px; justify-content:space-between; margin-top:6px;
  font-size:15px; color:#bfb39d; }
.sr-count[data-over="1"]{ color:#ff8a80; font-weight:700; }

@media (prefers-reduced-motion: reduce){
  .sr-letter.sr-opening .sr-fold, .sr-letter.sr-opening .sr-seal::before, .sr-letter.sr-opening .sr-seal::after{ animation:none; }
}

/* ===================== DENSE LAYOUT (opt-in: mount(el,{dense:true}) / room.html?dense=1) =====================
   Most words per screen: edge-to-edge text, inline speaker tags, condensed tall-x-height face,
   one thin fixed control bar. Font: Roboto Condensed (SIL OFL 1.1), bundled in /soluv/fonts — no CDN. */
@font-face{ font-family:"Soluv Condensed"; src:url("fonts/RobotoCondensed-var.woff2") format("woff2");
  font-weight:100 900; font-style:normal; font-display:swap; }
.sr-dense{ font-family:"Soluv Condensed","Roboto Condensed","Arial Narrow",sans-serif; font-size:var(--sr-dfs,15px); }
.sr-dense .sr-list{ display:block; padding:2px 6px 4px; }
.sr-dense .sr-line{ font-size:var(--sr-dfs,15px); line-height:1.3; color:#efe7d6; padding:1px 2px;
  white-space:pre-wrap; overflow-wrap:anywhere; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.sr-dense .sr-line.sr-newspk{ border-top:1px solid #2c2536; padding-top:2px; margin-top:1px; }
.sr-dense .sr-line .sr-text{ font-size:inherit; margin:0; white-space:pre-wrap; }
.sr-dense .sr-tag{ font-weight:700; color:var(--sr-ct,#9cf); margin-right:.3em; white-space:nowrap; }
.sr-dense .sr-king .sr-tag{ color:var(--sr-gold); text-shadow:0 0 6px rgba(231,181,58,.6); }
.sr-dense .sr-line.sr-king .sr-text{ color:#fff3cf; }
.sr-dense .sr-line.sr-mine .sr-text{ color:#ffffff; }
.sr-dense .sr-line.sr-tapped{ background:#2a2333; }
.sr-dense .sr-line.sr-pending .sr-text{ opacity:.6; }
.sr-dense .sr-line.sr-failed .sr-text{ color:#ff9a8f; }
.sr-dense .sr-line .sr-retry{ margin-left:6px; vertical-align:middle; }
.sr-dense .sr-line.sr-fresh{ animation:sr-fade .25s ease-out both; }
@keyframes sr-fade{ from{ opacity:0; } to{ opacity:1; } }

/* Welcome stays as one short sealed block at the top */
.sr-dense .sr-welcome-dense{ margin:14px 4px 6px; padding:24px 10px 6px; box-shadow:none; }  /* clears the seal */
.sr-dense .sr-welcome-dense .sr-text{ font-family:"Soluv Condensed","Roboto Condensed",sans-serif; font-size:var(--sr-dfs,15px); line-height:1.3; }
.sr-dense .sr-welcome-dense .sr-sign{ margin-top:2px; font-size:13px; }
.sr-dense .sr-welcome-dense .sr-seal{ transform:scale(.7); top:-16px; }

/* The one thin fixed bar: status · readout · A− · A+ · ↓, then the composer row. */
.sr-dense .sr-compose{ padding:4px 6px calc(4px + env(safe-area-inset-bottom,0px)); }
.sr-bar{ display:flex; align-items:center; gap:4px; margin-bottom:4px; }
.sr-dense .sr-status{ min-height:48px; padding:0 8px; border-radius:10px; font-size:15px; gap:6px; flex:0 0 auto; }
.sr-read{ flex:1 1 auto; min-width:0; font-size:15px; line-height:1.2; color:#d9cdb6; overflow-wrap:anywhere;
  max-height:36px; overflow:hidden; }
.sr-dense .sr-btn{ padding:0 8px; border-radius:10px; }
.sr-dense .sr-row{ gap:4px; }
.sr-dense .sr-input{ padding:11px 10px; font-family:inherit; font-size:17px; }   /* 17px keeps iOS from zooming on focus */
.sr-dense .sr-send{ min-width:64px; }


===== FILE: public/soluv/room.html =====
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content">
<meta name="theme-color" content="#16121c">
<title>Soluv Room</title>
<link rel="stylesheet" href="/soluv/room.css?v=2">
<style>
  html,body{ margin:0; height:100%; background:#16121c; }
  #soluv-room{ height:100%; }
</style>
</head>
<body>
<!-- Full-screen dense room (the King's word). ?dense=0 shows the letters look. In Solid's /soluv world the room mounts into whatever element he gives it. -->
<div id="soluv-room"></div>
<script src="/soluv/room.js?v=2"></script>
<script>SoluvRoom.mount(document.getElementById('soluv-room'), { fitViewport: true, dense: !/[?&]dense=0\b/.test(location.search) });</script>
</body>
</html>


===== FILE: public/soluv/room.js =====
/* SOLUV ROOM client — Playa. Mount into any element Solid's world provides:
 *   <link rel="stylesheet" href="/soluv/room.css"><script src="/soluv/room.js"></script>
 *   const room = SoluvRoom.mount(document.getElementById('soluv-room'), { fitViewport: false });
 *   room.destroy();
 * Laws kept: phone first, 48px buttons, nothing overlaps/hides/moves, no silent fallbacks
 * (every failure is shown on screen), light on the GPU (no backdrop-filter, no canvas).
 */
(function () {
  'use strict';

  var KING = 'TheEpistolary';
  var MAX_LEN = 2000;
  var WELCOME = [
    'Speak, and the seal breaks.',
    'Every v