:root{
  --paper:#f2efe8; --ink:#1d2026; --dim:#6b7280; --line:#d8d2c6;
  --floor:#e7e2d7; --wall:#c9c2b3; --panel:#fbfaf7;
  --open:#2f9e68; --knock:#cf8a26; --members:#4074c9; --closed:#8b8b8b;
  --you:#d94f3d; --shadow:0 1px 3px rgba(0,0,0,.08),0 8px 24px rgba(0,0,0,.06);
  --peek:54px;          /* collapsed height of the mobile sheet */
  --rail:320px;
}
@media (prefers-color-scheme: dark){
  :root{
    --paper:#12141a; --ink:#e8e6e1; --dim:#8b93a1; --line:#2a2f39;
    --floor:#1a1e26; --wall:#333a46; --panel:#171b22;
    --open:#3fbc80; --knock:#e0a04a; --members:#6b9ae8; --closed:#6a7280;
    --you:#f2705c; --shadow:0 1px 3px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.3);
  }
}
*{box-sizing:border-box}
/* Author rules like .overlay{display:grid} outbid the UA sheet's [hidden] rule,
   so state the intent explicitly rather than relying on it. */
[hidden]{display:none !important}
html,body{height:100%}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font:15px/1.5 ui-sans-serif,system-ui,"Segoe UI",Roboto,"Noto Sans","Noto Sans Arabic",sans-serif;
  display:grid; grid-template-rows:auto 1fr; grid-template-columns:1fr var(--rail);
  grid-template-areas:"bar bar" "stage rail";
  overflow:hidden;
}
button{font:inherit}

/* ---------- join ---------- */
.overlay{position:fixed;inset:0;z-index:50;display:grid;place-items:center;background:var(--paper);
  padding:16px;overflow-y:auto}
.card{width:min(420px,100%);background:var(--panel);border:1px solid var(--line);border-radius:14px;
  padding:clamp(20px,5vw,28px);box-shadow:var(--shadow)}
.card h1{margin:0;font-size:clamp(25px,7vw,30px);letter-spacing:-.5px;font-weight:650}
.card h1 span{font-size:15px;color:var(--dim);font-weight:400;letter-spacing:.14em;margin-inline-start:10px;text-transform:uppercase}
.tag{margin:6px 0 22px;color:var(--dim)}
.seg{display:flex;gap:6px;background:var(--floor);padding:4px;border-radius:9px;margin-bottom:18px}
.seg button{flex:1;border:0;background:transparent;color:var(--dim);padding:10px 8px;border-radius:6px;cursor:pointer}
.seg button.on{background:var(--panel);color:var(--ink);box-shadow:var(--shadow);font-weight:550}
label{display:block;font-size:13px;color:var(--dim);margin-bottom:14px}
/* 16px keeps iOS Safari from zooming the page when a field takes focus. */
input{width:100%;margin-top:5px;padding:11px 12px;font:inherit;font-size:16px;color:var(--ink);
  background:var(--paper);border:1px solid var(--line);border-radius:8px}
input:focus{outline:2px solid var(--members);outline-offset:1px}
.fine{font-size:12.5px;line-height:1.55;color:var(--dim);margin:0 0 18px;
  border-inline-start:2px solid var(--line);padding-inline-start:10px}
.go{width:100%;padding:13px;border:0;border-radius:8px;background:var(--ink);color:var(--paper);
  font-weight:600;cursor:pointer}
.go:hover{opacity:.9}
.err{color:var(--you);font-size:13px;margin:12px 0 0}

/* ---------- bar ---------- */
#bar{grid-area:bar;display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:10px 18px;padding-top:max(10px,env(safe-area-inset-top));
  border-bottom:1px solid var(--line);background:var(--panel);position:relative}
.who{display:flex;align-items:center;gap:9px;font-weight:600;min-width:0}
.who span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chip{font:11px/1 ui-monospace,monospace;text-transform:uppercase;letter-spacing:.08em;
  padding:4px 7px;border-radius:5px;background:var(--floor);color:var(--dim);font-weight:600;flex:none}
.legend{display:flex;align-items:center;gap:14px;font-size:12.5px;color:var(--dim);flex:none}
.legend i{display:inline-block;width:9px;height:9px;border-radius:2px;margin-inline-end:5px}
.k-open{background:var(--open)} .k-knock{background:var(--knock)} .k-members{background:var(--members)}
.legend .hint{padding-inline-start:6px;border-inline-start:1px solid var(--line);opacity:.8}
#offline{position:absolute;inset-inline:0;top:100%;background:var(--you);color:#fff;
  font-size:12.5px;font-weight:600;text-align:center;padding:5px;z-index:20}

/* ---------- floor ---------- */
#stage{grid-area:stage;min-width:0;min-height:0;padding:18px;display:grid;place-items:center;
  position:relative}
#floorWrap{width:100%;max-width:1240px;max-height:100%;display:flex}
#floor{width:100%;height:auto;max-height:100%;display:block;border-radius:12px;box-shadow:var(--shadow);
  touch-action:manipulation}
.rm{fill:var(--floor);stroke:var(--wall);stroke-width:2.5}
.rm.open{stroke:var(--open)} .rm.knock{stroke:var(--knock)}
.rm.members{stroke:var(--members)} .rm.closed{stroke:var(--closed)}
.rm.live{fill:color-mix(in srgb, var(--floor) 82%, currentColor)}
.rlab{font:600 15px ui-sans-serif,system-ui,sans-serif;fill:var(--ink)}
.rsub{font:12px ui-sans-serif,system-ui,sans-serif;fill:var(--dim)}
/* Who is inside, readable from the corridor without entering. */
.rroster{font:500 12px ui-sans-serif,system-ui,sans-serif;fill:var(--ink);opacity:.85}
.rcount{font:600 12px ui-sans-serif,system-ui,sans-serif;fill:var(--dim);letter-spacing:.01em}
.rcount.live{fill:var(--ink)}
.rdot{fill:var(--dim)} .rdot.live{fill:var(--open)}
.door{stroke:var(--paper);stroke-width:6;stroke-linecap:butt}
.av circle{stroke:var(--panel);stroke-width:2}
.av text{font:600 9px ui-monospace,monospace;fill:#fff;text-anchor:middle}
/* A paper-coloured halo, so a name over a room wall stays readable. */
.av .nm{font:500 11px ui-sans-serif,system-ui,sans-serif;fill:var(--ink);text-anchor:middle;
  paint-order:stroke;stroke:var(--paper);stroke-width:3px;stroke-linejoin:round}
.av.you circle{stroke:var(--you);stroke-width:2.5}
.av.ghost circle{fill:var(--dim);opacity:.45}
.tgt{fill:none;stroke:var(--you);stroke-width:2;opacity:.75}

/* ---------- touch stick ---------- */
#stick{position:absolute;left:18px;bottom:18px;width:124px;height:124px;border-radius:50%;
  background:color-mix(in srgb, var(--panel) 72%, transparent);border:1px solid var(--line);
  box-shadow:var(--shadow);touch-action:none;z-index:15;display:grid;place-items:center}
#knob{width:52px;height:52px;border-radius:50%;background:var(--ink);opacity:.55;
  will-change:transform;pointer-events:none}
#stick.hot{background:color-mix(in srgb, var(--panel) 92%, transparent)}
#stick.hot #knob{opacity:.8}

/* ---------- rail: room + activity ---------- */
#rail{grid-area:rail;min-width:0;min-height:0;border-inline-start:1px solid var(--line);
  background:var(--panel);display:flex;flex-direction:column}
#grip,.tabs{display:none}
#rail section{padding:14px 16px;min-height:0;display:flex;flex-direction:column;gap:10px}
#room{flex:1 1 auto;overflow:hidden}
#activityPane{flex:0 0 auto;max-height:40%;border-top:1px solid var(--line)}
/* With no room panel showing, activity has the rail to itself. */
#rail:has(#room[hidden]) #activityPane{max-height:none;flex:1 1 auto;border-top:0}
#room h2{margin:0;font-size:18px}
#rail h3{margin:2px 0 0;font-size:11px;text-transform:uppercase;letter-spacing:.1em;color:var(--dim);
  display:flex;align-items:center;gap:6px;flex:none}
#rail h3 .n{font:600 11px ui-monospace,monospace;background:var(--floor);color:var(--dim);
  padding:2px 6px;border-radius:20px;letter-spacing:0}
#room p{margin:3px 0 0;font-size:13px;color:var(--dim)}
.rctl{display:flex;gap:8px;flex:none}
.rctl button{flex:1;padding:11px 8px;border:1px solid var(--line);background:var(--paper);color:var(--ink);
  border-radius:7px;cursor:pointer}
.rctl button.on{background:var(--you);border-color:var(--you);color:#fff}
.rctl .leave{border-color:transparent;background:var(--floor)}
#peers{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;
  flex:0 1 auto;overflow-y:auto;min-height:44px}
#peers li{display:flex;align-items:center;gap:8px;font-size:13.5px}
/* The swatch is the same colour as the avatar on the floor, so the list and the
   map name the same person. */
#peers .sw{width:22px;height:22px;border-radius:50%;flex:none;display:grid;place-items:center;
  color:#fff;font:600 10px ui-monospace,monospace}
#peers .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#peers .dot{width:7px;height:7px;border-radius:50%;background:var(--open);flex:none;margin-inline-start:auto}
#peers .dot.muted{background:var(--dim)}
#peers .dot.pending{background:var(--knock)}
#peers .g{font:10px ui-monospace,monospace;color:var(--dim);border:1px solid var(--line);
  padding:1px 4px;border-radius:4px;flex:none}
#chatLog{flex:1 1 auto;overflow-y:auto;font-size:13.5px;display:flex;flex-direction:column;gap:6px;min-height:52px}
#chatLog b{font-weight:600}
#chatForm{flex:none}
#chatForm input{margin:0}

/* ---------- activity ---------- */
#activity{flex:1 1 auto;overflow-y:auto;display:flex;flex-direction:column;gap:7px;
  font-size:13px;min-height:44px}
.ev{display:flex;gap:8px;align-items:baseline;color:var(--ink);
  border-inline-start:2px solid var(--line);padding-inline-start:8px}
.ev time{font:11px/1.4 ui-monospace,monospace;color:var(--dim);flex:none}
.ev.warn{border-inline-start-color:var(--knock)}
.ev.bad{border-inline-start-color:var(--you)}
.ev.good{border-inline-start-color:var(--open)}
.ev .quiet{color:var(--dim)}
#activity .empty{color:var(--dim);font-size:12.5px;border:0;padding:0}

/* ---------- prompts (knocks, blocked audio) ---------- */
#prompts{position:fixed;top:calc(env(safe-area-inset-top) + 62px);left:50%;transform:translateX(-50%);
  z-index:45;display:flex;flex-direction:column;gap:8px;align-items:center;
  width:min(440px,calc(100% - 24px));pointer-events:none}
.prompt{pointer-events:auto;width:100%;background:var(--panel);color:var(--ink);
  border:1px solid var(--knock);border-radius:10px;padding:11px 13px;box-shadow:var(--shadow);
  font-size:13.5px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.prompt span{flex:1;min-width:140px}
.prompt button{border:0;border-radius:7px;padding:9px 13px;font-weight:600;cursor:pointer}
.prompt .yes{background:var(--open);color:#fff}
.prompt .no{background:var(--floor);color:var(--ink)}

/* ---------- phone ---------- */
@media (max-width:879px){
  body{grid-template-columns:1fr;grid-template-areas:"bar" "stage"}
  #bar{padding:9px 12px;padding-top:max(9px,env(safe-area-inset-top))}
  .legend span:not(.hint){display:none}
  .legend .hint{border-inline-start:0;padding-inline-start:0}
  #stage{padding:10px;padding-bottom:calc(var(--peek) + 10px)}

  /* The rail becomes a sheet over the floor rather than a panel below it, so
     the map and the room controls are on screen at the same time. */
  #rail{position:fixed;inset-inline:0;bottom:0;top:auto;height:auto;max-height:78dvh;
    border-inline-start:0;border-top:1px solid var(--line);border-radius:14px 14px 0 0;
    box-shadow:0 -4px 24px rgba(0,0,0,.14);z-index:30;
    transform:translateY(calc(100% - var(--peek)));transition:transform .22s ease;
    padding-bottom:env(safe-area-inset-bottom)}
  body.sheet-open #rail{transform:translateY(0)}

  #grip{display:flex;align-items:center;gap:10px;height:var(--peek);flex:none;
    width:100%;background:transparent;border:0;padding:0 16px;color:var(--ink);
    font-weight:600;font-size:14px;cursor:pointer;text-align:start}
  #gripLabel{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .gripbar{position:absolute;top:7px;left:50%;transform:translateX(-50%);
    width:36px;height:4px;border-radius:2px;background:var(--line)}
  .gripchev{width:9px;height:9px;border-inline-end:2px solid var(--dim);
    border-block-start:2px solid var(--dim);transform:rotate(-45deg);flex:none;
    transition:transform .22s ease}
  body.sheet-open .gripchev{transform:rotate(135deg)}

  .tabs{display:flex;gap:4px;padding:0 12px 8px;flex:none}
  .tabs button{flex:1;padding:9px;border:0;border-radius:8px;background:var(--floor);
    color:var(--dim);cursor:pointer;position:relative}
  .tabs button.on{background:var(--ink);color:var(--paper);font-weight:600}
  .tabs button:disabled{opacity:.45;cursor:default}
  .tabs #actDot{position:absolute;top:6px;inset-inline-end:8px;width:7px;height:7px;
    border-radius:50%;background:var(--knock)}

  #rail[data-tab="activity"] #room{display:none}
  #rail[data-tab="room"] #activityPane{display:none}
  #activityPane{max-height:none;flex:1 1 auto;border-top:0}
  #rail section{padding:0 16px 16px}
  #chatLog{min-height:80px}
  #activity{min-height:80px}

  #stick{left:14px;bottom:calc(var(--peek) + 14px);width:112px;height:112px}
  #prompts{top:auto;bottom:calc(var(--peek) + 14px)}
}

/* A device with no fine pointer never sees the keyboard hint. */
@media (pointer:coarse){
  #stage{--stick-shown:1}
}
