/* My Virtual World Online — Copyright (c) 2026 My Virtual World. All rights reserved. Proprietary and confidential: not open source, not MIT-licensed. No copying, porting, re-implementation or AI training without written permission (see LICENSE). · ref 0be9d0a8321f */

/* rev mvwo-d5babbbb16d2 */
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; background: var(--page); color: var(--text); }
body { font-size: 13px; -webkit-font-smoothing: antialiased; user-select: none; }
#gl { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; outline: none; touch-action: none; }
/* under water (render/underwater-fx.js): the view darker toward its edges, lighter from above */
#underwater { position: fixed; inset: 0; pointer-events: none; z-index: 1; opacity: 0; transition: opacity .3s ease;
  background: linear-gradient(to bottom, rgba(150, 225, 230, .10), rgba(150, 225, 230, 0) 45%), radial-gradient(ellipse 75% 70% at 50% 45%, rgba(6, 46, 56, 0) 55%, rgba(3, 26, 34, .45) 100%); }
#underwater.on { opacity: 1; }
#labels { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 2; }
#ui { position: fixed; inset: 0; pointer-events: none; z-index: 3; }
#ui > * { pointer-events: auto; }
button { font: inherit; color: inherit; cursor: pointer; }
input, select, textarea { font: inherit; color: var(--text); }
.hidden { display: none !important; }

/* ---------- icons (js/core/icons.js): line icons drawn in the text's own colour and sized with the text, so they suit
   every theme; a few carry a meaning colour from the theme (done, warning, rating, online). ---------- */
svg.mvi { display: inline-block; width: 1.2em; height: 1.2em; vertical-align: -.24em; flex: none; overflow: visible;
  fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
svg.mvi .f { fill: currentColor; stroke: currentColor; stroke-width: .5; }
svg.mvi.t-good { color: var(--good); }
svg.mvi.t-bad { color: var(--bad); }
svg.mvi.t-gold { color: var(--gold); }
svg.mvi.t-dim { color: var(--dim); }
.btn svg.mvi:only-child, .icon svg.mvi:only-child { vertical-align: -.2em; }
.lbl svg.mvi { filter: drop-shadow(0 1px 1.5px var(--shadow-c4)); }

/* ---------- loading: the brand's own screen, dark whatever the theme. The logo's orange and magenta light lives in CSS
   layers (opacity, transform and a masked sweep only, so the compositor keeps them moving while the page is busy); the
   figures, sparks, status line and progress line are drawn on .ld-canvas by js/loading-art.js. ---------- */
#loading { position: fixed; inset: 0; z-index: 10; overflow: hidden; color: #eadcd2;
  background: radial-gradient(95% 70% at 50% 34%, #1d1016 0%, #0c0709 50%, #030203 100%); transition: opacity .7s ease;
  --lw: min(640px, 84vw, calc((100dvh - 330px) * 3.06)); }
#loading.done { opacity: 0; pointer-events: none; }
#loading.gone { display: none; }
.ld-col { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding-bottom: 3vh; }
.ld-logo { position: relative; width: var(--lw); min-width: 220px; aspect-ratio: 1200 / 392; isolation: isolate; animation: ld-in 1.2s cubic-bezier(.2,.7,.2,1) both; }
.ld-logo::before { content: ''; position: absolute; inset: -55% -18%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255, 96, 32, .2), rgba(255, 40, 110, .07) 55%, transparent 78%);
  animation: ld-heat 3.7s ease-in-out infinite; }
.ld-logo img, .ld-flow { position: absolute; left: 0; top: 0; width: 100%; height: 100%; display: block; pointer-events: none; user-select: none; -webkit-user-select: none; }
.ld-logo .ld-halo { left: -10%; top: -30.61%; width: 120%; height: 161.22%; }
.ld-glow, .ld-hot, .ld-halo, .ld-flow { mix-blend-mode: plus-lighter; }
.ld-glow { animation: ld-breathe 3.7s ease-in-out infinite; }
.ld-hot { animation: ld-flicker 5.3s ease-in-out infinite; opacity: 0; }
.ld-halo { animation: ld-halo 3.7s ease-in-out infinite; animation-delay: -.25s; }
.ld-flow { overflow: hidden; -webkit-mask: url(/img/brand/mvw-mask.png) 0 0 / 100% 100% no-repeat; mask: url(/img/brand/mvw-mask.png) 0 0 / 100% 100% no-repeat; }
.ld-flow i { position: absolute; left: 0; top: -10%; width: 100%; height: 120%; transform: translateX(-120%);
  background: linear-gradient(102deg, transparent 30%, rgba(255, 170, 80, .0) 36%, rgba(255, 214, 150, .85) 46%, rgba(255, 246, 225, 1) 50%, rgba(255, 90, 150, .75) 55%, transparent 66%);
  animation: ld-sweep 5.2s cubic-bezier(.45, .05, .5, .95) infinite; }
.ld-flow i + i { background: linear-gradient(78deg, transparent 34%, rgba(255, 60, 130, .7) 47%, rgba(255, 150, 70, .55) 53%, transparent 62%);
  animation-duration: 8.3s; animation-delay: -3.1s; animation-direction: reverse; opacity: .7; }
.ld-word { width: calc(max(var(--lw), 220px) * .74); margin-top: calc(max(var(--lw), 220px) * .03); opacity: .94; pointer-events: none; user-select: none;
  animation: ld-in 1.2s .2s cubic-bezier(.2,.7,.2,1) both; }
.ld-fig { height: clamp(110px, 25vh, 220px); aspect-ratio: 3 / 2; margin-top: clamp(10px, 4.5vh, 44px); }
.ld-text { width: min(380px, 88vw); height: 22px; margin-top: clamp(4px, 1.2vh, 12px); }
.ld-bar { width: min(260px, 66vw); height: 12px; margin-top: 6px; }
.ld-canvas { position: absolute; left: 0; top: 0; width: 100%; height: 100%; pointer-events: none; }
.ld-logo .ld-embers { position: absolute; inset: 0; overflow: visible; mix-blend-mode: normal; }
.ld-embers i { position: absolute; border-radius: 50%; opacity: 0; will-change: transform, opacity;
  background: radial-gradient(circle, #fff3dc 0%, #ffb256 35%, rgba(255, 90, 30, .5) 60%, transparent 72%); }
.ld-embers i.m { background: radial-gradient(circle, #ffe8f0 0%, #ff7aa8 35%, rgba(240, 40, 110, .5) 60%, transparent 72%); }
@keyframes ld-ember0 { 0% { opacity: 0; transform: translate(0, 0) scale(1); } 15% { opacity: .95; } 100% { opacity: 0; transform: translate(-14px, -90px) scale(.35); } }
@keyframes ld-ember1 { 0% { opacity: 0; transform: translate(0, 0) scale(1); } 20% { opacity: .9; } 100% { opacity: 0; transform: translate(10px, -70px) scale(.4); } }
@keyframes ld-ember2 { 0% { opacity: 0; transform: translate(0, 0) scale(1.1); } 12% { opacity: 1; } 100% { opacity: 0; transform: translate(20px, -110px) scale(.3); } }
@keyframes ld-ember3 { 0% { opacity: 0; transform: translate(0, 0) scale(.9); } 25% { opacity: .85; } 100% { opacity: 0; transform: translate(-5px, -60px) scale(.45); } }
.ld-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@keyframes ld-in { from { opacity: 0; transform: scale(.965); } to { opacity: 1; transform: none; } }
@keyframes ld-breathe { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes ld-halo { 0%, 100% { opacity: .32; transform: scale(.985); } 50% { opacity: .9; transform: scale(1.02); } }
@keyframes ld-heat { 0%, 100% { opacity: .55; transform: scale(.96); } 50% { opacity: 1; transform: scale(1.04); } }
@keyframes ld-flicker { 0% { opacity: 0; } 7% { opacity: .3; } 9% { opacity: .12; } 14% { opacity: .42; } 22% { opacity: .16; } 31% { opacity: 0; }
  44% { opacity: .3; } 47% { opacity: .08; } 52% { opacity: .46; } 63% { opacity: .18; } 71% { opacity: .04; } 80% { opacity: .36; } 84% { opacity: .2; } 92% { opacity: .05; } 100% { opacity: 0; } }
@keyframes ld-sweep { 0% { transform: translateX(-120%); } 62%, 100% { transform: translateX(120%); } }
@supports not (mix-blend-mode: plus-lighter) { .ld-glow, .ld-hot, .ld-halo, .ld-flow { mix-blend-mode: screen; } }
@media (prefers-reduced-motion: reduce) {
  .ld-logo, .ld-logo::before, .ld-logo *, .ld-word { animation: none !important; }
  .ld-glow { opacity: 1; } .ld-halo { opacity: .6; } .ld-flow, .ld-embers { display: none; }
}

/* ---------- generic panel ---------- */
.panel { background: var(--bg); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow);
  backdrop-filter: blur(14px) saturate(.6); -webkit-backdrop-filter: blur(14px) saturate(.6); }
/* See-through (Settings → Display → Transparency; core/theme.js, theme.css): the world shows through the windows, panels
   and buttons — not frosted — and their words keep a faint halo of the theme's own surface colour so they read over a busy
   world. High contrast never is. */
:root.see-through .panel, :root.see-through .dock, :root.see-through #topbar { backdrop-filter: none; -webkit-backdrop-filter: none;
  text-shadow: 0 0 3px var(--panel-strong-0), 0 0 9px var(--panel-strong-0); }
.btn { background: var(--btn); border: 1px solid var(--line); border-radius: 9px; padding: 6px 10px; transition: background .15s, border-color .15s, transform .08s; white-space: nowrap; }
.btn:hover { background: var(--btn-hover); }
.btn:active { transform: translateY(1px); }
.btn.on { background: linear-gradient(180deg, var(--btn-on-a), var(--btn-on-b)); border-color: var(--hl-line); color: var(--strong); }
.btn.primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); font-weight: 600; }
.btn.primary:hover { background: var(--strong); }
.btn.danger { background: var(--bad-soft); border-color: var(--bad-line); }
.btn.small { padding: 3px 8px; font-size: 12px; border-radius: 7px; }
.btn.icon { width: 32px; height: 32px; padding: 0; display: inline-grid; place-items: center; font-size: 15px; }
.btn:disabled { opacity: .4; cursor: default; }
.row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
/* Settings → Display → Transparency: the slider and its value on one line */
.tr-row { flex-wrap: nowrap; gap: 12px; } .tr-row input[type=range] { flex: 1; width: auto; min-width: 0; }
.tr-v { flex: none; min-width: 3.2em; text-align: right; font-variant-numeric: tabular-nums; }
.tr-l.off { opacity: .5; }
.sep { height: 1px; background: var(--line); margin: 10px 0; }
.dim { color: var(--dim); }
.tag { display: inline-block; padding: 1px 7px; border-radius: 20px; font-size: 11px; background: var(--bar); color: var(--dim); }
.tag.live { background: var(--good-soft); color: var(--good); }
.tag.vip { background: var(--gold-soft); color: var(--gold); }
/* High contrast: --bar is white there, so a plain tag (white on white) becomes an outlined one. */
:root[data-theme="contrast"] .tag:not(.live):not(.vip) { background: transparent; border: 1px solid var(--line); color: var(--text); }
.field { display: grid; grid-template-columns: 92px 1fr; gap: 6px 8px; align-items: center; margin: 6px 0; }
.field label { color: var(--dim); font-size: 12px; }
.input, select.input { width: 100%; background: var(--field); border: 1px solid var(--line); border-radius: 8px; padding: 6px 8px; outline: none; }
.input:focus { border-color: var(--hl-line); }
/* Dropdowns in the theme (2026-10-06), every <select> in every panel: the closed box like the other fields, and the open
   list too — fully, where the browser has stylable selects (Chromium's appearance: base-select), else at least its colours. */
select { font: inherit; color: var(--text); background-color: var(--field); border: 1px solid var(--line); border-radius: 8px; }
select option { background-color: var(--panel-strong); color: var(--text); }
@supports (appearance: base-select) {
  select, select::picker(select) { appearance: base-select; }
  select { display: inline-flex; align-items: center; justify-content: space-between; gap: 8px; padding: 5px 9px; min-height: 30px; cursor: pointer; text-align: left; }
  select:hover { border-color: var(--btn-hover); }
  select:focus-visible { outline: none; border-color: var(--hl-line); }
  select::picker-icon { content: ''; flex: none; width: 7px; height: 7px; border-right: 1.75px solid currentColor; border-bottom: 1.75px solid currentColor; transform: translateY(-2px) rotate(45deg); opacity: .65; transition: transform .15s ease; }
  select:open::picker-icon { transform: translateY(2px) rotate(225deg); }
  select::picker(select) { margin-top: 4px; padding: 4px; min-width: anchor-size(width); border: 1px solid var(--vw-border-strong, var(--line)); border-radius: 10px;
    background: var(--panel-strong); color: var(--text); box-shadow: 0 14px 34px var(--shadow-c2); backdrop-filter: blur(14px); }
  select option { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 7px; background: transparent; color: var(--text); cursor: pointer; white-space: nowrap; }
  select option:hover, select option:focus-visible { background: var(--hover-1); outline: none; }
  select option:checked { background: var(--sel); font-weight: 600; }
  select option::checkmark { display: none; }
  select option:disabled { color: var(--dim); }
}
input[type=color] { width: 34px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 6px; background: none; cursor: pointer; }
input[type=range] { width: 100%; accent-color: var(--accent); }
.scroll { overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent; }

/* ---------- top bar ---------- */
#topbar { position: fixed; top: 10px; left: 10px; right: 10px; height: 46px; display: flex; align-items: center; gap: 10px; padding: 0 10px; }
#topbar .brand { font-weight: 800; letter-spacing: .2px; white-space: nowrap; display: flex; align-items: center; gap: 8px; }
#topbar .brand b { color: var(--accent2); }
#topbar .brand small { color: var(--dim); font-weight: 500; }
#clock { display: flex; align-items: center; gap: 8px; padding: 4px 12px; border-radius: 10px; background: var(--pill); border: 1px solid var(--line); min-width: 150px; }
#clock .t { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 15px; white-space: nowrap; }
#clock .d { color: var(--dim); font-size: 12px; }
#speed { display: flex; align-items: center; gap: 4px; }
#speed .btn { height: 32px; padding: 0 9px; display: inline-flex; align-items: center; justify-content: center; gap: 3px; font-size: 12px; }
#speed .btn .tri { width: 12px; height: 12px; fill: currentColor; flex: none; }
#speed .spd { min-width: 52px; }
#speed .spd b { font-size: 11px; font-weight: 800; letter-spacing: .2px; }
#topbar .spacer { flex: 1; }
#stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; color: var(--dim); }
#stats span { display: flex; flex-direction: column; align-items: center; font-size: 11px; line-height: 1.25; }
#stats b { color: var(--text); font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
#net { width: 9px; height: 9px; border-radius: 50%; background: var(--bad); box-shadow: 0 0 8px var(--bad); }
#net.ok { background: var(--good); box-shadow: 0 0 8px var(--good); }
#search { position: relative; }
#search input { width: 210px; }
#search .results { position: absolute; top: 36px; right: 0; width: 300px; max-height: 360px; padding: 6px; }
.result { padding: 7px 9px; border-radius: 8px; cursor: pointer; display: flex; gap: 8px; align-items: center; }
.result:hover, .result.hl { background: var(--bar); }
.result .sub { color: var(--dim); font-size: 11px; }

/* ---------- side panels ---------- */
#roster { position: fixed; top: 66px; left: 10px; width: 262px; max-height: calc(100vh - 330px); display: flex; flex-direction: column; }
#roster .head, .insp .head { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; border-bottom: 1px solid var(--line); font-weight: 700; }
#roster .list { padding: 6px; }
#roster.collapsed .list { display: none; }
.agent-row { display: flex; gap: 9px; align-items: center; padding: 6px 7px; border-radius: 9px; cursor: pointer; }
.agent-row:hover { background: var(--hover-1); }
.agent-row.sel { background: var(--btn-on-b); }
.agent-row .em { width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; font-size: 17px; background: var(--hover-1); flex: none; position: relative; }
.agent-row .em i { position: absolute; right: -2px; bottom: -2px; width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--bubble); background: var(--muted-2); }
.agent-row .em i.live { background: var(--good); }
.agent-row .nm { font-weight: 600; }
.agent-row .ac { color: var(--dim); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 190px; }

.insp { position: fixed; top: 66px; right: 10px; width: 312px; max-height: calc(100vh - 150px); display: flex; flex-direction: column; }
.insp .body { padding: 12px; }
.insp .title { display: flex; gap: 10px; align-items: center; }
.insp .title .big { font-size: 26px; width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; background: var(--hover-1); }
.insp .title .name { font-size: 16px; font-weight: 700; }
.insp .title .role { color: var(--dim); font-size: 12px; }
.act { display: flex; gap: 10px; align-items: center; padding: 9px 10px; border-radius: 10px; background: var(--ghost); margin: 10px 0; }
.act .ic { font-size: 20px; }
.act .lb { font-weight: 600; }
.act .pl { color: var(--dim); font-size: 12px; }
.needs { display: grid; grid-template-columns: 70px 1fr; gap: 5px 8px; align-items: center; font-size: 12px; }
.bar { height: 7px; border-radius: 6px; background: var(--bar); overflow: hidden; }
.bar i { display: block; height: 100%; border-radius: 6px; transition: width .5s; }
.kv { display: grid; grid-template-columns: 70px 1fr; gap: 5px 8px; font-size: 12px; margin-top: 8px; }
.kv .k { color: var(--dim); }
.kv a { color: var(--accent); cursor: pointer; text-decoration: none; }
.kv a:hover { text-decoration: underline; }
.floors { display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 4px; max-height: 150px; overflow-y: auto; margin-top: 6px; }
.floors .btn { padding: 4px 0; font-size: 12px; }

/* ---------- floor widget ---------- */
/* The floor control sits on the building being looked into (C113); ui.js placeFloorw() sets its transform each frame. */
#floorw { position: fixed; left: 0; top: 0; width: 62px; display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 6px; border-radius: 14px; will-change: transform; }
#floorw .btn.icon { width: 100%; height: 30px; }
#floorw .fl { text-align: center; line-height: 1.05; cursor: default; padding: 2px 0; }
#floorw .fl b { display: block; font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }
#floorw .fl small { color: var(--dim); font-size: 11px; }
#floorw .sep2 { height: 1px; background: var(--line); margin: 2px 0; }
#floorw .walls, #floorw .exit { padding: 5px 2px; font-size: 11px; text-align: center; }

/* ---------- editor panels (inside the edit dock since WP1.7) ---------- */
.toolpanel { position: fixed; bottom: 66px; left: 50%; transform: translateX(-50%); width: min(760px, calc(100vw - 560px)); min-width: 420px; padding: 10px 12px; }
.toolpanel h4 { margin: 0 0 8px; font-size: 13px; display: flex; justify-content: space-between; align-items: center; }
.cats { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 8px; }
.items { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 5px; max-height: 150px; overflow-y: auto; }
.item-btn { padding: 7px 6px; border-radius: 9px; background: var(--ghost); border: 1px solid var(--line); text-align: center; font-size: 12px; cursor: pointer; }
.item-btn:hover { background: var(--line); }
.item-btn.on { border-color: var(--hl-line); background: var(--on-1); }
.item-btn .em { font-size: 18px; display: block; margin-bottom: 2px; }
.hint { color: var(--dim); font-size: 12px; margin-top: 6px; }
kbd { background: var(--line); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px; padding: 0 5px; font-size: 11px; font-family: inherit; }

/* ---------- minimap ---------- */
#minimap { position: fixed; left: 10px; bottom: 12px; padding: 6px; }
#minimap canvas { display: block; border-radius: 8px; cursor: crosshair; }

/* ---------- labels ---------- */
.lbl { position: absolute; left: 0; top: 0; transform: translate(-50%, -100%); white-space: nowrap; pointer-events: none; will-change: transform; }
.lbl .tagname { background: var(--label); border: 1px solid var(--btn-hover); padding: 2px 8px; border-radius: 20px; font-size: 12px; font-weight: 600; color: var(--strong); display: inline-flex; gap: 5px; align-items: center; }
.lbl .tagname.vip { border-color: var(--gold-line); }
.lbl .tagname .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--good); box-shadow: 0 0 6px var(--good); }
.lbl .tagname.sel { background: var(--sel-tag-bg); border-color: var(--strong); color: var(--page); }
/* an agent talking in the chat — voice mode, or an answer read aloud (ui/chat-voice.js, render/labels.js): its name glows
   blue with how loud it is now (--lv, 0–1, on the label) */
.lbl .tagname.voicing { border-color: rgba(56, 189, 248, .9); box-shadow: 0 0 0 1px rgba(56, 189, 248, calc(.35 + var(--lv, 0) * .5)),
  0 0 calc(6px + var(--lv, 0) * 22px) calc(var(--lv, 0) * 5px) rgba(56, 189, 248, calc(.4 + var(--lv, 0) * .55)); }
.lbl .ico { font-size: 15px; filter: drop-shadow(0 1px 2px var(--shadow-c4)); }
.bubble { position: absolute; left: 0; top: 0; transform: translate(-50%, -100%); max-width: 260px; white-space: normal; background: var(--strong); color: var(--bubble); padding: 8px 11px; border-radius: 14px; font-size: 12.5px; line-height: 1.35; box-shadow: 0 6px 18px var(--scrim-2); pointer-events: none; }
.bubble::after { content: ''; position: absolute; left: 50%; bottom: -7px; margin-left: -7px; border: 7px solid transparent; border-bottom: 0; border-top-color: var(--strong); }
.bubble b { display: block; font-size: 11px; color: var(--muted); margin-bottom: 2px; }
.bubble .bt { max-height: 152px; overflow: hidden; white-space: pre-line; overflow-wrap: anywhere; }
/* (a long one — an agent's answer — scrolls inside, under the finger or the wheel; faded at the foot until its end) */
.bubble.scroll { pointer-events: auto; }
.bubble.scroll .bt { overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; scrollbar-width: thin; scrollbar-color: var(--muted) transparent; padding-right: 4px;
  -webkit-mask-image: linear-gradient(#000 calc(100% - 22px), transparent); mask-image: linear-gradient(#000 calc(100% - 22px), transparent); }
.bubble.scroll.end .bt { -webkit-mask-image: none; mask-image: none; }
.bubble.low::after { display: none; }   /* (slid down out from under a bar: over the head, its tail would point nowhere) */
/* first person (render/labels.js): beside the person, the bubble's tail at the end nearest to it */
.bubble.side::after { left: 16px; margin-left: 0; }
.bubble.side.flip::after { left: auto; right: 16px; }

/* ---------- toasts ---------- */
#toasts { position: fixed; top: max(66px, var(--sel-b, 0px)); left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: 6px; align-items: center; pointer-events: none !important; }
.toast { padding: 8px 14px; border-radius: 10px; background: var(--bg2); border: 1px solid var(--line); box-shadow: var(--shadow); animation: tin .25s ease-out; font-weight: 500; }
.toast.bad { border-color: var(--bad-line-2); }
.toast.good { border-color: var(--good-line); }
@keyframes tin { from { opacity: 0; transform: translateY(-6px); } }

/* ---------- modal ---------- */
.modal-back { position: fixed; inset: 0; background: var(--scrim); display: grid; place-items: center; z-index: 5; pointer-events: auto; }
.modal { width: min(860px, calc(100vw - 30px)); max-height: calc(100vh - 40px); display: grid; grid-template-columns: 300px 1fr; overflow: hidden; }
.modal .preview { background: radial-gradient(400px 300px at 50% 60%, var(--preview-a), var(--preview-b)); position: relative; min-height: 460px; }
.modal .preview canvas { width: 100%; height: 100%; display: block; }
.modal .preview .pname { position: absolute; left: 0; right: 0; bottom: 14px; text-align: center; font-weight: 700; font-size: 16px; }
.modal .form { padding: 14px 16px; overflow-y: auto; max-height: calc(100vh - 40px); }
.modal h3 { margin: 0 0 10px; }
.swatches { display: flex; flex-wrap: wrap; gap: 5px; }
.sw { width: 22px; height: 22px; border-radius: 6px; border: 2px solid transparent; cursor: pointer; box-shadow: inset 0 0 0 1px var(--field); }
.sw.on { border-color: var(--strong); }
.chips { display: flex; flex-wrap: wrap; gap: 4px; }
.chip { padding: 4px 9px; border-radius: 20px; background: var(--btn); border: 1px solid var(--line); font-size: 12px; cursor: pointer; }
.chip.on { background: var(--lbl-shadow); border-color: var(--hl-line); }

/* ---------- player HUD ---------- */
#phud { position: fixed; bottom: 70px; left: 50%; transform: translateX(-50%); text-align: center; pointer-events: none !important; }
#phud .prompt { display: inline-block; padding: 8px 14px; border-radius: 10px; background: var(--label-4); border: 1px solid var(--btn-on-b); font-weight: 600; margin-bottom: 8px; }
#phud .keys { display: none; }   /* the controls live behind ? in the top bar (2026-10-06); the prompt above stays */
#elev { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: 12px; width: 240px; }
#elev .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; max-height: 300px; overflow-y: auto; margin-top: 8px; }
#fade { position: fixed; inset: 0; background: var(--curtain); opacity: 0; pointer-events: none !important; transition: opacity .25s; z-index: 4; }
#fade.on { opacity: 1; }
#help { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(640px, calc(100vw - 30px));
  max-height: calc(100vh - 30px); overflow-y: auto; padding: 16px 18px; }
/* The close button stays reachable however long the sheet is (found in the phone audit, 2026-09-28). */
#help h3 { position: sticky; top: -16px; background: var(--bg); padding-top: 4px; margin: 0 0 10px; z-index: 1; }
#help table { width: 100%; border-collapse: collapse; }
#help td { padding: 4px 6px; border-bottom: 1px solid var(--line); }
#help td:first-child { width: 42%; }
@media (max-width: 1100px) {
  .toolpanel { width: calc(100vw - 30px); min-width: 0; }
}

/* ---------- additions (ui.js) ---------- */
#tip { position: fixed; left: 0; top: 0; z-index: 4; pointer-events: none !important; padding: 5px 9px; border-radius: 8px; background: var(--label-3); border: 1px solid var(--btn-hover); font-size: 12px; white-space: nowrap; box-shadow: var(--shadow); }
#tip .sub { color: var(--dim); font-size: 11px; }
.lbl .tagname.small { font-size: 11px; font-weight: 500; padding: 1px 7px; background: var(--label-2); }
.insp .head .close { margin-left: 8px; }
.insp .said { background: var(--hover-1); border-radius: 10px; padding: 7px 10px; margin: 6px 0 10px; font-style: italic; line-height: 1.35; }
.insp .task { margin: -4px 0 8px; }
.insp .tags { gap: 4px; }
.insp .chips { margin-top: 6px; }
.floors .btn small { display: block; font-size: 10px; line-height: 1.1; color: var(--accent2); min-height: 11px; }
.floors .btn { position: relative; }
.flatrow { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 4px; margin-top: 6px; }
.flatrow .btn { padding: 4px 0; font-size: 12px; } .flatrow .btn small { display: block; font-size: 10px; line-height: 1.1; color: var(--accent2); min-height: 11px; }
.floors .btn[data-fm="custom"]::after, .floors .btn[data-fm="empty"]::after { position: absolute; top: 1px; right: 3px; font-size: 9px; line-height: 1; color: var(--warn, #d9a441); }
.floors .btn[data-fm="custom"]::after { content: '✎'; } .floors .btn[data-fm="empty"]::after { content: '○'; color: var(--dim); }
/* the floor being furnished: its mode and whole-floor actions (ui/editors.js renderFloorBar) */
.toolpanel .floorbar { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.toolpanel .floorbar:empty { display: none; }
.floorbar .fmode { font-weight: 700; font-size: 12px; padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); white-space: nowrap; }
.floorbar .fm-auto { color: var(--good); } .floorbar .fm-custom { color: var(--warn, #d9a441); } .floorbar .fm-empty { color: var(--dim); }
.floorbar .fm-tip { color: var(--dim); font-size: 12px; flex: 1 1 200px; min-width: 0; }
.floorbar .fm-acts { display: flex; gap: 6px; flex-wrap: wrap; }
@media (pointer: coarse) { .floorbar .fm-acts .btn { min-height: 36px; } }
/* saved floor layouts (ui/floor-library.js) */
.lib-back { z-index: 9; }
.libdlg { width: min(560px, calc(100vw - 20px)); max-height: calc(100vh - 40px); padding: 16px 18px; display: grid; gap: 10px; grid-template-rows: auto; overflow: auto; }
.libdlg h3 { margin: 0; font-size: 17px; display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.libdlg p { margin: 0; line-height: 1.4; }
.libdlg .lib-list { display: grid; gap: 8px; max-height: min(60vh, 520px); overflow-y: auto; }
.libdlg .lib-row { border: 1px solid var(--line); border-radius: 10px; padding: 9px 10px; display: grid; gap: 7px; }
.libdlg .lib-main { display: grid; gap: 2px; min-width: 0; } .libdlg .lib-main .dim { font-size: 12px; color: var(--dim); }
.libdlg .lib-acts { display: flex; flex-wrap: wrap; gap: 6px; }
.libdlg .lib-share { display: grid; gap: 6px; border-top: 1px solid var(--line); padding-top: 7px; }
.libdlg .lib-who { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 13px; }
.libdlg .lib-who .chip button { background: none; border: 0; color: inherit; margin-left: 4px; padding: 0 2px; cursor: pointer; }
.libdlg .lib-add { display: flex; gap: 6px; } .libdlg .lib-add input, .libdlg .lib-field input, .libdlg .lib-rename { flex: 1; min-width: 0; padding: 7px 9px; border-radius: 8px; border: 1px solid var(--line); background: var(--btn); color: inherit; font: inherit; }
.libdlg .lib-field { display: grid; gap: 4px; font-size: 13px; }
.libdlg .lib-btns { display: flex; gap: 8px; justify-content: flex-end; } .libdlg .lib-btns .btn { min-height: 40px; padding: 8px 16px; }
.libdlg .bad { color: var(--bad); }
.flatdlg .flat-sec { display: grid; gap: 6px; border-top: 1px solid var(--line); padding-top: 8px; }
.flatdlg .lib-add select, .flatdlg .lib-add input[type=number] { padding: 6px 8px; border-radius: 8px; border: 1px solid var(--line); background: var(--btn); color: inherit; font: inherit; max-width: 140px; }
@media (max-width: 760px) { .lib-back { place-items: end center; } .libdlg { width: calc(100vw - 12px); margin-bottom: calc(6px + env(safe-area-inset-bottom)); } .libdlg .lib-btns .btn { flex: 1; min-height: 46px; } .libdlg .lib-acts .btn { min-height: 38px; } }
#speed .skip { width: auto; padding: 4px 6px; font-size: 12px; margin-left: 2px; }
#clock .sun { font-size: 15px; }
.result .em { width: 26px; text-align: center; font-size: 17px; flex: none; }
#roster .head .cnt { font-weight: 500; font-size: 12px; color: var(--good); }
#stats span { white-space: nowrap; }
#help h3 { margin: 0 0 10px; display: flex; justify-content: space-between; align-items: center; }
#help .hint { margin-top: 10px; line-height: 1.4; }
@media (max-width: 760px) {
  #topbar { height: 42px; gap: 6px; }
  #topbar .brand span, #speed .skip { display: none; }
  #clock { min-width: 0; padding: 3px 8px; }
  #search input { width: 120px; }
  #search .results { right: -40px; width: 280px; }
  #minimap { display: none; }
}

/* ---------- editors ---------- */
.toolpanel .selbar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.toolpanel .selbar:empty { display: none; }
.toolpanel .swatches { align-items: center; }
.toolpanel .swatches input[type=color], .modal .swatches input[type=color] { width: 26px; height: 22px; }
.toolpanel h4 .scope { display: inline-flex; gap: 5px; align-items: center; font-size: 12px; color: var(--dim); font-weight: 500; cursor: pointer; margin-right: 6px; }
.toolpanel .status { min-height: 16px; }
.toolpanel .where { font-weight: 500; font-size: 12px; }
#buildp .tabs { margin-bottom: 8px; }
#buildp .field { grid-template-columns: 96px 1fr; }
#buildp .field label b, .modal .field label b { color: var(--text); font-weight: 600; margin-left: 4px; }
#buildp .colors { gap: 10px; }
.ccol { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; font-size: 10px; color: var(--dim); cursor: pointer; }
#buildp .tedit, #buildp .tnew { max-height: 44vh; overflow-y: auto; }
/* The building editor in sections (2026-10-06): a card for the building, then name and sign, size and place, look,
   billboards and actions — section titles small and quiet, labels above their fields, choices in even grids. */
#buildp .be-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-bottom: 10px; }
#buildp .be-tabs .btn { justify-content: center; }
#buildp .be { display: grid; gap: 12px; }
#buildp .be-head { display: flex; gap: 10px; align-items: center; padding: 10px; border-radius: 12px; background: var(--hover-1); border: 1px solid var(--line); }
#buildp .be-ic { flex: none; width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center; background: var(--btn); border: 1px solid var(--line); font-size: 19px; }
#buildp .be-id { display: grid; gap: 1px; min-width: 0; }
#buildp .be-id b { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#buildp .be-id small { color: var(--dim); font-size: 12px; }
#buildp .be-sec { display: grid; gap: 8px; padding-top: 12px; border-top: 1px solid var(--line); }
#buildp .be-sec.first { border-top: 0; padding-top: 0; }
#buildp .be-sec h5 { margin: 0; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
#buildp .be-f { display: grid; gap: 5px; margin: 0; }
#buildp .be-f > span, #buildp .be-lbl, #buildp .be-slider > span { font-size: 12px; color: var(--dim); }
#buildp .be-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
#buildp .be-step { display: inline-flex; align-items: center; gap: 4px; }
#buildp .be-step .btn { width: 32px; height: 32px; padding: 0; font-size: 16px; }
#buildp .be-step input { width: 58px; height: 32px; text-align: center; }
#buildp .be-chips { display: grid; grid-template-columns: repeat(auto-fill, minmax(86px, 1fr)); gap: 6px; }
#buildp .be-chips.wide { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
#buildp .be-chips .chip { display: flex; align-items: center; justify-content: center; gap: 5px; border-radius: 9px; padding: 7px 8px; text-align: center; font-size: 12.5px; }
#buildp .be-colors { display: grid; grid-template-columns: repeat(auto-fit, minmax(44px, 1fr)); gap: 6px; }
#buildp .be-color { display: grid; gap: 4px; justify-items: center; font-size: 11px; color: var(--dim); cursor: pointer; }
#buildp .be-color input[type=color] { width: 100%; height: 30px; padding: 2px; border-radius: 8px; border: 1px solid var(--line); background: var(--field); cursor: pointer; }
#buildp .be-slider { display: grid; grid-template-columns: 56px 1fr 52px; gap: 8px; align-items: center; margin: 0; }
#buildp .be-slider b { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
#buildp .be .btn.wide { width: 100%; justify-content: center; }
#buildp .be-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding-top: 12px; border-top: 1px solid var(--line); }
#buildp .be-acts .btn { justify-content: center; }
#buildp .be-acts .danger { grid-column: 1 / -1; }
#buildp .be-empty { display: grid; justify-items: center; gap: 6px; padding: 18px 10px; text-align: center; color: var(--dim); }
#buildp .be-empty span { font-size: 28px; opacity: .7; }
#buildp .be-empty p { margin: 0; font-size: 12.5px; line-height: 1.45; }

/* ---------- customizer ---------- */
.modal .preview { cursor: grab; }
.modal .preview .pv-anims { position: absolute; top: 10px; left: 8px; right: 8px; justify-content: center; }
.modal .preview .pv-hint { position: absolute; left: 0; right: 0; bottom: 40px; text-align: center; color: var(--dim); font-size: 11px; pointer-events: none; }
.modal .preview .pname { pointer-events: none; }
.modal .actions { position: sticky; bottom: -14px; background: var(--bg2); padding: 10px 0 12px; margin-top: 12px; border-top: 1px solid var(--line); }
.modal .actions .spacer { flex: 1; }

.modal .field.wide { grid-template-columns: 1fr; }
.modal .chars { display: flex; flex-wrap: wrap; gap: 5px; }
.modal .cgroup { display: grid; grid-template-columns: 56px 1fr; align-items: start; gap: 6px; margin-top: 6px; }
.modal .cgt { color: var(--dim); font-size: 11px; padding-top: 5px; }
.modal .cchip { min-width: 28px; text-align: center; }
.modal .soon-box { margin-top: 14px; padding: 10px 12px; border: 1px dashed var(--line); border-radius: 10px; }
.modal .soon-h { font-weight: 700; margin-bottom: 4px; }
.modal .soon-badge { margin-left: 6px; padding: 2px 8px; border-radius: 20px; font-size: 11px; font-weight: 700; background: rgba(255,200,80,.18); color: #f1c40f; border: 1px solid rgba(241,196,15,.45); }
.modal .soon { opacity: .38; filter: grayscale(1); pointer-events: none; user-select: none; margin-top: 6px; }

/* ---------- play mode ---------- */
/* the You bar in the top-right corner under the top bar, its right edge in line with the bar's last control, 12 px in
   (2026-10-06; it was bottom-right); a phone keeps its own place beside the radar (below) */
#playbar { position: fixed; right: 12px; top: calc(var(--topbar-height, 56px) + 10px); display: flex; gap: 6px; padding: 6px 6px 6px 12px; align-items: center; }
/* the chat window opens in that corner too: below the You bar while playing */
#playbar .pn { font-weight: 700; margin-right: 4px; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.play #floorw { display: none !important; }
#phud .prompt kbd { background: var(--lbl-shadow); margin-right: 2px; }
#elev .grid .btn { padding: 7px 0; }
#joy { position: fixed; left: 24px; bottom: 92px; width: 126px; height: 126px; border-radius: 50%; background: var(--joy-bg); border: 2px solid var(--on-3); touch-action: none; }
#joy i { position: absolute; left: 50%; top: 50%; width: 56px; height: 56px; margin: -28px 0 0 -28px; border-radius: 50%; background: var(--joy-knob); box-shadow: 0 2px 10px var(--scrim-2); }
#pbtns { position: fixed; right: 20px; bottom: 96px; display: flex; flex-direction: column; gap: 10px; }
#pbtns .btn { width: 62px; height: 62px; border-radius: 50%; font-size: 20px; font-weight: 800; background: var(--label-2); touch-action: none; -webkit-tap-highlight-color: transparent; }
#pbtns .btn.on { background: var(--pbtn-on); }
body.driving #pbtns .btn { width: 104px; height: 52px; border-radius: 14px; font-size: 13px; }
body.driving #phud { max-width: calc(100vw - 30px); width: 580px; }
@media (pointer: coarse) { #playbar { top: 58px; } }
/* a phone: the radar sits in the top-left corner, so the play bar keeps to the right of it */
@media (pointer: coarse) and (max-width: 760px) {
  #playbar { max-width: calc(100vw - 144px); padding: 5px; gap: 4px; }
  #playbar .pn { display: none; }
  #playbar .btn.small { padding: 5px 8px; font-size: 12px; }
}
@media (pointer: coarse) and (max-width: 440px) {   /* narrow phones: the play bar's buttons as icons (their names are the tooltips) */
  #playbar .pl { display: none; }
  #playbar .btn.small { width: 40px; height: 36px; padding: 0; font-size: 15px; }
}
@media (max-width: 760px) {
  .modal { grid-template-columns: 1fr; }
  .modal .preview { min-height: 220px; height: 220px; }
  .modal .form { max-height: calc(100vh - 280px); }
  .toolpanel { bottom: 62px; max-height: 48vh; overflow-y: auto; }
  #phud .keys { display: none; }
}

/* ---------- accounts (ui/account.js) ---------- */
#acct .btn.me { display: flex; align-items: center; gap: 7px; padding: 3px 10px 3px 3px; }
#acct .av { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; font-weight: 800;
  background: var(--avatar); color: var(--on-primary); }
#acct .rl { color: var(--dim); font-size: 11px; }
#acctmenu { position: fixed; top: 62px; right: 10px; width: 250px; padding: 10px; display: grid; gap: 6px; pointer-events: auto; }
#acctmenu .who { display: grid; gap: 2px; margin: 0 2px 4px; }
#acctmenu .who span { color: var(--dim); font-size: 12px; }
#acctmenu .btn { text-align: left; }
.modal-back.auth-back { z-index: 20; }
.modal.auth { display: block; width: min(410px, calc(100vw - 30px)); padding: 16px 18px; overflow-y: auto; }
.modal.auth .why { margin: 0 0 12px; }
.modal.auth .hint { margin: 0; color: var(--dim); font-size: 12px; }
.modal.auth .warn, .modal.auth .err { margin: 0; color: var(--bad); font-size: 13px; }
.modal.auth .sub { font-weight: 600; margin-bottom: 6px; }
.modal.auth .sep { margin: 4px 0; }
.aform { display: grid; gap: 10px; }
.aform label { display: grid; gap: 4px; color: var(--dim); font-size: 12px; }
.modal.auth [hidden] { display: none !important; }   /* author display rules would otherwise override [hidden] */
.aform .row { display: flex; gap: 8px; align-items: center; }
.aform .row.end { justify-content: flex-end; margin-top: 4px; }
.devices { display: grid; gap: 8px; max-height: 220px; overflow-y: auto; }
.devices .dev { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.devices .dev small { display: block; color: var(--dim); }
/* Tools a visitor cannot use: the server refuses them anyway; hiding keeps the UI honest. */
body:not(.cap-world-edit) [data-cap="world.edit"] { display: none !important; }
body:not(.cap-agents-manage) [data-cap="agents.manage"] { display: none !important; }
#roster .ros-new { padding: 0 12px 8px; display: grid; gap: 6px; }
/* (the clock's controls are the administrators': others see the time, not controls they can't use — step 8) */
body:not(.cap-world-clock) [data-cap="world.clock"] { display: none !important; }
@media (max-width: 700px) { #acct .nm, #acct .rl { display: none; } }

/* ---------- admin screens and two-factor (ui/admin.js, ui/account.js) ---------- */
.modal.auth.wide { width: min(1000px, calc(100vw - 30px)); max-height: 88vh; }
.adm { display: grid; gap: 10px; }
.adm-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.adm-tabs .tab.on { border-color: var(--hl-line); color: var(--strong); background: var(--hl); }
.adm-body { display: grid; gap: 10px; max-height: 64vh; overflow: auto; }
.adm-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.adm-table th { text-align: left; color: var(--dim); font-weight: 600; padding: 4px 6px; border-bottom: 1px solid var(--line, var(--line-2)); position: sticky; top: 0; background: var(--thead); }
.adm-table td { padding: 5px 6px; border-bottom: 1px solid var(--line, var(--line-3)); vertical-align: middle; }
.adm-table td.acts { white-space: nowrap; }
.adm-table td.det { font-family: ui-monospace, monospace; font-size: 11px; color: var(--dim); max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adm .row.wrap, .aform .row.wrap { flex-wrap: wrap; }
.adm .inline, .aform .inline { display: inline-flex; align-items: center; gap: 6px; color: var(--dim); font-size: 12px; }
.adm .input.days { width: 64px; }
.input.small, .btn.small { padding: 3px 8px; font-size: 12px; }
.btn.link { background: none; border: none; color: var(--accent); padding: 0; text-decoration: underline; text-underline-offset: 2px; }
.once, .confirm-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 8px 10px; border: 1px solid var(--accent); border-radius: 8px; }
.once code.val { user-select: all; word-break: break-all; }
.once small { color: var(--dim); }
.aform label.check { display: flex; align-items: center; gap: 8px; color: var(--text); font-size: 13px; }
.twofa .qr { width: 176px; height: 176px; background: var(--strong); padding: 6px; border-radius: 8px; }
.twofa .qr svg { width: 100%; height: 100%; }
.twofa code.key { user-select: all; letter-spacing: .06em; }
.codes { display: grid; grid-template-columns: repeat(2, max-content); gap: 4px 18px; font-size: 14px; }
.codes code { user-select: all; }

/* The account chip (and the Sign in button) must always stay on screen (CHECKLIST I14.8): the stats and the search box
   give way first. */
#acct { flex: none; }
#search { flex: 0 1 210px; min-width: 110px; }
#search input { width: 100%; }
@media (max-width: 1320px) { #topbar .brand small { display: none; } }
@media (max-width: 760px) { #search { flex-basis: 120px; min-width: 70px; } }
@media (max-width: 480px) { #clock .d { display: none; } }   /* the logo stays (2026-10-06) */

/* ---------- settings tiers and the key (ui/admin.js, WP1.5) ---------- */
.aform.settings .tier-head { font-weight: 600; font-size: 13px; }
.aform label.off, .aform label.check.off { opacity: .6; }
.aform small.why { color: var(--dim); font-size: 12px; margin-top: -6px; }
.aform .tag { font-size: 11px; padding: 1px 6px; border-radius: 6px; border: 1px solid var(--line, var(--line-3)); color: var(--dim); }
.aform .tag.set { color: var(--good, var(--good-alt)); border-color: currentColor; }
.adm .keyinfo { padding: 8px 10px; border: 1px solid var(--line, var(--line-2)); border-radius: 8px; font-size: 13px; line-height: 1.5; }
.adm .keyinfo.bad { border-color: var(--bad); }
.adm .keyinfo .warn { margin: 6px 0 0; }

/* ---------- the shell (ui/docks.js, ui/settings.js; PLAN WP1.7, DECISIONS C112): top bar 56 px, the left edit dock,
   the right info dock, the floating controls and the compact Settings dialog, in the earlier release's layout
   (translucent panels in one grey family since C113, 18 px corners, 320/330 px docks). */

#topbar {
  top: 0; left: 0; right: 0; height: var(--topbar-height); border-radius: 0; border-left: 0; border-right: 0; border-top: 0;
  background: linear-gradient(180deg, var(--vw-panel-strong), var(--vw-panel));
  border-bottom: 1px solid var(--vw-border-strong); box-shadow: 0 10px 34px var(--shadow-c2);
  backdrop-filter: blur(14px) saturate(.6); padding: 0 12px;
}
#topbar .btn.soon { opacity: .45; }
#topbar .spacer { flex: 1; }
/* One size for everything in the top bar (2026-10-06): every control --tb tall with the same corners, icon buttons
   square and never squeezed; the logo on the left. */
#topbar { --tb: 34px; gap: 8px; }
#topbar .brand { flex: none; margin-right: 4px; }
#topbar .brand .logo { display: block; height: 26px; width: auto; user-select: none; -webkit-user-drag: none; }
#topbar .btn, #topbar .input, #topbar select, #clock, #acct .me, #topbar .ec-chip { height: var(--tb); box-sizing: border-box; border-radius: 10px; }
#topbar .btn.icon { width: var(--tb); flex: none; font-size: 16px; }
#speed { gap: 6px; }
#speed .btn { height: var(--tb); padding: 0 10px; }
#speed .pause { width: var(--tb); padding: 0; }
#clock { padding: 0 12px; }
#topbar .searchb { display: none; }
@media (max-width: 760px) {
  #topbar { --tb: 32px; gap: 5px; }
  #topbar .brand { margin-right: 0; }
  #topbar .brand .logo { height: 20px; }
  /* search is a button; the field opens across the bar while it is used */
  #topbar .searchb { display: inline-grid; }
  #search { display: none; }
  #search.open { display: block; position: absolute; left: 6px; right: 6px; top: 50%; transform: translateY(-50%); z-index: 2; flex: none; }
  #search.open .results { right: 0; left: 0; width: auto; }
}
@media (max-width: 420px) { #speed .spd { display: none; } }
@media (max-width: 380px) { #topbar { gap: 3px; padding: 0 4px; } #clock { padding: 0 6px; } #clock .t { font-size: 13.5px; } #topbar .brand .logo { height: 16px; } #topbar .ec-chip { padding: 0 5px; gap: 3px; } }
@media (pointer: coarse) { #topbar .helpb { display: none; } }   /* the controls are a keyboard and mouse's (2026-10-06) */
#clock { flex: none; white-space: nowrap; }   /* room for the logo: the speed stays in the help's Space */

/* docks */
.dock {
  position: fixed; top: calc(var(--topbar-height) + 10px); bottom: 12px; width: var(--dock-lw); z-index: 3;
  display: flex; flex-direction: column; background: var(--vw-panel); border: 1px solid var(--vw-border);
  box-shadow: var(--shadow); backdrop-filter: blur(12px) saturate(.6);
  transition: transform .18s ease;
}
.dock.left { left: 0; border-left: 0; border-radius: 0 18px 18px 0; }
.dock.right { right: 0; width: var(--dock-rw); border-right: 0; border-radius: 18px 0 0 18px; }
.dock.left.closed { transform: translateX(calc(-1 * var(--dock-lw))); }
.dock.right.closed { transform: translateX(var(--dock-rw)); }
.dock-head { padding: 10px 14px; border-bottom: 1px solid var(--vw-border); display: flex; align-items: center; gap: 8px; }
.dock-head .dh { font-weight: 700; font-size: 13px; letter-spacing: .2px; color: var(--vw-accent); }
.dock-body { padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
/* A section keeps its full height and the dock scrolls as a whole. With the flex children shrinking by default, a long
   Selection panel was clipped by the Team section below it (the owner's report, 2026-09-28; Jev batch 33 .90). */
.dock-body > .dsec { flex: none; }
.dock-toggle {
  position: absolute; top: 16px; width: 34px; height: 46px; display: grid; place-items: center; font: inherit; cursor: pointer;
  background: var(--vw-panel-strong); border: 1px solid var(--vw-border-strong); color: var(--text); box-shadow: 0 12px 28px var(--shadow-c3);
}
.dock.left .dock-toggle { right: -35px; border-radius: 0 14px 14px 0; }
.dock.right .dock-toggle { left: -35px; border-radius: 14px 0 0 14px; }
.dock.right .dock-toggle.mark::after { content: ''; position: absolute; top: 5px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--vw-accent); }
.dsec { border-radius: var(--vw-radius-sm, 12px); overflow: hidden; }
.dsec-h { width: 100%; display: flex; align-items: center; gap: 8px; padding: 10px 12px; min-height: 44px; text-align: left;
  background: var(--wash); border: 1px solid var(--vw-border); border-radius: var(--vw-radius-sm, 12px); font-weight: 600; }
.dsec-h:hover { background: var(--hover-2); }
.dsec.open .dsec-h { border-color: var(--vw-border-strong); border-radius: 12px 12px 0 0; color: var(--vw-accent); }
.dsec-h .caret { color: var(--dim); font-size: 11px; width: 10px; }
.dsec-b { display: none; padding: 8px; border: 1px solid var(--vw-border); border-top: 0; border-radius: 0 0 12px 12px; background: var(--wash); }
.dsec.open .dsec-b { display: block; }
.dpad { display: grid; gap: 8px; }
.btn.wide { width: 100%; text-align: left; }
.dtabs { display: flex; gap: 4px; margin-bottom: 8px; }
.dtab { flex: 1; padding: 7px 6px; border-radius: 9px; background: var(--ghost); border: 1px solid var(--vw-border); font-size: 12px; }
.dtab.on { border-color: var(--vw-border-strong); color: var(--vw-accent); background: var(--btn-hover); }
.dlist { display: flex; flex-direction: column; gap: 3px; max-height: 300px; overflow-y: auto; }
.ditem { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 9px; background: none; border: 0; text-align: left; width: 100%; }
.ditem:hover { background: var(--hover-1); }
.ditem .di { width: 22px; text-align: center; flex: none; }
.ditem .dn { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ditem small { color: var(--dim); font-size: 11px; white-space: nowrap; }
/* Favourites (Jev batch 33): a star on the Selection panel and on every list row, and a ★ only filter beside the
   filter box. The one highlight marks it, as everywhere else (DECISIONS C113). An owned place shows a house and
   cannot be unstarred. */
.fbtn { background: none; border: 0; padding: 2px 5px; font-size: 15px; line-height: 1.1; color: var(--dim); cursor: pointer; border-radius: 8px; flex: none; }
.fbtn:hover { background: var(--line); color: var(--text); }
.fbtn.on { color: var(--strong); background: var(--lbl-shadow); }
.fbtn.owned { cursor: default; opacity: .9; }
.dfilters { display: flex; gap: 6px; align-items: center; }
.dfilters .input { flex: 1; min-width: 0; }
.staronly { padding: 4px 8px; font-size: 12px; white-space: nowrap; }
.tgroup { padding: 8px 8px 2px; color: var(--dim); font-size: 11px; font-weight: 600; letter-spacing: .04em; }
.tgroup:first-child { padding-top: 2px; }
.drow { display: flex; gap: 6px; align-items: center; }
.drow .minisel { width: auto; padding: 4px 6px; font-size: 12px; }
.own { color: var(--dim); font-size: 11px; }
#roster, .insp { position: static; width: auto; max-height: none; background: none; border: 0; box-shadow: none; padding: 0; }
#roster .list { max-height: 320px; overflow-y: auto; }
.insp .body { padding: 0; }
.dock .scroll { scrollbar-width: thin; }

/* floating controls: the minimap, zoom, player and chat (I3.1) */
#minimap { left: calc(var(--dock-lb, 0px) + 12px); bottom: 12px; z-index: 3; transition: left .18s ease; }   /* 12 px from the side and the bottom (2026-10-06) */
/* The floating controls sit 12 px from the side and the bottom alike (2026-10-06): they keep clear of an open dock only
   (--dock-rb), not of a closed dock's edge button up at the top. */
/* The bottom-right buttons (2026-10-06), top to bottom: Chat in a panel of its own, then one panel with Play, the map,
   the data map and Home — 12 px from the side (or an open dock) and from the bottom. */
#floatbtns .btn { width: 36px; height: 34px; padding: 0; border-radius: 9px; font-size: 16px; display: inline-grid; place-items: center; }
@media (pointer: coarse) { #floatbtns .btn { width: 42px; height: 40px; font-size: 18px; } }
#floatbtns .fb-chat, #floatbtns .fb-main { display: flex; flex-direction: column; gap: 4px; padding: 6px; }
#floatbtns .fb-main .player { order: 1; } #floatbtns .fb-main .wmapbtn { order: 2; } #floatbtns .fb-main .pmapbtn { order: 3; } #floatbtns .fb-main .zfit { order: 4; }
body.play #floatbtns .zfit { display: none; }   /* Home flies the camera: not while playing */
#floatbtns { position: fixed; right: calc(var(--dock-rb, 0px) + 12px); bottom: 12px; z-index: 3; display: flex; flex-direction: column; gap: 8px; transition: right .18s ease; }
#floatbtns .btn.on { border-color: var(--vw-border-strong); color: var(--vw-accent); }

/* the Settings dialog: tabs at its side (C112); the Agent Studio's and the Map's size and place (2026-10-08: the big
   windows one size — theme.css --win-w/--win-h), its forms kept to a readable width inside it */
.modal.auth.settings { display: grid; grid-template-columns: 200px 1fr; width: var(--win-w); height: var(--win-h); max-height: none; padding: 0; overflow: hidden;
  margin-top: var(--topbar-height, 56px); border-radius: 18px; }
.modal.auth.settings .st-body .atab { max-width: 900px; }
.modal.auth.settings > h3 { position: absolute; left: 14px; top: 8px; margin: 0; font-size: 12px; color: var(--dim); }
.st { display: grid; grid-template-columns: 200px 1fr; grid-template-rows: minmax(0, 1fr) auto; grid-column: 1 / 3; min-height: 0; }
.st-tabs { flex-direction: column; gap: 3px; flex-wrap: nowrap; padding: 30px 8px 8px; border-right: 1px solid var(--vw-border); overflow-y: auto; }
.st-tabs .tab { text-align: left; justify-content: flex-start; min-height: 34px; }
.st-tabs .tab.on { border-color: var(--vw-border-strong); color: var(--vw-accent); background: var(--line); }
.st-body { padding: 16px 18px; overflow-y: auto; display: block; max-height: none; }
.st-body .atab { display: grid; gap: 10px; align-content: start; }
.st-body h4 { margin: 0 0 4px; }
.kv2 { display: grid; grid-template-columns: 110px 1fr; gap: 4px 8px; font-size: 13px; }
.kv2 span { color: var(--dim); }
.st-body .adm-table { font-size: 12px; }
.st-body .adm-tabs { flex-wrap: wrap; }

/* phones: the docks become drawers (I3.6) */
@media (max-width: 760px) {
  :root { --dock-lw: min(calc(100vw - 56px), 340px); --dock-rw: min(calc(100vw - 56px), 360px); }
  .dock { top: calc(var(--topbar-height) + 6px); bottom: 6px; }
  .dock-toggle { width: 48px; height: 48px; top: 12px; }
  .dock.left .dock-toggle { right: -49px; }
  .dock.right .dock-toggle { left: -49px; }
  .dsec-h, .ditem, .dtab { min-height: 48px; }
  #minimap { display: none; }

  /* a phone: the screen under the top bar, as the Agent Studio and the Map */
  .modal.auth.settings { grid-template-columns: 1fr; width: 100vw; height: calc(100dvh - var(--topbar-height, 44px)); margin-top: var(--topbar-height, 44px);
    border-radius: 0; border-left: 0; border-right: 0; }
  .st { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .st-tabs { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; padding: 26px 8px 6px; border-right: 0; border-bottom: 1px solid var(--vw-border); }
  .st-tabs .tab { min-height: 44px; white-space: nowrap; }
}
.dock .toolpanel { position: static; transform: none; inset: auto; width: auto; min-width: 0; max-width: none; max-height: none; padding: 0; background: none; border: 0; box-shadow: none; }
.dock .toolpanel h4 { margin: 0 0 8px; }
.dock .toolpanel h4 .row { flex-wrap: wrap; }
.dock.hidden, .dsec.hidden { display: none !important; }
.modal.auth.settings .st { grid-template-rows: 1fr auto; }
.st-foot { grid-column: 1 / 3; display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 8px 12px; border-top: 1px solid var(--vw-border); }
.st-foot .st-note { font-size: 11px; }
/* Stacking: the docks sit above the world, the floating controls beside them, and menus, messages and dialogs above
   all of it (the account menu opens over the right dock). */
.dock { z-index: 2; }
#floatbtns { z-index: 3; }
#elev, #playbar, #phud, #pbtns, #joy, #fade { z-index: 4; }
#acctmenu, #toasts { z-index: 6; }
#help, #tip { z-index: 6; }
#topbar { z-index: 4; }   /* above the docks and floating controls, so its search results drop over them; dialogs stay above it */
#floorw { z-index: 3; }
/* The top bar on a phone: the essentials only, so the account chip stays on screen (I3.6). */
@media (max-width: 760px) {
  :root { --topbar-height: 44px; }
  #topbar { height: 44px; gap: 4px; padding: 0 6px; }
  #topbar .undo, #topbar .redo { display: none; }
  #search { flex: 1 1 84px; min-width: 54px; }
  #search input { width: 100%; min-width: 0; }
  #acct .me { padding: 3px 6px 3px 3px; max-width: 106px; }
  #acct .me .nm { max-width: 58px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #acct .me .rl { display: none; }
}

/* ---------- WP1.7 revision (DECISIONS C113, C114) ---------- */

/* Each dock's arrow points the way the dock will move: out when closed, back when open (I3.12). */
.dock-toggle .ca { display: inline-block; transition: transform .25s ease; }
.dock:not(.closed) .dock-toggle .ca { transform: rotate(180deg); }
/* Play mode gives the whole screen to the walk, as the earlier release did. */
body.play .dock, body.play .dock-scrim { display: none !important; }
/* The city counts, pinned under the info dock's title (I3.9). */
.dock-strip { padding: 8px 10px; border-bottom: 1px solid var(--vw-border); }
#topbar .btn .ptr { width: 16px; height: 16px; fill: currentColor; }
/* The phone scrim: a tap on the world beside an open drawer closes it. */
.dock-scrim { position: fixed; left: 0; right: 0; bottom: 0; top: var(--topbar-height); background: var(--scrim-2); z-index: 1; }
@media (max-width: 760px) {
  .dock { z-index: 5; }
  .dock-scrim { z-index: 4; }
  /* One drawer at a time: while one is open, the other's edge button and the floating controls step aside. */
  .drawer-open .dock.closed .dock-toggle { display: none; }
  .drawer-open #floatbtns, .drawer-open #floorw, .drawer-open #minimap { display: none !important; }
  #speed .spd { min-width: 44px; padding: 0 7px; }
  #speed .btn { padding: 0 7px; }
}
@media (max-width: 480px) { #clock .sun { display: none; } }
/* On a phone the help sheet hangs from the bottom, under the top bar, and scrolls. */
@media (max-width: 760px) {
  #help { top: auto; bottom: 8px; transform: translateX(-50%); max-height: calc(100vh - 64px); }
  #help h3 { top: -16px; }
  #help td:first-child { width: 38%; }
  /* The Settings dialog on a phone: the tabs scroll across the top, the page below them, the footer last. The
     footer's desktop span of both columns would force an implicit second column and squeeze the tabs (phone audit,
     2026-09-28). */
  .modal.auth.settings .st { grid-template-columns: 1fr; grid-template-rows: auto 1fr auto; }
  .st-foot { grid-column: 1; }
}
/* One grey family for the parts the browser draws itself too (C113): native controls, focus rings, text selection. */
input[type=checkbox], input[type=radio], input[type=range] { accent-color: var(--avatar); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
::selection { background: var(--sel); color: var(--strong); }
/* Play mode: the walk keeps the screen; the zoom column would sit on the play bar. On touch screens the Player/Chat
   column and the minimap would sit on the joystick and the action buttons; the play bar has Leave. */
@media (pointer: coarse) { body.play #floatbtns, body.play #minimap { display: none; } }
/* In play mode on a touch screen the play bar sits under the top bar, so the messages move below it. */
@media (pointer: coarse) { body.play #toasts { top: 106px; } }

/* ---------- the activity log and undo/redo (WP1.8, DECISIONS C116) ---------- */
/* The activity log (ui/activity.js, 2026-10-06): filters, the days as headings, then a timeline — time, a dot coloured by
   kind on a line joining the dots, and a card with what happened, who, when and its actions. */
.alog { display: grid; gap: 10px; }
.al-filters { display: flex; flex-wrap: nowrap; gap: 3px; overflow-x: auto; scrollbar-width: none; }
.al-filters .btn { flex: 1 1 auto; justify-content: center; padding: 4px 6px; font-size: 11.5px; }
.al-list { display: flex; flex-direction: column; max-height: min(560px, 62vh); overflow-y: auto; padding-right: 2px; }
.al-day { position: sticky; top: 0; z-index: 1; padding: 8px 2px 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); background: linear-gradient(180deg, var(--panel-strong) 70%, transparent); }
.al-item { --k: var(--text); position: relative; display: grid; grid-template-columns: 52px 26px 1fr; gap: 0 8px; padding: 0 0 12px; }
.al-item.k-edit { --k: var(--accent); }
.al-item.k-revert, .al-item.k-undo, .al-item.k-redo { --k: var(--gold); }
.al-item.k-residents { --k: var(--good); }
.al-item.k-agent { --k: var(--gold); }
.al-item.k-player { --k: var(--dim); }
.al-item::before { content: ''; position: absolute; left: calc(52px + 8px + 12px); top: 26px; bottom: 0; width: 2px; background: var(--line); }   /* the line to the next dot */
.al-item:last-child::before, .al-item:has(+ .al-day)::before { display: none; }
.al-time { padding-top: 5px; font-size: 11.5px; color: var(--dim); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.al-dot { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: 13px; color: var(--k);
  background: color-mix(in srgb, var(--k) 16%, var(--panel-strong)); border: 1px solid color-mix(in srgb, var(--k) 45%, transparent); z-index: 1; }
.al-card { min-width: 0; padding: 4px 10px 8px; border-radius: 10px; border: 1px solid transparent; transition: background .15s, border-color .15s; }
.al-item.has-place .al-card { cursor: pointer; }
.al-item.has-place:hover .al-card { background: var(--hover-1); border-color: var(--line); }
.al-text { font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.al-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 3px; font-size: 11.5px; color: var(--dim); }
.al-meta b { color: var(--text); font-weight: 600; }
.al-sep { opacity: .6; }
.al-pill { margin-left: 4px; padding: 0 7px; border-radius: 20px; font-size: 10.5px; border: 1px solid var(--line); color: var(--text); }
.al-task { margin-top: 6px; padding: 6px 9px; border-left: 2px solid var(--k); border-radius: 0 8px 8px 0; background: var(--hover-1); font-size: 12px; color: var(--dim); overflow-wrap: anywhere; }
.al-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.al-acts .btn { padding: 3px 9px; font-size: 11.5px; }
.al-item.off .al-text { color: var(--dim); text-decoration: line-through; text-decoration-color: var(--hl-line); }
.al-empty { display: grid; justify-items: center; gap: 6px; padding: 22px 12px; text-align: center; color: var(--dim); }
.al-empty span { font-size: 26px; opacity: .7; }
.al-empty p { margin: 0; font-size: 12.5px; line-height: 1.45; }
.act-more { margin-top: 6px; }
.dock-undo { display: none; margin-left: auto; gap: 6px; }
@media (max-width: 760px) {
  .dock-undo { display: flex; }
  .dock-undo .btn { width: 48px; height: 48px; font-size: 18px; }
  #dockL .dock-head { padding-top: 4px; padding-bottom: 4px; }
  .al-acts .btn { min-height: 36px; padding: 6px 12px; }
  .act-revert { min-height: 44px; min-width: 64px; }
}

/* ---------- Settings → About: the notice lists (WP1.9, I13.9) ---------- */
.notice-list { margin: 4px 0 2px; padding-left: 18px; color: var(--text); font-size: 12.5px; line-height: 1.5; }
.notice-list li { margin: 1px 0; }
.notice-list b { font-weight: 600; }
.aform h5, .st-body h5 { margin: 10px 0 2px; font-size: 12.5px; color: var(--vw-accent); letter-spacing: .2px; }

/* ---------- players, friends, status, proximity chat (WP1.10, DECISIONS C118) ---------- */
.lbl .tagname.player { border-color: var(--good-line); }
.lbl .tagname.player.friend { border-color: var(--gold-line); }
.lbl .tagname.player.obs { background: var(--label-2); color: var(--dim); }
.lbl .tagname .obs-t { margin-left: 6px; font-size: 10px; font-weight: 500; color: var(--dim); text-transform: uppercase; letter-spacing: .4px; }
.soc-status { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; }
.soc-status select { width: auto; }
.soc-h { margin: 10px 0 4px; font-size: 12px; color: var(--dim); text-transform: uppercase; letter-spacing: .4px; }
.soc-h .n { text-transform: none; }
.soc-r, .soc-f { display: flex; align-items: center; gap: 6px; padding: 5px 6px; border-radius: 9px; font-size: 12.5px; }
.soc-r { background: var(--gold-soft); margin-bottom: 4px; }
.soc-r.out { background: var(--wash); }
.soc-r span, .soc-f span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.soc-f small { color: var(--dim); font-size: 11px; }
.soc-p.you .dn { font-weight: 700; }
.soc-add { gap: 6px; margin-bottom: 4px; }
.soc-add .input { flex: 1; min-width: 0; }
#pchat { position: fixed; left: 50%; bottom: 118px; transform: translateX(-50%); width: min(460px, calc(100vw - 24px)); padding: 8px; display: flex; flex-direction: column; gap: 6px; }
#pchat .pc-log { max-height: 150px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; }
#pchat .pc-log:empty { display: none; }
#pchat .pc-l b { color: var(--accent); margin-right: 4px; }
#pchat .pc-l.you b { color: var(--good); }
#pchat .pc-form { gap: 6px; }
#pchat .pc-in { flex: 1; min-width: 0; }
#pchat.pc-ro .pc-form { display: none; }   /* a phone: what people near you said, a tap answers */
#pchat.pc-ro .pc-log { cursor: pointer; }
@media (pointer: coarse) { body.play #pchat { left: 12px; right: 96px; width: auto; transform: none; } }   /* clear of E, jump and chat */
#pbtns .btn.soon { opacity: .45; }
@media (max-width: 760px) {
  #pchat { bottom: 236px; }
  .soc-r .btn, .soc-f .btn, .soc-add .btn { min-height: 44px; }
}

/* ---------- demo mode (WP1.11, DECISIONS E19): visible, openable, greyed out and unusable ---------- */
#demo-mark { position: fixed; left: 50%; bottom: 10px; transform: translateX(-50%); z-index: 40; display: flex; gap: 8px; align-items: center;
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--gold-line); background: var(--gold-soft); color: inherit; font-size: 12px; cursor: pointer; opacity: .92; }
#demo-mark b { letter-spacing: .6px; }
body.play #demo-mark { bottom: auto; top: 10px; }
body.demo-locked #dockL .dsec-b > *, body.demo-locked #buildp > :not(h4), body.demo-locked #furnp > :not(h4),
body.demo-locked [data-cap="world.edit"], body.demo-locked #buildp h4 .addp, body.demo-locked .undo, body.demo-locked .redo,
body.demo-locked .act-revert, body.demo-locked .revert {
  opacity: .42; filter: grayscale(.7); pointer-events: none; user-select: none;
}
body.demo-locked #dockL .dsec-b::before, body.demo-locked #buildp::after, body.demo-locked #furnp::after {
  content: '🔒 Locked in demo mode: a licence key unlocks editing'; display: block; margin: 0 0 6px; padding: 4px 8px; border-radius: 8px;
  background: var(--gold-soft); font-size: 11.5px;
}
body.demo-locked #buildp::after, body.demo-locked #furnp::after { margin: 6px 0 0; }
.lic-act { gap: 6px; } .lic-act .input { flex: 1; min-width: 0; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* Settings → Connections (WP2.2) */
.conn { border: 1px solid var(--line-3, var(--line)); border-radius: 10px; padding: 10px; margin: 8px 0; display: grid; gap: 6px; }
.conn-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.conn .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--dim); flex: none; }
.conn .dot.ok { background: var(--good, #4caf7a); } .conn .dot.bad { background: var(--bad, #e05a5a); } .conn .dot.later { background: var(--warn, #d9a441); }
.conn-state { font-size: 12px; color: var(--dim); } .conn-state.ok { color: var(--good, #4caf7a); } .conn-state.bad { color: var(--bad, #e05a5a); }
.conn .tag { font-size: 11px; padding: 1px 6px; border-radius: 6px; border: 1px solid var(--line-3, var(--line)); color: var(--dim); }

/* A connected agent's chat (WP2.14 follow-up): a panel beside the right dock */

/* Property (WP4.14) */
.property .row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0; }
.property .legend { display: flex; flex-wrap: wrap; gap: 4px 10px; margin: 4px 0 8px; }
.property .lg i { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin-right: 4px; vertical-align: -1px; border: 1px solid rgba(255,255,255,.35); }
.property .kv { display: flex; justify-content: space-between; gap: 10px; padding: 2px 0; border-bottom: 1px solid var(--line); }
.property .kv span { opacity: .75; }
.property .kv b { font-weight: 600; text-align: right; }
.property h4 { margin: 8px 0 4px; }
.property .hist { margin: 4px 0 0 18px; padding: 0; max-height: 180px; overflow: auto; font-size: 12px; }
.property .btn.sm { padding: 3px 7px; font-size: 12px; }
.property input, .property select { max-width: 100%; }
/* Roads section of the edit dock (WP4.4) */
.roads .row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0; }
.roads label.row input, .roads label.row select { flex: 1; min-width: 0; }
.roads .inspector h4 { margin: 8px 0 4px; }
.roads .status.bad { color: var(--bad, #f87171); }

/* Interior walls (ui/walls-tool.js): the length beside a wall being drawn or moved */
.wall-len { position: fixed; transform: translate(-50%, -110%); padding: 3px 8px; border-radius: 8px; background: rgba(18, 24, 33, 0.88); color: #f4f7fa; font: 600 12px/1.3 system-ui, sans-serif; pointer-events: none; z-index: 40; white-space: nowrap; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); }
.wall-len.bad { background: rgba(140, 32, 32, 0.92); }
.wtools .wsel .wlen { font-weight: 600; margin-right: 6px; }
.wtools .row { gap: 6px; margin-bottom: 6px; }
@media (pointer: coarse) { .wtools .btn.small { min-height: 40px; padding: 6px 12px; } }
/* on a phone the wall tools float over the view while one is in use */
.wtools.floating { position: fixed; left: 8px; right: 8px; bottom: 84px; z-index: 35; padding: 8px 10px; max-height: 42vh; overflow: auto; }
.wtools .wdone { justify-content: flex-end; margin-bottom: 4px; }

/* ---------- building handles (ui/place-tool.js) ---------- */
#ui > #placehandles { position: fixed; inset: 0; pointer-events: none; z-index: 4; }
#placehandles .ph { position: absolute; left: 0; top: 0; pointer-events: auto; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
  font-size: 18px; line-height: 1; padding: 0; background: var(--bg2); color: var(--strong, #fff); border: 2px solid var(--vw-accent, #fff); box-shadow: 0 2px 10px rgba(0,0,0,.45); touch-action: none; cursor: grab; }
#placehandles .ph:active, #placehandles .ph.on { cursor: grabbing; background: var(--vw-accent, #fff); color: #111; }
#placehandles .ph-e, #placehandles .ph-w, #placehandles .ph-n, #placehandles .ph-s { font-size: 17px; }
#placehandles .ph i { font-style: normal; display: inline-grid; place-items: center; line-height: 0; }
#placehandles .ph-e i, #placehandles .ph-w i { rotate: var(--a, 0deg); }
#placehandles .ph-n i, #placehandles .ph-s i { rotate: var(--a, 90deg); }
#placehandles .ph-move { width: 46px; height: 46px; font-size: 24px; }
#placehandles .ph-up { border-color: var(--gold); }
#placehandles .ph-rot { border-color: #6fb7ff; }
#placehandles.dragging .ph:not(.on) { opacity: .45; }
#placehandles .pdim { position: absolute; left: 0; top: 0; pointer-events: none; padding: 2px 7px; border-radius: 8px; font-size: 12px; font-weight: 700;
  background: rgba(0,0,0,.62); color: #fff; white-space: nowrap; }
@media (pointer: coarse) { #placehandles .ph { width: 46px; height: 46px; font-size: 21px; } #placehandles .ph-move { width: 54px; height: 54px; font-size: 27px; } }
#placebar { position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%); width: min(560px, calc(100vw - 20px)); z-index: 5; padding: 10px 12px; display: grid; gap: 6px; }
#placebar .pb-types { display: flex; flex-wrap: nowrap; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
#placebar .pb-types .chip { flex: 0 0 auto; }
#placebar .pb-head { font-size: 14px; } #placebar .pb-dims { color: var(--dim); }
#placebar .pb-why { font-weight: 600; } #placebar .pb-why.bad { color: var(--bad); }
#placebar .pb-btns { display: flex; gap: 8px; justify-content: flex-end; }
#placebar .pb-btns .btn { min-height: 40px; padding: 8px 16px; font-size: 14px; }
@media (max-width: 760px) { #placebar { bottom: calc(8px + var(--kb, 0px)); padding-bottom: calc(10px + env(safe-area-inset-bottom)); } #placebar .pb-btns .btn { flex: 1; min-height: 46px; } }
body.placing #floatbtns, body.placing #minimap { opacity: .35; pointer-events: none; }
#placebar .pb-why.warn { color: var(--warn, #d9a441); }
/* resizing: floors changed by hand where something no longer fits (ui/place-tool.js chooseFit) */
.fit-back { z-index: 9; }
.fitdlg { width: min(480px, calc(100vw - 20px)); max-height: calc(100vh - 40px); overflow: auto; padding: 16px 18px; display: grid; gap: 10px; }
.fitdlg h3 { margin: 0; font-size: 17px; }
.fitdlg p { margin: 0; line-height: 1.4; }
.fitdlg .fit-list { margin: 0; padding-left: 20px; display: grid; gap: 4px; line-height: 1.4; }
.fitdlg .bad { color: var(--bad); }
.fitdlg .fit-btns { display: grid; gap: 8px; margin-top: 2px; }
.fitdlg .fit-btns .btn, .fitdlg .fit-each > .btn { min-height: 44px; padding: 8px 14px; font-size: 14px; white-space: normal; }
.fitdlg .btn:disabled { opacity: .45; cursor: not-allowed; }
.fitdlg .fit-more { justify-self: start; background: none; border: 0; padding: 4px 0; color: inherit; text-decoration: underline; cursor: pointer; font-size: 14px; }
.fitdlg .fit-each { display: grid; gap: 8px; border-top: 1px solid var(--line); padding-top: 10px; }
.fitdlg .fit-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.fitdlg .fit-row .seg { display: inline-flex; gap: 4px; }
.fitdlg .fit-row .seg .btn { min-height: 38px; }
@media (max-width: 760px) { .fit-back { place-items: end center; } .fitdlg { width: calc(100vw - 12px); margin-bottom: calc(6px + env(safe-area-inset-bottom)); } }

/* ---------- press-and-hold / right-click menu and the selected building's bar (ui/world-menu.js) ---------- */
#wmenu { position: fixed; z-index: 7; min-width: 220px; max-width: min(310px, calc(100vw - 16px)); padding: 6px; display: grid; gap: 2px; }
#wmenu .wm-head { padding: 6px 8px 8px; display: grid; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
#wmenu .wm-head b { font-size: 14px; }
#wmenu .wm-note { color: var(--dim); font-size: 12px; margin-top: 2px; }
#wmenu .wm-item { display: flex; gap: 10px; align-items: center; text-align: left; background: none; border: 0; border-radius: 8px; padding: 9px 10px; font-size: 14px; }
#wmenu .wm-item:hover { background: var(--btn-hover); }
#wmenu .wm-item.danger { color: var(--bad); }
#wmenu .ic { width: 22px; text-align: center; }
@media (pointer: coarse) { #wmenu .wm-item { padding: 12px; font-size: 15px; } }
@property --hold { syntax: '<percentage>'; inherits: false; initial-value: 0%; }
#ui > #holdring { position: fixed; left: 0; top: 0; z-index: 6; width: 68px; height: 68px; pointer-events: none; }
#holdring i { position: absolute; inset: 0; border-radius: 50%; background: conic-gradient(#fff var(--hold), rgba(255, 255, 255, .2) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 5px)); mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 5px)); }
#holdring.go i { animation: holdfill .34s linear forwards; }
@keyframes holdfill { to { --hold: 100%; } }
#selbar { position: fixed; left: 0; top: 0; z-index: 4; display: flex; gap: 4px; padding: 4px; border-radius: 14px; }
#selbar .btn { display: grid; place-items: center; gap: 1px; min-width: 50px; padding: 5px 8px; font-size: 17px; line-height: 1.1; }
#selbar .btn span { font-size: 11px; }
#selbar .btn.more { min-width: 38px; font-size: 20px; }
@media (pointer: coarse) { #selbar .btn { min-width: 56px; min-height: 48px; } }

/* ---------- the property map and lot cards (ui/property.js) ---------- */
#propbar { position: fixed; left: 50%; top: 58px; transform: translateX(-50%); z-index: 5; width: min(720px, calc(100vw - 20px)); padding: 8px 10px; display: grid; gap: 6px; }
#propbar .pbar-top { display: flex; gap: 8px; align-items: center; }
#propbar .pbar-top > b { white-space: nowrap; font-size: 14px; }
#propbar .seg { display: flex; gap: 4px; flex: 1; }
#propbar .seg .btn { flex: 1; min-height: 32px; }
#propbar .legend { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; align-items: center; }
#propbar .lg { flex: 0 0 auto; display: inline-flex; gap: 6px; align-items: center; padding: 4px 10px; border-radius: 16px; background: var(--btn); border: 1px solid var(--line); font-size: 12px; }
#propbar .lg i { width: 12px; height: 12px; border-radius: 4px; display: inline-block; box-shadow: 0 0 0 1px rgba(0,0,0,.35); }
#propbar .lg .n { color: var(--dim); font-weight: 700; }
#propbar .lg.on { border-color: var(--hl-line); background: var(--lbl-shadow); }
#propbar .lg.off { opacity: .45; }
#propbar .lg-note { flex: 0 0 auto; color: var(--dim); font-size: 11px; }
.seg .btn.on { background: linear-gradient(180deg, var(--btn-on-a), var(--btn-on-b)); border-color: var(--hl-line); color: var(--strong); }
#ui > #lotpins { position: fixed; inset: 0; pointer-events: none; z-index: 3; overflow: hidden; }
#lotpins .lotpin { position: absolute; left: 0; top: 0; pointer-events: auto; padding: 3px 9px; border-radius: 12px; font-size: 12px; font-weight: 700; white-space: nowrap;
  color: #111; background: #fff; border: 0; box-shadow: 0 2px 8px rgba(0,0,0,.45); }
#lotpins .lotpin::after { content: ''; position: absolute; left: 50%; bottom: -5px; margin-left: -5px; border: 5px solid transparent; border-bottom: 0; border-top-color: inherit; }
#lotpins .lotpin.sale { background: #2ee08a; } #lotpins .lotpin.mine { background: #ffc83d; } #lotpins .lotpin.sel { background: #fff; outline: 2px solid #111; }
#lotpins .lotpin.val { color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.6); min-width: 30px; }
#lotpins .lotpin.zone { background: rgba(255,255,255,.88); font-weight: 600; }
#lotpins .lotpin.add { background: #ffc83d; font-size: 14px; padding: 6px 12px; } #lotpins .lotpin.pk { background: #fff; }
@media (pointer: coarse) { #lotpins .lotpin { padding: 5px 11px; font-size: 13px; } }
#lotcard { position: fixed; right: calc(var(--dock-r, 0px) + 12px); top: 150px; z-index: 5; width: 350px; max-height: calc(100vh - 170px); overflow: auto; padding: 12px; display: grid; gap: 10px; }
#lotcard .lc-head { display: flex; gap: 10px; align-items: center; }
#lotcard .lc-head .dot { width: 16px; height: 16px; border-radius: 5px; flex: 0 0 auto; box-shadow: 0 0 0 1px rgba(0,0,0,.35); }
#lotcard .lc-title { display: grid; flex: 1; min-width: 0; } #lotcard .lc-title b { font-size: 16px; }
#lotcard .lc-note { margin: 0; font-style: italic; color: var(--dim); }
#lotcard .lc-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
#lotcard .lc-stats > div { background: var(--btn); border: 1px solid var(--line); border-radius: 10px; padding: 7px 9px; display: grid; gap: 1px; min-width: 0; }
#lotcard .lc-stats span { font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .04em; }
#lotcard .lc-stats b { font-size: 13px; overflow: hidden; text-overflow: ellipsis; } #lotcard .lc-stats small { color: var(--dim); font-size: 11px; }
#lotcard .lc-stats a { color: inherit; }
#lotcard .lc-acts { display: flex; flex-wrap: wrap; gap: 6px; } #lotcard .lc-acts .btn { min-height: 38px; }
#lotcard .lc-sec { border-top: 1px solid var(--line); padding-top: 8px; } #lotcard .lc-sec summary { cursor: pointer; font-weight: 600; padding: 2px 0 6px; }
#lotcard .fld { display: grid; gap: 4px; margin: 6px 0; font-size: 12px; color: var(--dim); }
#lotcard .fld .input, #lotcard textarea { width: 100%; }
#lotcard .dels { margin: 2px 0; padding-left: 16px; color: var(--text); }
#lotcard .share { margin-top: 4px; } #lotcard .hist { padding-left: 18px; margin: 4px 0; font-size: 12px; }
#mergebar { position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 5; width: min(520px, calc(100vw - 20px)); padding: 10px 12px; display: grid; gap: 8px; }
#mergebar .mb-btns { display: flex; gap: 8px; justify-content: flex-end; } #mergebar .mb-btns .btn { min-height: 40px; padding: 8px 16px; font-size: 14px; }
#floatbtns .pmapbtn.on { border-color: var(--vw-border-strong); color: var(--vw-accent); background: var(--btn-hover); }
@media (max-width: 760px) {
  #propbar { top: 52px; width: calc(100vw - 12px); padding: 6px 8px; }
  #propbar .pbar-top > b { display: none; }
  #lotcard { left: 0; right: 0; top: auto; bottom: var(--kb, 0px); width: auto; max-height: min(56vh, calc(var(--vvh, 100vh) - 64px)); border-radius: 16px 16px 0 0; padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
  #lotcard .lc-acts .btn { flex: 1 1 auto; min-height: 44px; }
  #mergebar { bottom: calc(8px + var(--kb, 0px)); } #mergebar .mb-btns .btn { flex: 1; min-height: 46px; }
}

/* ---------- a floor picked from outside (ui/ui.js floorTag) ---------- */
#floortag { position: fixed; left: 0; top: 0; z-index: 4; padding: 5px 11px; border-radius: 14px; border: 0; font-size: 12px; font-weight: 700; white-space: nowrap;
  background: #ffc83d; color: #111; box-shadow: 0 2px 10px rgba(0,0,0,.45); }
#floortag::after { content: ''; position: absolute; left: 50%; bottom: -5px; margin-left: -5px; border: 5px solid transparent; border-bottom: 0; border-top-color: #ffc83d; }
@media (pointer: coarse) { #floortag { padding: 7px 13px; font-size: 13px; } }
.insp .floors .btn.pick { border-color: #ffc83d; box-shadow: inset 0 0 0 1px #ffc83d; }

/* ------------------------------------------------------------------ the shop (platform edition; ui/shop.js, ui/shop-admin.js) */
.shop-dock { display: grid; gap: 6px; margin-top: 8px; }
.shop-dock .row { display: flex; gap: 6px; flex-wrap: wrap; }
.shop-dock .btn { flex: 1 1 auto; }
.lc-shop, .flat-shop { display: grid; gap: 8px; }
.lc-shop:empty { display: none; }
.lc-shop .row, .flat-shop .row { display: flex; gap: 6px; align-items: center; }
.lc-shop .row.wrap, .flat-shop .row.wrap { flex-wrap: wrap; }
.shop-price { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 2px 10px; padding: 9px 11px; border-radius: 10px;
  background: linear-gradient(180deg, rgba(46, 224, 138, .14), rgba(46, 224, 138, .05)); border: 1px solid rgba(46, 224, 138, .38); }
.shop-price > span { color: var(--dim); font-size: 12px; }
.shop-price > b { font-size: 20px; letter-spacing: .2px; grid-row: span 2; }
.shop-price b small, .sum-row b small, .mk-price small { font-size: 12px; font-weight: 600; color: var(--dim); margin-left: 2px; }
.shop-price > small { color: var(--dim); font-size: 11px; }
/* the realty market (server/commerce/market.js): a lot's value today, and the offer's price beside the regular one */
.shop-value { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 2px 10px; padding: 7px 11px; border-radius: 10px; border: 1px solid var(--line); background: var(--btn); }
.shop-value > span { color: var(--dim); font-size: 12px; }
.shop-value > b { font-size: 16px; grid-row: span 3; }
.shop-value > small { font-size: 11px; color: var(--dim); }
.shop-value > small.good { color: var(--good); } .shop-value > small.bad { color: var(--bad, #ff7a7a); }
s.was { color: var(--dim); font-weight: 500; font-size: .7em; margin-right: 4px; }
.shop-sale { margin: 4px 0; padding: 6px 10px; border-radius: 9px; font-size: 12px; background: linear-gradient(90deg, rgba(255, 170, 60, .18), rgba(255, 90, 120, .1)); border: 1px solid rgba(255, 170, 60, .45); }
.sum-row.sale span, .sum-row.sub span { color: var(--dim); font-size: 12px; } .sum-row.sub b { font-weight: 500; font-size: 13px; }
.shop-note { padding: 8px 10px; border-radius: 10px; border: 1px solid var(--line); background: var(--btn); display: grid; gap: 6px; font-size: 13px; }
.shop-note.good { border-color: var(--good-line, rgba(94, 224, 143, .5)); }
.shop-offers { display: grid; gap: 6px; }
.shop-offer { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 7px 9px; border-radius: 9px; border: 1px solid var(--line); background: var(--btn); flex-wrap: wrap; }
.shop-offer span { display: grid; gap: 1px; } .shop-offer small { color: var(--dim); font-size: 11px; } .shop-offer small.good, .good { color: var(--good); }
.shop-pf { display: grid; gap: 7px; }
.shop-pf .fld, .shopadm .fld { display: grid; gap: 4px; font-size: 13px; }
.shop-pf .row { display: flex; gap: 6px; align-items: center; }
.shop-pf .cur { font-weight: 700; color: var(--dim); min-width: 12px; }
.shop-pf .input { flex: 1; min-width: 0; padding: 7px 9px; border-radius: 8px; border: 1px solid var(--line); background: var(--btn); color: inherit; font: inherit; }
.shop-kind { display: flex; gap: 4px; }
.shop-kind .btn { flex: 1; min-height: 34px; }
.shopdlg { width: min(470px, calc(100vw - 20px)); }
/* Plan & usage (ui/plans.js): the plan, this month's meters, the plans side by side (one under another on a phone) */
.shopdlg.plandlg { width: min(940px, calc(100vw - 20px)); max-height: calc(100vh - 40px); overflow-y: auto; }
.pl-cur h4 { margin: 2px 0; font-size: 18px; }
.pl-cur small { color: var(--dim); text-transform: uppercase; letter-spacing: .06em; font-size: 10.5px; }
.pl-st { font-size: 12.5px; color: var(--dim); }
.pl-st.active { color: #4ade80; } .pl-st.ending { color: #facc15; } .pl-st.past_due { color: #f87171; }
.pl-meters { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px 16px; margin: 10px 0; }
.pl-meter .row { justify-content: space-between; font-size: 12.5px; gap: 8px; }
.pl-meter .st-meter { height: 6px; border-radius: 4px; background: var(--line); overflow: hidden; margin-top: 3px; }
.pl-meter .st-meter i { display: block; height: 100%; background: #38bdf8; }
.pl-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; margin: 10px 0; }
.pl-card { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; display: grid; gap: 6px; align-content: start; }
.pl-card.on { border-color: #38bdf8; box-shadow: 0 0 0 1px #38bdf8 inset; }
.pl-card .row { justify-content: space-between; align-items: baseline; }
.pl-card .row b { font-size: 15px; }
.pl-card .row small { color: var(--dim); }
.pl-card ul { margin: 0; padding-left: 0; list-style: none; display: grid; gap: 4px; font-size: 12.5px; line-height: 1.35; }
.pl-card .btn, .pl-card .tag { justify-self: start; }
.pl-pack { justify-content: space-between; gap: 10px; font-size: 12.5px; margin: 4px 0 8px; }
.pl-terms { display: flex; gap: 6px; align-items: center; font-size: 12.5px; margin: 6px 0; }
@media (max-width: 640px) { .pl-cards { grid-template-columns: 1fr; } .pl-pack { flex-wrap: wrap; } }
.shopdlg .shop-sum { display: grid; gap: 7px; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--line); background: var(--btn); }
.shopdlg .sum-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.shopdlg .sum-row.title span { font-weight: 600; } .shopdlg .sum-row.total { border-top: 1px solid var(--line); padding-top: 7px; font-size: 16px; }
.shopdlg .sum-row.total b { font-size: 20px; }
.shopdlg .shop-terms { font-size: 13px; line-height: 1.4; align-items: flex-start; display: flex; gap: 8px; }
.shopdlg .shop-terms input { margin-top: 3px; flex: 0 0 auto; }
.shopdlg .shop-terms a, .shopadm a { color: var(--accent); }
.shopdlg .sc-err:empty { display: none; }
.shopdlg .lib-btns .btn.primary { min-width: 190px; }
.shop-spin { width: 34px; height: 34px; border-radius: 50%; border: 3px solid var(--line); border-top-color: var(--good); animation: shopspin .8s linear infinite; justify-self: center; margin: 8px; }
@keyframes shopspin { to { transform: rotate(360deg); } }
.walletdlg { width: min(560px, calc(100vw - 20px)); }
.walletdlg .wl-bal { display: grid; gap: 2px; padding: 12px 14px; border-radius: 12px; background: linear-gradient(135deg, rgba(255, 200, 61, .16), rgba(46, 224, 138, .10)); border: 1px solid rgba(255, 200, 61, .35); }
.walletdlg .wl-bal span { font-size: 12px; color: var(--dim); } .walletdlg .wl-bal b { font-size: 26px; } .walletdlg .wl-bal small { color: var(--dim); font-size: 11px; line-height: 1.35; }
.walletdlg .wl-tabs, .marketdlg .mk-tabs { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; }
.walletdlg .wl-tabs .btn, .marketdlg .mk-tabs .btn { flex: 1 0 auto; min-height: 34px; }
.walletdlg .badge { display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 9px; background: var(--bad); color: #fff; font-size: 11px; line-height: 18px; }
.walletdlg .wl-body { display: grid; gap: 8px; max-height: min(52vh, 480px); overflow-y: auto; }
.walletdlg h4 { margin: 4px 0 0; font-size: 13px; color: var(--dim); text-transform: uppercase; letter-spacing: .4px; }
.walletdlg .wl-row, .walletdlg .lib-row { grid-template-columns: 1fr auto; align-items: center; }
.walletdlg .lib-acts { justify-content: flex-end; align-items: center; }
.marketdlg .mk-row { display: grid; grid-template-columns: 1fr auto; align-items: center; text-align: left; background: var(--btn); color: inherit; font: inherit; cursor: pointer; }
.marketdlg .mk-row:hover { border-color: var(--hl-line); }
.marketdlg .mk-price { font-size: 16px; white-space: nowrap; }
.shopadm .sh-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 12px; }
.shopadm .sh-orders { display: grid; gap: 5px; max-height: 300px; overflow-y: auto; }
.shopadm .sh-order { display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: center; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; }
.shopadm .sh-order span { display: grid; min-width: 0; } .shopadm .sh-order small { color: var(--dim); font-size: 11px; overflow: hidden; text-overflow: ellipsis; }
.shopadm .sh-order.bad { border-color: var(--bad); }
.shopadm .sh-probs { margin: 0; padding-left: 18px; } .shopadm .sh-probs .bad { color: var(--bad); }
.shopadm code { font-size: 11px; word-break: break-all; }
#lotpins .lotpin.sale { color: #08311d; }
/* the shop's ads (ui/ads.js): the panel when an ad is tapped, the builder, the wallet's ads and the review queue */
.addlg { width: min(520px, calc(100vw - 20px)); }
.addlg .ad-big, .adbuild .ab-fig canvas { width: 100%; height: auto; display: block; border-radius: 8px; border: 1px solid var(--line); background: #10141a; }
.addlg .ad-msg { white-space: pre-wrap; font-size: 15px; }
.addlg .ad-visit { justify-self: start; }
.addlg .ad-stats { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 13px; color: var(--dim); }
.addlg .ad-stats b { color: var(--strong, inherit); }
.addlg .ad-spaces { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.addlg .ad-space { display: grid; gap: 2px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--btn); }
.addlg .ad-space .dim { font-size: 12px; color: var(--dim); }
.addlg .ad-how { margin: 0; padding-left: 18px; display: grid; gap: 4px; font-size: 13px; line-height: 1.4; }
.adbuild { width: min(620px, calc(100vw - 20px)); }
.adbuild .ab-sec { display: grid; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; }
.adbuild .ab-h { font-size: 13px; text-transform: uppercase; letter-spacing: .4px; color: var(--dim); }
.adbuild .ab-spaces { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.adbuild .ab-space, .adbuild .ab-tier { display: grid; gap: 3px; text-align: left; padding: 9px 11px; border-radius: 10px; border: 1px solid var(--line); background: var(--btn); color: inherit; font: inherit; cursor: pointer; }
.adbuild .ab-space span { font-size: 12px; color: var(--dim); line-height: 1.35; } .adbuild .ab-space small { font-size: 11px; color: var(--dim); }
.adbuild .ab-space.on, .adbuild .ab-tier.on { border-color: var(--hl-line); background: linear-gradient(180deg, var(--btn-on-a), var(--btn-on-b)); }
.adbuild .ab-space:disabled { opacity: .5; cursor: not-allowed; }
.adbuild .ab-preview { display: grid; gap: 8px; }
.adbuild .ab-fig { margin: 0; display: grid; gap: 3px; }
.adbuild .ab-fig figcaption { font-size: 11px; color: var(--dim); text-align: center; }
.adbuild .ab-fig.bb { padding: 8px 8px 22px; border-radius: 10px; background: linear-gradient(180deg, #2a2e35, #1b1e23); position: relative; }
.adbuild .ab-fig.bb::after { content: ''; position: absolute; left: calc(50% - 7px); bottom: 0; width: 14px; height: 22px; background: #6d737a; }
.adbuild .ab-fig.bb figcaption { position: absolute; right: 10px; bottom: 3px; color: #c9ced6; }
.adbuild .ab-fig.cloth canvas { border-radius: 2px; }
.adbuild .ab-format, .adbuild .ab-billing, .adbuild .ab-paywith, .shopdlg .sc-pay { display: flex; gap: 4px; }
.adbuild .ab-format .btn, .adbuild .ab-billing .btn, .adbuild .ab-paywith .btn, .shopdlg .sc-pay .btn { flex: 1; min-height: 34px; }
.adbuild .ab-pic { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.adbuild .ab-pic .dim { font-size: 12px; color: var(--dim); }
.adbuild .fld { display: grid; gap: 4px; font-size: 13px; }
.adbuild .input { padding: 7px 9px; border-radius: 8px; border: 1px solid var(--line); background: var(--btn); color: inherit; font: inherit; min-width: 0; }
.adbuild textarea.input { resize: vertical; }
.adbuild .ab-colors, .adbuild .ab-place { display: flex; flex-wrap: wrap; gap: 8px 16px; font-size: 13px; align-items: center; }
.adbuild .ab-colors label, .adbuild .ab-place label { display: flex; gap: 6px; align-items: center; }
.adbuild .ab-colors input[type=color] { width: 40px; height: 28px; padding: 0; border: 1px solid var(--line); border-radius: 6px; background: none; }
.adbuild .ab-place input[type=range] { width: 110px; }
.adbuild .ab-start { display: grid; gap: 4px; font-size: 13px; }
.adbuild .ab-start .check { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.adbuild .ab-start .ab-at { width: auto; max-width: 100%; padding: 4px 8px; }
.adbuild .ab-tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.adbuild .ab-tiers .hint { grid-column: 1 / -1; }
.adbuild .ab-tier span { font-size: 11px; color: var(--dim); } .adbuild .ab-tier .ab-tp { font-size: 15px; } .adbuild .ab-tier .ab-tp small { font-size: 11px; color: var(--dim); font-weight: 600; }
.adbuild .ab-err:empty { display: none; }
.adbuild .ab-preview.many { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); align-items: end; }
.adbuild .ab-fig.tall { justify-self: center; width: min(190px, 60%); padding: 6px 6px 26px; border-radius: 8px; background: linear-gradient(180deg, #2a2e35, #1b1e23); position: relative; }
.adbuild .ab-fig.tall::after { content: ''; position: absolute; left: calc(50% - 16px); bottom: 0; width: 32px; height: 24px; background: #3b3f45; }
.adbuild .ab-fig.tall figcaption { position: absolute; right: 8px; bottom: 4px; color: #c9ced6; }
.adbuild .ab-fig.plain { padding: 6px; border-radius: 8px; background: #1f2226; }
.adbuild .ab-fig.plain figcaption { color: #c9ced6; }
.adbuild .designer { display: grid; gap: 8px; }
.adbuild .ab-fig { position: relative; touch-action: none; }
.adbuild .ab-fig canvas { cursor: grab; }
.adbuild .pv-box { position: absolute; border: 1.5px dashed rgba(255, 255, 255, .85); box-shadow: 0 0 0 1px rgba(0, 0, 0, .45); pointer-events: none; border-radius: 2px; }
.adbuild .pv-handle { position: absolute; right: -9px; bottom: -9px; width: 16px; height: 16px; border-radius: 4px; background: #fff; border: 2px solid #1d4ed8; pointer-events: auto; cursor: nwse-resize; box-shadow: 0 1px 4px rgba(0, 0, 0, .5); }
.adbuild .pic-tools { display: grid; gap: 6px; padding: 7px 9px; border: 1px solid var(--line); border-radius: 10px; background: var(--btn); }
.adbuild .pic-tools .row { display: flex; gap: 8px; align-items: center; }
.adbuild .pic-tools .seg { display: inline-flex; gap: 4px; }
.adbuild .pic-tools .pt-zoom { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.adbuild .pic-tools .pt-zoom input { width: 120px; }
.crop-back { position: fixed; inset: 0; z-index: 30; display: grid; place-items: center; background: rgba(0, 0, 0, .6); }
.crop-box { width: min(760px, calc(100vw - 20px)); max-height: calc(100vh - 30px); padding: 14px 16px; display: grid; gap: 10px; overflow: auto; }
.crop-box h3 { margin: 0; font-size: 16px; }
.crop-box .row { display: flex; gap: 10px; align-items: center; }
.crop-box .seg { display: inline-flex; gap: 4px; }
.crop-stage { position: relative; justify-self: center; touch-action: none; line-height: 0; max-width: 100%; }
.crop-stage img { max-width: min(720px, calc(100vw - 50px)); max-height: 60vh; display: block; user-select: none; -webkit-user-drag: none; }
.crop-rect { position: absolute; box-shadow: 0 0 0 9999px rgba(0, 0, 0, .55); outline: 2px solid #fff; cursor: move; }
.crop-rect i { position: absolute; width: 14px; height: 14px; margin: -7px; background: #fff; border: 2px solid #1d4ed8; border-radius: 3px; }
.crop-rect i[data-h="nw"] { left: 0; top: 0; cursor: nwse-resize; } .crop-rect i[data-h="n"] { left: 50%; top: 0; cursor: ns-resize; }
.crop-rect i[data-h="ne"] { left: 100%; top: 0; cursor: nesw-resize; } .crop-rect i[data-h="e"] { left: 100%; top: 50%; cursor: ew-resize; }
.crop-rect i[data-h="se"] { left: 100%; top: 100%; cursor: nwse-resize; } .crop-rect i[data-h="s"] { left: 50%; top: 100%; cursor: ns-resize; }
.crop-rect i[data-h="sw"] { left: 0; top: 100%; cursor: nesw-resize; } .crop-rect i[data-h="w"] { left: 0; top: 50%; cursor: ew-resize; }
.adbuild .ab-derr:empty { display: none; }
.addlg .ad-big.tall { width: min(300px, 70%); justify-self: center; }
.ad-earn { display: grid; gap: 4px; }
.signdlg .rs-size { display: inline-flex; gap: 4px; }
.signdlg .row.wrap { align-items: end; gap: 8px; }
.signdlg .rs-at { width: 140px; }
.signdlg .seg { display: inline-flex; gap: 4px; }
.signdlg .is-styles { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; }
.signdlg .is-style { display: grid; gap: 2px; justify-items: center; text-align: center; padding: 6px; border-radius: 10px; border: 2px solid var(--line); background: var(--btn); color: inherit; font: inherit; cursor: pointer; }
.signdlg .is-style.on { border-color: var(--accent, #1d4ed8); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #1d4ed8) 25%, transparent); }
.signdlg .is-style b { font-size: 13px; }
.signdlg .is-style small { font-size: 11px; color: var(--dim); line-height: 1.25; }
.signdlg .is-thumb { width: 96px; height: 96px; border-radius: 8px; background: radial-gradient(circle at 50% 40%, #3a4250, #1b2029) center / cover no-repeat; background-blend-mode: normal; }
.signdlg .is-light { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; }
.signdlg .is-swatches { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.signdlg .is-dims { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; }
.signdlg .is-dims label { display: inline-flex; align-items: center; gap: 5px; }
.signdlg .is-dims .input { width: 76px; padding: 5px 7px; border-radius: 7px; border: 1px solid var(--line); background: var(--btn); color: inherit; font: inherit; }
.signdlg .is-keep { margin-left: auto; }
.signdlg .is-shapes .chip small { font-size: 10px; }
.signdlg .is-fit:empty { display: none; }
.signdlg .is-c { width: 34px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 6px; background: none; cursor: pointer; }
.mkt { display: grid; gap: 8px; grid-template-columns: minmax(0, 1fr); }
.mkt > *, .mkt .mk-sec > div { min-width: 0; }
.mkt h5 { margin: 4px 0 0; }
.mkt .seg { display: inline-flex; gap: 4px; }
.mkt .mk-sec { border: 1px solid var(--line); border-radius: 10px; padding: 6px 9px; }
.mkt .mk-sec > summary { cursor: pointer; font-weight: 600; font-size: 13px; }
.mkt .mk-sec[open] > summary { margin-bottom: 6px; }
.mkt .mk-row { display: flex; justify-content: space-between; align-items: center; gap: 6px; padding: 4px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.mkt .mk-row:last-child { border-bottom: 0; }
.mkt .mk-row .row { display: flex; gap: 4px; flex: 0 0 auto; }
.mkt .mk-row > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.mkt .mk-g { display: grid; gap: 5px; padding: 6px 8px; margin: 4px 0 8px; border-radius: 8px; background: var(--btn); font-size: 13px; }
.mkt .mk-g .fld { display: grid; gap: 3px; }
.mkt .input { padding: 5px 7px; border-radius: 7px; border: 1px solid var(--line); background: var(--btn); color: inherit; font: inherit; min-width: 0; }
.mkt .mk-ad { display: grid; gap: 5px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.mkt .mk-ad .ad-thumb { max-height: 110px; width: auto; max-width: 100%; }
.mkt .mk-ad small { display: block; }
.mkt .mk-ad .input { flex: 1; min-width: 120px; }
.dtools .dextra:empty { display: none; }
.dtools .dextra { display: grid; gap: 6px; margin-top: 6px; }
.walletdlg .ad-row { grid-template-columns: 120px 1fr; }
.walletdlg .ad-row .lib-acts { grid-column: 1 / -1; justify-content: flex-start; }
.ad-thumb { width: 100%; height: auto; border-radius: 6px; border: 1px solid var(--line); background: #10141a; display: block; }
.walletdlg .lib-row.due { border-color: var(--bad); }
.shopadm .sh-ads { display: grid; gap: 6px; max-height: 420px; overflow-y: auto; }
.shopadm .sh-ad { display: grid; grid-template-columns: 150px 1fr; gap: 6px 10px; padding: 8px; border: 1px solid var(--line); border-radius: 10px; }
.shopadm .sh-ad > div { display: grid; gap: 2px; min-width: 0; } .shopadm .sh-ad small { color: var(--dim); font-size: 11px; overflow-wrap: anywhere; }
.shopadm .sh-adacts { grid-column: 1 / -1; display: flex !important; gap: 6px; flex-wrap: wrap; align-items: center; }
.shopadm .sh-adacts .input { flex: 1; min-width: 160px; }
.shopadm .sh-tiers { width: 100%; border-collapse: collapse; font-size: 12px; }
.shopadm .sh-tiers th { text-align: left; color: var(--dim); font-weight: 600; padding: 2px 4px; }
.shopadm .sh-tiers td { padding: 2px 4px; } .shopadm .sh-tiers .input { width: 100%; box-sizing: border-box; }
@media (max-width: 760px) {
  .shopadm .sh-grid { grid-template-columns: 1fr; }
  .shopdlg .lib-btns .btn.primary { min-width: 0; white-space: normal; line-height: 1.2; }
  .shopdlg .lib-btns .btn { padding-left: 10px; padding-right: 10px; }
  .shop-price > b { font-size: 18px; }
  .walletdlg .wl-row, .walletdlg .lib-row { grid-template-columns: 1fr; }
  .walletdlg .lib-acts { justify-content: flex-start; }
  .adbuild .ab-spaces, .addlg .ad-spaces { grid-template-columns: 1fr; }
  .adbuild .ab-tiers { grid-template-columns: 1fr 1fr; }
  .walletdlg .ad-row { grid-template-columns: 1fr; }
  .shopadm .sh-ad { grid-template-columns: 1fr; }
}

/* Free Will's "Why it chose" rows (client/js/ui/free-will.js; shown in the Agent Studio) and Settings → Free Will */
.fw-list { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; max-height: 320px; overflow-y: auto; }
.fw-item { padding: 6px 8px; border-radius: 8px; background: var(--btn); border: 1px solid var(--line); font-size: 12px; }
.fw-item.routine { opacity: .85; }
.fw-when { font-weight: 600; }
.fw-pick { margin-top: 3px; font-weight: 600; }
.fw-opts { margin-top: 4px; display: flex; flex-direction: column; gap: 2px; }
.fw-opt { position: relative; display: flex; align-items: center; gap: 6px; padding: 1px 4px; border-radius: 4px; overflow: hidden; }
.fw-opt .fw-bar { position: absolute; left: 0; top: 0; bottom: 0; background: var(--accent); opacity: .16; border-radius: 4px; }
.fw-opt.on .fw-bar { opacity: .32; }
.fw-opt .fw-ol { position: relative; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fw-opt .fw-op { position: relative; font-variant-numeric: tabular-nums; color: var(--dim); }
.fwadm .tag.warn { color: var(--warn, #e0a83a); }

.fw-kind { font-size: 10px; padding: 1px 6px; }

/* The Mind's thoughts (ui/mind.js; shown in the Agent Studio's Brain tab) */
.mind-t .mind-thought { font-style: italic; margin: 3px 0; }
.mind-t .mind-did { font-size: 12px; line-height: 1.35; margin: 1px 0; }
.mind-t.bad { opacity: 0.8; }

/* Settings → Voice (ui/voice-settings.js) */
.vs .vs-voice-l.hidden, .vs .vs-f-url-l.hidden { display: none; }
.vs input[type="range"] { flex: 1; min-width: 120px; accent-color: var(--primary); }
.vs .vs-speed-v { min-width: 3.4em; text-align: right; }
.vs-meter { display: grid; gap: 4px; margin: 4px 0; }
.vs-meter-t { display: flex; justify-content: space-between; gap: 8px; font-size: 12.5px; } .vs-meter-t span { color: var(--dim); }
.vs-meter .st-meter { --sc: var(--primary); height: 7px; border-radius: 4px; background: var(--btn); overflow: hidden; border: 1px solid var(--line); }
.vs-meter .st-meter i { display: block; height: 100%; background: var(--primary); }
.vs-add { margin-top: 6px; } .vs-add > summary { cursor: pointer; font-weight: 600; padding: 4px 0; }
.vs-try-out, .vs-f-out { margin-left: 8px; }

/* the Lots section of the edit dock (ui/lot-tools.js) */
.lottools .row { gap: 6px; flex-wrap: wrap; }
.lottools .lt-form { margin-top: 8px; display: grid; gap: 10px; }
.lottools .lt-step { margin: 0; display: flex; gap: 8px; align-items: baseline; }
.lottools .lt-step > b { flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%; background: var(--hl-line); color: #fff; display: inline-grid; place-items: center; font-size: 12px; }
.lottools .lt-f { display: grid; gap: 5px; }
.lottools .lt-l { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; opacity: .7; }
.lottools .chip { display: inline-flex; align-items: center; gap: 5px; min-height: 30px; }
.lottools .chip small { opacity: .65; font-size: 10.5px; }
.lottools .chip .dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.lottools .stepper { display: inline-flex; align-items: center; gap: 6px; }
.lottools .stepper b { min-width: 26px; text-align: center; }
.lottools .lt-custom .input { width: 70px; }
.lottools .lt-sale { display: grid; gap: 4px; }
.lottools .lt-opt { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; cursor: pointer; }
.lottools .lt-opt .lt-price { width: 84px; }
.lottools .lt-stat.bad { color: var(--bad, #e5484d); }
.lottools .lt-made .chips { margin-top: 4px; }
#lotbar { position: absolute; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 30; display: flex; align-items: center; gap: 10px; padding: 8px 10px 8px 14px; max-width: min(640px, calc(100vw - 16px)); }
#lotbar .lb-stat { font-size: 13px; line-height: 1.3; }
#lotbar .lb-stat.bad { color: var(--bad, #e5484d); }
#lotbar .lb-btns { display: flex; gap: 6px; flex: 0 0 auto; }
@media (max-width: 760px) { #lotbar { flex-direction: column; align-items: stretch; width: calc(100vw - 16px); } #lotbar .lb-btns { justify-content: flex-end; } }

/* the show/hide eye on password fields (core/pw-eye.js) */
.pw-eye { position: relative; display: block; width: 100%; }
.pw-eye > input { width: 100%; padding-right: 38px; }
.pw-eye-btn { position: absolute; right: 3px; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--text); opacity: .6; cursor: pointer; }
.pw-eye-btn:hover, .pw-eye-btn:focus-visible { opacity: 1; background: var(--btn); }
.pw-eye-btn[aria-pressed="true"] { opacity: .95; }
