:root{--bg:#0f1115;--panel:#171a21;--panel2:#1e222b;--line:#2a2f3a;--text:#e7e9ee;--muted:#8f97a6;
--accent:#e8a33d;--accent2:#ffbf5c;--ok:#3fd47a;--bad:#ff5d5d;--warn:#f2c14e;--cyan:#00e5ff;--radius:10px}
*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{margin:0;height:100%;background:var(--bg);color:var(--text);
font:14px/1.45 system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;overflow:hidden}
button,select,input,textarea{font:inherit;color:inherit}
.muted{color:var(--muted)}.small{font-size:12px}
.warn{color:var(--warn)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:34px;padding:0 13px;border-radius:8px;
border:1px solid var(--line);background:var(--panel2);cursor:pointer;white-space:nowrap;text-decoration:none;color:var(--text)}
.btn:hover{border-color:#3a4150}.btn:disabled,.btn.disabled{opacity:.45;cursor:default}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#16120a;font-weight:600}
.btn.primary:hover{background:var(--accent2)}
.btn.big{height:46px;padding:0 24px;font-size:16px}
.btn.small{height:28px;padding:0 10px;font-size:13px}
.btn.icon{width:38px;padding:0;font-size:17px}
.btn.active{background:#00e5ff22;border-color:var(--cyan);color:#9ff4ff}
.btn.danger{border-color:#6a2626;color:#ffb3b3}
.btn.wide{width:100%;margin-top:8px}
.linkbtn{border:none;background:none;color:var(--accent2);cursor:pointer;padding:0 4px;text-decoration:underline;font-size:inherit}
.linkbtn:disabled{opacity:.5;cursor:default}
.x{border:none;background:none;cursor:pointer;font-size:18px;line-height:1;padding:0 6px;color:var(--muted)}
.x:hover{color:var(--text)}
.chip{height:30px;padding:0 11px;border-radius:15px;border:1px solid var(--line);background:#11141bdd;cursor:pointer;
display:inline-flex;align-items:center;gap:6px;white-space:nowrap;font-size:13px}
.chip:hover{border-color:#3d4453}.chip:disabled{opacity:.45;cursor:default}
.chip.active{background:#00e5ff22;border-color:var(--cyan);color:#9ff4ff}

#app{position:relative;display:flex;height:100vh;height:100dvh;width:100%;overflow:hidden}
/* ---- left: chat */
#chatpane{position:relative;width:38%;min-width:340px;max-width:520px;display:flex;flex-direction:column;background:var(--panel);
border-right:1px solid var(--line);min-height:0}
.chead{display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--line);min-height:52px;flex-wrap:wrap}
.chead .title{flex:1 1 120px;min-width:0;display:flex;align-items:baseline;gap:6px;overflow:hidden;white-space:nowrap}
/* the map name may be cut, the version label never is */
.chead .title #mapname{min-width:0;overflow:hidden;text-overflow:ellipsis}
.chead .title #mapver{flex:none}
.hbtns{display:flex;gap:6px}
.mapinfo{display:flex;flex-wrap:wrap;gap:2px 12px;padding:6px 12px;border-bottom:1px solid var(--line);color:#c9ced8}
.mapinfo .warn{flex-basis:100%}
.chat{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;min-height:0}
.msg{max-width:92%;padding:8px 11px;border-radius:12px;background:var(--panel2);white-space:pre-wrap;overflow-wrap:anywhere}
.msg.me{align-self:flex-end;background:#3a2c14;border:1px solid #5a4320}
.msg.ai{align-self:flex-start}
.msg.sys{align-self:center;background:none;color:var(--muted);font-size:13px;text-align:center}
.msg.err{align-self:center;background:#3a1717;border:1px solid #6a2626;color:#ffd0d0;font-size:13px}
.msg.ver{align-self:center;background:#123222;border:1px solid #1f5a3a;font-size:13px;text-align:center}
.msg .meta{display:flex;flex-wrap:wrap;gap:4px;margin-top:5px}
.msg .tag{font-size:11px;padding:1px 7px;border-radius:9px;background:#0005;color:#d9c7a6}
.thinking{animation:blink 1.2s infinite}
@keyframes blink{50%{opacity:.4}}
.empty{margin:auto 0;padding:8px 2px}
.empty-h{font-size:16px;font-weight:600;margin-bottom:6px}
.examples{display:flex;flex-direction:column;gap:6px;margin-top:6px}
.example{text-align:left;border:1px solid var(--line);background:var(--panel2);border-radius:10px;padding:8px 11px;cursor:pointer;color:#dfe3ea}
.example:hover{border-color:var(--accent)}
.proposal{padding:10px 12px;border:1px solid var(--accent);border-radius:var(--radius);background:#211b10}
.proposal .ph{font-weight:600;margin-bottom:4px}
.proposal .diff{margin:4px 0 8px;padding-left:18px}
.proposal .row{display:flex;gap:8px;margin-top:8px}
.beforeafter{display:flex;align-items:center;gap:8px;margin:6px 0}
.beforeafter figure{margin:0;flex:1;min-width:0;text-align:center}
.beforeafter img{width:100%;max-height:150px;object-fit:contain;background:#000;border:1px solid var(--line);border-radius:6px;image-rendering:pixelated}
.beforeafter figure.noimg img{visibility:hidden}
.beforeafter figcaption{font-size:12px;color:var(--muted)}
.beforeafter .arrow{color:var(--accent);font-size:20px}
.composer{border-top:1px solid var(--line);padding:8px 12px 10px;background:var(--panel)}
.chips{display:flex;flex-direction:column;gap:6px}
.chips:has(> :not([hidden])){margin-bottom:6px}
.selchip{display:inline-flex;align-items:center;gap:6px;align-self:flex-start;max-width:100%;background:#00e5ff1a;border:1px solid #00e5ff66;color:#9ff4ff;
border-radius:14px;padding:2px 2px 2px 10px;font-size:12px}
.selchip .txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.selchip .dot{width:8px;height:8px;border-radius:50%;background:var(--cyan);flex:none}
.selchip .dot.obj{background:#ff9e26}
.attchips{display:flex;flex-wrap:wrap;gap:6px}
.chip.att{height:auto;min-height:30px;padding:2px 2px 2px 4px;border-radius:10px;background:var(--panel2);cursor:default;max-width:100%;white-space:normal}
.chip.att img{width:34px;height:24px;object-fit:cover;border-radius:4px}
.chip.att.busy{opacity:.7}
.chip.att .mdl-ico{color:var(--accent);padding-left:4px}
.crow{display:flex;gap:6px;align-items:flex-end}
.crow textarea{flex:1;min-width:0;resize:none;min-height:38px;max-height:140px;padding:8px 10px;border-radius:8px;border:1px solid var(--line);background:var(--bg);outline:none}
.crow textarea:focus{border-color:var(--accent)}
.crow .btn{height:38px}
.limits{margin-top:4px;min-height:0}
.drawer{position:absolute;inset:0;z-index:30;background:var(--panel);display:flex;flex-direction:column;padding:10px 12px;overflow:hidden}
.dhead{display:flex;align-items:center;justify-content:space-between;gap:8px}
.drawer p{margin:6px 0 10px}
.hlist{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:6px}
.hrow{display:flex;gap:10px;align-items:center;padding:6px;border:1px solid var(--line);border-radius:8px;background:var(--panel2)}
.hrow.head{border-color:var(--accent)}
.hrow .thumb{width:80px;height:45px;flex:none;border-radius:4px;background:#000 linear-gradient(45deg,#1c1f26 25%,transparent 25%,transparent 75%,#1c1f26 75%) 0 0/12px 12px;overflow:hidden}
.hrow .thumb img{width:100%;height:100%;object-fit:cover;display:block}
.htxt{flex:1;min-width:0}
.htitle{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.now{margin-left:6px;font-size:11px;padding:0 7px;border-radius:9px;background:var(--accent);color:#16120a;font-weight:600}
.hacts{display:flex;flex-direction:column;gap:4px}
#chatpane.dragging,#mappane.dragging{outline:2px dashed var(--accent);outline-offset:-6px}

/* ---- right: map */
#mappane{position:relative;flex:1;min-width:0;background:#000}
.viewer,.hlv-host{position:absolute;inset:0}
.hlv-host{touch-action:none}
/* hlviewer's own loading screen (white spinner, fades for 2 s) is never shown: loader.js is the one loader */
.hlv-title,.hlv-controls,.hlv-loading-log,.hlv-loading{display:none!important}
.overlay{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:40;touch-action:none}
.overlay.pick{pointer-events:auto;cursor:crosshair}
.vstatus{position:absolute;left:50%;top:14px;transform:translateX(-50%);z-index:50;background:#000a;border:1px solid var(--line);
padding:6px 14px;border-radius:16px;font-size:13px;white-space:nowrap}
.hint{position:absolute;top:10px;left:10px;right:10px;z-index:45;font-size:12px;color:#cfd3da;pointer-events:none}
.hint:not(:empty){background:#0008;padding:4px 10px;border-radius:12px;justify-self:start;width:fit-content;max-width:calc(100% - 20px)}
.maptools{position:absolute;left:10px;right:10px;bottom:10px;z-index:50;display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap;justify-content:flex-end;pointer-events:none}
.maptools>*{pointer-events:auto}
.seg{display:flex;gap:2px;background:#11141bdd;border-radius:16px;padding:1px}
.seg .chip{border-color:transparent;background:transparent}.seg .chip.active{background:#00e5ff22;border-color:var(--cyan)}
.fly{display:none;gap:4px;flex-wrap:wrap}
.card{position:absolute;left:10px;bottom:52px;z-index:55;width:min(360px,calc(100% - 20px));background:#171a21f2;border:1px solid var(--line);
border-radius:12px;padding:10px 12px;box-shadow:0 8px 28px #000a;max-height:calc(100% - 70px);overflow:auto}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}
.card-head b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.card-row,.card-pad,.replace{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0}
.card p{margin:4px 0 8px}
.swatches{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:6px 0}
.btn.swatch{width:30px;height:30px;padding:0;border-radius:50%;border:2px solid #0008}
.alpha{display:flex;align-items:center;gap:8px;margin:6px 0}
.alpha input{flex:1}

/* ---- landing */
.landing{position:absolute;inset:0;z-index:70;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:16px;overflow:auto;
background:radial-gradient(1200px 600px at 30% 20%,#2a2010 0%,var(--bg) 60%)}
.drop{max-width:620px;width:100%;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;padding:40px 24px;
border:2px dashed #4a4f5b;border-radius:18px;background:#14171dcc;cursor:pointer}
.drop:hover,body.dragging .drop{border-color:var(--accent)}
.drop-h{font-size:28px;font-weight:700}
.drop-p{color:#cfd3da;max-width:500px}
.err{color:#ffb3b3;background:#3a1717;border:1px solid #6a2626;border-radius:8px;padding:8px 12px}

/* ---- dialog, toast */
.dlg{background:var(--panel);color:var(--text);border:1px solid var(--line);border-radius:14px;padding:14px 16px;width:min(440px,calc(100vw - 32px))}
.dlg::backdrop{background:#000a}
.fld{display:flex;flex-direction:column;gap:4px;margin:10px 0}
.keepchk{display:flex;gap:8px;align-items:flex-start;margin:10px 0 4px;cursor:pointer;line-height:1.35}.keepchk input{width:18px;height:18px;margin:1px 0 0;flex:none}
.fld select,.fld input{height:36px;border-radius:8px;border:1px solid var(--line);background:var(--bg);padding:0 10px;min-width:0;width:100%}
.dlg .btn.big{width:100%;margin-top:6px}
.toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:100;background:#222833;border:1px solid var(--line);
padding:10px 14px;border-radius:10px;max-width:min(92vw,520px);box-shadow:0 6px 24px #0008;display:flex;gap:10px;align-items:center}
.toast.bad{background:#3a1717;border-color:#6a2626}

@media (pointer:coarse){.fly{display:flex}}
@media (max-width:899px){
  #app{flex-direction:column}
  #mappane{order:-1;flex:none;height:45vh;min-height:220px}
  #chatpane{width:auto;min-width:0;max-width:none;flex:1;border-right:none;border-top:1px solid var(--line)}
  .chead{padding:6px 12px;min-height:44px}
  .btn{height:32px;padding:0 10px}
  .hint{display:none}
  .maptools{gap:6px;bottom:6px;left:6px;right:6px}
  /* phone: the card lives over the bottom of the map (never over the chat, its answers or «История»), opaque */
  .card{position:absolute;left:6px;right:6px;bottom:56px;width:auto;max-height:calc(100% - 64px);border-radius:12px;z-index:55;padding:10px 12px;background:#171a21}
  .card .btn{height:38px}
  .card-pad .btn.icon{width:46px}
  .drop{padding:28px 16px}.drop-h{font-size:22px}
  .toast{bottom:auto;top:12px}
}

/* fix23: proposal summaries in the chat log, the user's picture in the card, desktop-only hints */
.propsum{margin-top:6px;padding:6px 8px;border-radius:8px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08)}
.propsum .diff{margin:0;padding-left:18px}
.pstat{margin-top:4px;font-size:12px}
.pstat.ok{color:#7bd88f}
.pstat.no{color:#c9a46a}
.yourpic{display:flex;gap:10px;margin:6px 0}
.yourpic figure{margin:0;max-width:160px}
.yourpic img{max-width:160px;max-height:90px;border-radius:6px;background:#222}
.yourpic figcaption{font-size:12px;opacity:.8;word-break:break-all}
@media (hover:none),(max-width:899px){.desk-only{display:none}}
@media (max-width:520px){.hbtns{flex-wrap:wrap;gap:4px}.hbtns .btn{padding:6px 9px;font-size:13px}}
/* desktop: the header buttons get a second line before the version label is pushed out */
@media (min-width:900px){.hbtns{flex-wrap:wrap;justify-content:flex-end}.hbtns .btn{padding:0 10px}}
/* landing: projects of this browser */
.myprojects{width:100%;max-width:620px;margin-top:14px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;background:#14171dcc;text-align:left}
.mp-h{font-weight:600;margin-bottom:6px}
.mp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 0;border-top:1px solid var(--line)}
.mp-row:first-of-type{border-top:none}
.mp-name{color:var(--accent2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* map load gave up (slow network): message + «Повторить» over the 3D */
.vfail{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:60;max-width:min(420px,calc(100% - 32px));background:#000c;border:1px solid var(--line);border-radius:10px;padding:14px 16px;color:#fff;text-align:center;display:flex;flex-direction:column;gap:10px;align-items:center}
.vfail[hidden]{display:none}

/* frame for a picture (region.js) */
.rpanel{position:absolute;right:10px;top:40px;z-index:52;width:min(300px,calc(100% - 20px));background:#171a21f2;border:1px solid var(--line);
border-radius:var(--radius);padding:8px 10px;display:flex;flex-direction:column;gap:6px}
.rpanel[hidden]{display:none}
.rpanel .seg{display:flex;gap:4px;flex-wrap:wrap;margin:2px 0}
.rpanel .beforeafter img{max-height:90px}
.rp-ph{height:60px;display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:12px;border:1px dashed var(--line);border-radius:6px}
.rp-ph[hidden],.rpanel figure[hidden],.rpanel .arrow[hidden]{display:none}
.rp-hint{color:#cfd3da}
.rp-warn{color:var(--warn)}
.rp-warn[hidden]{display:none}
/* loader over the 3D view (loader.js): the last frame stays visible under the veil */
.loader{position:absolute;inset:0;z-index:70;display:flex;align-items:center;justify-content:center;background:rgba(10,12,16,.4);cursor:progress}
.loader[hidden]{display:none}
.ld-card{display:flex;flex-direction:column;align-items:center;gap:10px;background:#171a21e6;border:1px solid var(--line);border-radius:12px;padding:16px 22px;min-width:220px;max-width:min(360px,calc(100% - 32px));text-align:center}
.ld-spin{width:34px;height:34px;border-radius:50%;border:3px solid #ffffff33;border-top-color:var(--accent);animation:ldspin .8s linear infinite}
.ld-spin[hidden]{display:none}
.ld-text{font-size:14px}
.ld-bar{width:100%;height:6px;background:#ffffff1f;border-radius:3px;overflow:hidden}
.ld-bar[hidden]{display:none}
.ld-fill{height:100%;width:0;background:var(--accent);transition:width .2s}
.loader.err{cursor:default}
.loader.err .ld-text{color:#ffd0d0}
@keyframes ldspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.ld-spin{animation-duration:2.4s}}
/* the panel never sits on the frame: region.js moves it to the other side (pos-l / pos-t) when the frame's
   handles are under it, and it fades out while the frame is dragged */
.rpanel{transition:opacity .15s}
.rpanel.dragging{opacity:.2;pointer-events:none}
.rpanel.pos-l{right:auto;left:10px}
.rp-head{display:flex;gap:6px;align-items:flex-start}
.rp-head .rp-hint{flex:1;min-width:0}
.rp-more{display:none;flex:none}
.rpanel.pos-bl{top:auto;bottom:56px;right:auto;left:10px}
.rpanel.mini .rp-more{display:inline-flex}
.rpanel.mini .rp-more[hidden]{display:none}
.rpanel.mini:not(.open) .rp-body{display:none}
.rp-body{display:flex;flex-direction:column;gap:6px}
/* «Станет на карте» big (that is what the map gets), «Было» small next to it */
.rpanel .beforeafter{flex-wrap:wrap}
.rpanel .beforeafter .arrow{display:none}
.rpanel .beforeafter .rp-afterfig{order:-1;flex:0 0 100%}
.rpanel .beforeafter figure:first-child{flex:0 0 45%}
.rpanel .beforeafter .rp-afterfig img{max-height:130px;cursor:zoom-in}
.rpanel.big{width:min(560px,calc(100% - 20px))}
.rpanel.big .beforeafter .rp-afterfig img{max-height:260px;cursor:zoom-out}
@media (max-width:899px){
  .rpanel{top:6px;bottom:auto;left:6px;right:6px;width:auto;max-height:calc(100% - 110px);overflow:auto;padding:6px 8px}
  .rpanel.pos-b{top:auto;bottom:var(--rp-bottom,100px)}
  .rpanel.pos-l{left:6px}
  .rpanel.big{width:auto}
  .rp-more{display:inline-flex}
  .rp-more[hidden]{display:none}
  .rpanel:not(.open) .rp-body{display:none}
  .rpanel:not(.open) .rp-hint{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .rpanel .beforeafter .rp-afterfig img{max-height:90px}
}
/* phone held sideways: map and chat side by side (one under the other left the chat a 30 px slit, the
   AI's offer and its «Применить» could not be read) */
@media (max-width:899px) and (orientation:landscape) and (max-height:540px){
  #app{flex-direction:row}
  #mappane{order:0;flex:1;height:auto;min-height:0}
  #chatpane{order:-1;flex:none;width:44%;min-width:300px;max-width:420px;border-top:none;border-right:1px solid var(--line)}
  .chead{min-height:0;padding:4px 10px}
  .hbtns{flex-wrap:wrap;gap:4px}.hbtns .btn{height:30px;padding:0 8px;font-size:13px}
  .mapinfo{padding:3px 10px}
  .composer{padding:6px 10px 6px}
}
/* phone: compact header buttons (one row on a small phone), and while the AI's offer waits for
   «Применить» the map gives the chat room (on a 360×640 phone the offer did not fit) */
@media (max-width:899px) and (orientation:portrait),(max-width:899px) and (min-height:541px){
  body.offer-open #mappane{height:32vh;min-height:170px}
  .mapinfo{font-size:11.5px;padding:4px 12px}
  .crow .btn.primary{padding:0 10px}
}
@media (max-width:420px){
  .hbtns{flex-wrap:nowrap;gap:4px;min-width:0;max-width:100%;overflow-x:auto;scrollbar-width:none}.hbtns .btn{padding:0 7px;font-size:12.5px;flex:none}
  .hbtns::-webkit-scrollbar{display:none}
  .chead{gap:4px 8px}
  /* «Поделиться» as an icon: five buttons in one row never make the page wider than the phone */
  #btn-share{font-size:0;padding:0 9px}
  #btn-share::before{content:'↗';font-size:16px;line-height:1}
}

/* ---- «Проверка карты» (n-health) */
.health-chip.bad{color:var(--bad)}.health-chip.warn{color:var(--warn)}.health-chip.ok{color:var(--ok);text-decoration:none}
/* a phone on its side: every line of the chat counts — «Карта в порядке ✓» is not shown (problems still are) */
@media (max-height:500px) and (max-width:899px),(max-height:500px) and (hover:none){.health-chip.ok{display:none}}
.dlg.wide{width:min(600px,calc(100vw - 32px));max-height:min(86vh,900px);overflow:auto}
.chk{display:flex;gap:8px;align-items:flex-start;margin:6px 0;color:#c9ced8;cursor:pointer}
.chk input{margin-top:2px}
.health-body{display:flex;flex-direction:column;gap:10px;margin-top:8px}
.hsum{display:flex;gap:10px;align-items:center;padding:10px 12px;border-radius:10px;background:var(--panel2);border:1px solid var(--line)}
.hsum.bad{border-color:var(--bad)}.hsum.warn{border-color:var(--warn)}.hsum.ok{border-color:var(--ok)}
.hic{flex:none;width:22px;height:22px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;background:#ffffff14}
.hic.big{width:30px;height:30px;font-size:16px}
.bad>.hic,.bad>.htop>.hic{background:var(--bad);color:#160808}.warn>.hic,.warn>.htop>.hic{background:var(--warn);color:#161208}
.ok>.hic,.ok>.htop>.hic{background:var(--ok);color:#08160d}.info>.htop>.hic{background:#ffffff22;color:var(--text)}
.hlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.hitem{padding:9px 11px;border-radius:9px;background:var(--panel2);border:1px solid var(--line)}
.hitem.bad{border-left:3px solid var(--bad)}.hitem.warn{border-left:3px solid var(--warn)}.hitem.ok{border-left:3px solid var(--ok)}
.htop{display:flex;gap:8px;align-items:flex-start}.htop b{line-height:22px;overflow-wrap:anywhere}
.htext{margin:4px 0 0 30px;color:#c9ced8;overflow-wrap:anywhere}
.hfix{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:8px 0 0 30px}
.hfix .btn{height:32px;white-space:normal;text-align:left}
.hmore{margin:6px 0 0 30px}.hpaths{white-space:pre-wrap;font-family:ui-monospace,monospace;font-size:11px;color:var(--muted);max-height:160px;overflow:auto}
.hok>summary{cursor:pointer;color:var(--muted);margin-bottom:8px}
.hsec{font-weight:600;margin-top:4px}
.hlimits{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px}
.hlrow{display:flex;justify-content:space-between;gap:10px}
.hbar{height:6px;border-radius:3px;background:#ffffff14;overflow:hidden;margin-top:3px}.hbar i{display:block;height:100%;background:var(--ok)}
.hlimits .warn .hbar i{background:var(--warn)}.hlimits .bad .hbar i{background:var(--bad)}
.hbtnrow{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.hbtnrow .btn{flex:1 1 auto}
@media (max-width:520px){.htext,.hfix,.hmore{margin-left:0}}
/* n-models: «Модели» picker (right side of the map) + the model controls on the card */
.mpanel{position:absolute;right:10px;top:10px;bottom:52px;z-index:56;width:min(380px,calc(100% - 20px));display:flex;flex-direction:column;gap:6px;
background:#171a21f2;border:1px solid var(--line);border-radius:12px;padding:10px 12px;box-shadow:0 8px 28px #000a;min-height:0}
.mp-head{display:flex;align-items:center;gap:8px}
.mp-head input{flex:1;min-width:0;height:32px;border-radius:8px;border:1px solid var(--line);background:var(--bg);padding:0 10px;color:var(--text)}
.mp-cats{display:flex;flex-wrap:wrap;gap:4px}
.mp-cats .chip{height:26px;padding:0 9px;font-size:12px}
.mp-grid{flex:1;min-height:120px;overflow:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:6px;align-content:start}
.mp-item{display:flex;flex-direction:column;align-items:center;gap:2px;padding:4px;border-radius:10px;border:1px solid var(--line);background:#11141b;color:var(--text);cursor:pointer;min-width:0}
.mp-item img{width:80px;height:80px;object-fit:contain}
.mp-item:hover{border-color:var(--accent)}
.mp-item.active{border-color:var(--cyan);background:#00e5ff14}
.mp-noimg{width:80px;height:80px;display:grid;place-items:center;font-size:30px}
.mp-name{font-size:12px;line-height:1.2;text-align:center;overflow:hidden;text-overflow:ellipsis;max-width:100%;white-space:nowrap}
.mp-detail{display:flex;flex-direction:column;gap:4px;border-top:1px solid var(--line);padding-top:6px}
.mp-detail .btn.wide{width:100%;margin-top:4px}
.mp-skins{display:flex;flex-wrap:wrap;gap:4px;align-items:center}
.mp-skins .chip{height:26px;padding:0 9px;font-size:12px}
.mp-placing{color:#9ff4ff;background:#00e5ff14;border:1px solid var(--cyan);border-radius:8px;padding:4px 8px}
.tiny{font-size:11px}
.mctl{display:flex;flex-direction:column;gap:4px;margin:6px 0;padding:6px 8px;border:1px solid var(--line);border-radius:8px;background:#11141b}
.mrow{display:grid;grid-template-columns:120px 1fr 40px;align-items:center;gap:6px}
.mrow input[type=range]{width:100%}
.mrow select{height:30px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--text);grid-column:2 / span 2}
.mono{font-variant-numeric:tabular-nums;text-align:right}
.mscale .chip,.steps .chip{height:26px;padding:0 9px;font-size:12px}
@media (max-width:899px){
  /* phone: a bottom sheet over the page (the map pane alone is too low for the list) */
  .mpanel{position:fixed;left:0;right:0;bottom:0;top:auto;height:min(78vh,640px);width:auto;border-radius:14px 14px 0 0;z-index:80;background:#171a21;
  padding-bottom:calc(10px + env(safe-area-inset-bottom))}
  .mp-detail{max-height:42%;overflow:auto}
  .mp-grid{grid-template-columns:repeat(auto-fill,minmax(84px,1fr))}
  .mp-item img,.mp-noimg{width:64px;height:64px}
  .mrow{grid-template-columns:96px 1fr 36px}
}
/* ---- tool palette (tools.js): Photoshop-like bar at the left edge of the 3D view, a row on a phone */
.toolbar{position:absolute;left:10px;top:50%;transform:translateY(-50%);z-index:56;display:flex;flex-direction:column;gap:3px;padding:4px;
background:#11141bee;border:1px solid var(--line);border-radius:12px;box-shadow:0 6px 20px #0008}
.tool{position:relative;width:38px;height:38px;display:flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:8px;
background:transparent;color:#cfd3da;cursor:pointer;padding:0}
.tool:hover{background:#ffffff12;color:#fff}
.tool:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.tool.active{background:#00e5ff26;border-color:var(--cyan);color:#9ff4ff}
.tool .tl{display:none}
.tool-sep{height:1px;margin:3px 4px;background:var(--line)}
/* tooltip: name + hotkey (desktop) */
.tool[data-tip]:hover::after{content:attr(data-tip) "  " attr(data-key);position:absolute;left:calc(100% + 10px);top:50%;transform:translateY(-50%);
white-space:pre;background:#222833;border:1px solid var(--line);color:var(--text);font-size:12px;padding:4px 8px;border-radius:6px;pointer-events:none;z-index:80;box-shadow:0 4px 14px #0008}
.tools-tip{position:absolute;left:62px;top:50%;transform:translateY(-50%);z-index:57;max-width:min(300px,calc(100% - 80px));display:flex;gap:6px;align-items:flex-start;
background:#222833f2;border:1px solid var(--accent);border-radius:10px;padding:8px 10px;box-shadow:0 6px 20px #0009}
/* the object card and the frame's panel keep clear of the bar */
@media (min-width:900px){
  .card{left:60px;width:min(360px,calc(100% - 70px))}
  .rpanel.pos-l,.rpanel.pos-bl{left:60px}
  .hint{left:60px}
}
@media (max-width:899px){
  .toolbar{top:auto;bottom:6px;left:6px;transform:none;flex-direction:row;padding:3px;gap:2px}
  .tool{width:auto;min-width:44px;height:40px;flex-direction:column;gap:0;padding:2px 4px}
  .tool .tl{display:block;font-size:10px;line-height:1.1}
  .tool svg{width:18px;height:18px}
  .tool[data-tip]:hover::after{display:none}
  .tool-sep{width:1px;height:auto;margin:4px 2px}
  .maptools{left:auto;max-width:calc(100% - 220px)}
  .tools-tip{left:6px;right:6px;top:auto;bottom:56px;transform:none;max-width:none}
}
@media (hover:none){.tool[data-tip]:hover::after{display:none}}
/* v1.2: «Механика» layer, captions over the 3D, logic card, files of the map, «Какую карту открыть?» */
.phone-only{display:none}
@media (hover:none),(max-width:899px){.phone-only{display:inline}}
.captions{position:absolute;left:50%;top:44px;transform:translateX(-50%);z-index:52;display:flex;flex-direction:column;align-items:center;gap:4px;pointer-events:none;max-width:calc(100% - 20px)}
.captions .cap{background:#000c;border:1px solid #ffffff33;color:#fff;padding:5px 12px;border-radius:14px;font-size:13px;text-align:center;transition:opacity .4s}
.captions .cap.out{opacity:0}
.lhint{position:absolute;right:10px;top:44px;z-index:54;display:flex;align-items:center;gap:8px;max-width:min(420px,calc(100% - 20px));background:#171a21f2;border:1px solid var(--cyan);border-radius:12px;padding:8px 6px 8px 12px;font-size:13px;box-shadow:0 6px 20px #0008}
.selchip .dot.logic{background:#3fd47a}
.lparams{margin:4px 0 8px;padding-left:18px;color:#cfd3da}
.lparams li{margin:1px 0}
.lconfirm{border:1px solid #6a2626;background:#2a1414;border-radius:10px;padding:8px 10px;margin:6px 0}
.lconfirm p{margin:0 0 4px}
.linkbtn.warnc{color:var(--warn)}
.chip.off{text-decoration:line-through;color:var(--muted)}
.card{bottom:calc(var(--tools-h,32px) + 20px)}
.card.compact{width:auto;padding:8px}
.card.compact .btn.big{width:100%}
.res-body{max-height:min(56vh,520px);overflow:auto;margin:8px 0}
.res-list{list-style:none;margin:4px 0 8px;padding:0;display:flex;flex-direction:column;gap:3px}
.res-list li{display:flex;gap:8px;align-items:baseline;font-size:12px;min-width:0}
.res-list .rk{flex:none;min-width:110px;color:var(--muted)}
.res-list .rp{min-width:0;overflow-wrap:anywhere;color:#dfe3ea}
.res-list li.miss .rp{color:#ffd9a0}
.res-have summary{cursor:pointer;color:var(--muted);font-size:13px;margin:6px 0}
.res-h{font-weight:600;margin:10px 0 4px}
.res-health{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px;font-size:13px}
.res-health li{display:flex;gap:8px}
.res-health .ic{flex:none;width:18px;text-align:center;font-weight:700}
.res-health li.ok .ic{color:var(--ok)}.res-health li.warn .ic{color:var(--warn)}.res-health li.bad .ic{color:var(--bad)}
.choose-list{display:flex;flex-direction:column;gap:6px;margin-top:8px}
.choose-list .btn{justify-content:flex-start;overflow:hidden;text-overflow:ellipsis}
@media (max-width:899px){
  .lhint{left:6px;right:6px;top:6px;max-width:none}
  .captions{top:8px}
  .card .btn.big{height:46px;flex:1 1 100%}
  /* phone: the 3D view is short and the map tools wrap into a tall column beside the tool palette — the card
     sits just above the palette row (over that column) and the camera turns the selected thing above it */
  .card{bottom:56px;max-height:calc(100% - 64px)}
  .res-list .rk{min-width:90px}
}

/* «сделай красиво»: variants to pick from (n-quick) */
.variants .variant{display:flex;gap:10px;align-items:flex-start;padding:8px 0;border-top:1px solid rgba(255,255,255,.08)}
.variants .variant.shown{background:rgba(232,163,61,.08);border-radius:8px}
.variants .vpic{flex:0 0 120px;width:120px;height:68px;border-radius:6px;overflow:hidden;background:#111;display:flex;align-items:center;justify-content:center}
.variants .vpic img{width:100%;height:100%;object-fit:cover;display:block}
.variants .vbody{flex:1;min-width:0}
.variants .vtitle{font-weight:600}
.variants .diff{margin:2px 0 4px;padding-left:18px}
.variants .row{margin-top:4px}
@media (max-width:480px){.variants .vpic{flex-basis:96px;width:96px;height:54px}}

/* «Поделиться» and the read-only page (n-quick) */
.dlg.share{max-width:560px}
.share-row{display:flex;gap:8px;margin:6px 0}
.share-row input{flex:1;min-width:0}
.share-h{font-weight:600;margin-top:12px}
.share-pic img{display:block;width:100%;border-radius:8px;margin:6px 0}
.viewbar{padding:10px 12px;border-bottom:1px solid rgba(255,255,255,.08)}
.viewbar .vb-h{font-weight:600}
.viewbar .vb-pic{display:block;width:100%;border-radius:8px;margin:8px 0}
body.readonly #composer,body.readonly .hbtns,body.readonly #drawer,body.readonly #rpanel,
body.readonly [data-tool=area],body.readonly [data-mode=area],body.readonly #card button:not(.x),
body.readonly #card .swatches,body.readonly .proposal,body.readonly .examples,body.readonly .empty,body.readonly #hint,body.readonly #tools-tip{display:none!important}
/* editor tools: the sketch chip, several points */
.selchip .dot.sk{background:#ffd400}
.sketchchip{background:#ffd4001a;border-color:#ffd40066;color:#ffe680}
.selchip .ptchip{display:inline-flex;align-items:center;gap:2px;border:1px solid #00e5ff55;background:#00e5ff14;color:#bff8ff;border-radius:10px;padding:0 2px 0 7px;font-size:12px;cursor:default}
.selchip .ptchip .x{font-size:14px;padding:0 3px}
.selchip.multi{flex-wrap:wrap;border-radius:12px}
.tool[data-tool=addpt].active{background:#ff9e2626;border-color:#ff9e26;color:#ffd08a}
/* phone: seven tools in the bottom row — a little narrower; the map's own buttons («Показать», «Механика»,
   the fly arrows) go in rows above that row, «Показать точку» as «Показать» */
@media (max-width:899px){
  .tool{min-width:41px;padding:2px 3px}
  .maptools{left:6px;right:6px;bottom:56px;max-width:none}
  #btn-show{font-size:0;padding:0 9px}
  #btn-show::before{content:'Показать';font-size:12px}
}
/* v12-fix: a phone mechanism card keeps its details folded (the tapped thing stays in view) */
.lmore summary{cursor:pointer;color:var(--muted,#9aa3ad);margin:2px 0}
.lmore[open] summary{margin-bottom:2px}
/* QA round 2 (web) */
/* the read-only link: nothing that needs the editor (mechanics, map files, the map check have no answer there) */
body.readonly #btn-logic,body.readonly #btn-logic-mute,body.readonly #btn-logic-amb,body.readonly #logic-hint,
body.readonly #btn-res,body.readonly #btn-health,body.readonly #captions{display:none!important}
/* history: the version number never breaks; what tells versions apart is shown first; titles may wrap */
.hrow .htop .hv{white-space:nowrap;flex:none}
.hrow .htop{display:flex;flex-wrap:wrap;align-items:baseline;row-gap:2px}
.hrow .htop .now,.hrow .htop .same-now{flex:none;white-space:nowrap}
.same-now{margin-left:6px;padding:0 7px;border-radius:9px;border:1px solid var(--line);color:var(--muted)}
.hsame{color:#ffd08a}
.hrow .htitle{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;overflow-wrap:anywhere}
.hrow.fresh{box-shadow:0 0 0 2px var(--accent) inset}
/* the frame: a refusal of the server for this place is said in the panel and the frame turns red */
.rp-err{color:#ffb4a8;background:#3a1612;border:1px solid #8a2b22;border-radius:8px;padding:5px 8px;margin:4px 0}
.rp-apply{margin-left:auto}
@media (max-width:899px){
  /* a small 3D view: while a frame is on the map or an offer waits, the floating map buttons step aside
     (their spot is where the frame's corners and the ghosts' labels are) */
  body.framing #btn-logic,body.framing #btn-show,body.framing #tools-tip,body.framing #logic-hint,
  body.offer-open #btn-logic,body.offer-open #btn-show,body.offer-open #logic-hint,
  body.card-open #logic-hint,body.card-open #tools-tip{display:none!important}
  /* the object card leaves the upper part of the view to the object (keepInView turns the camera there) */
  .card{max-height:48%;overflow:auto}
}
/* the narrowest phones: the header buttons fit without a scroll strip (QA r2: «Другая карт») */
@media (max-width:420px){
  .chead{padding-left:8px;padding-right:8px}
  .hbtns{gap:3px}
  .hbtns .btn{padding:0 5px;gap:0;font-size:12px}
  #btn-newmap,#btn-share{font-size:0!important}
  #btn-newmap::before{content:'Ещё карта';font-size:12px}
  #btn-share::before{content:'Ссылка';font-size:12px}
}
