/* role☆lab. Палитра и приёмы взяты с kirssei.space */
@font-face {
    font-family: "Cordata PPC-400";
    src: url("../WebPlus_Cordata_PPC-400.woff") format("woff");
    font-display: swap;
}

:root {
    --paper: #fcf7fd;
    --ink: #000000;
    --sky: #7a9eec;
    --sky-soft: #bccdf5;
    --font: "Cordata PPC-400", Tahoma, Verdana, sans-serif;
    --dither: repeating-conic-gradient(var(--ink) 0 25%, transparent 0 50%) 0 0 / 2px 2px;
    --dither-sky: repeating-conic-gradient(var(--sky) 0 25%, transparent 0 50%) 0 0 / 4px 4px;
}

* { box-sizing: border-box; }

/* атрибут hidden сильнее любых display у классов */
[hidden] { display: none !important; }

html, body { margin: 0; }

body {
    min-height: 100vh;
    background: var(--sky);
    color: var(--ink);
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.45;
}

a { color: var(--ink); }
a:hover { background: var(--ink); color: var(--paper); text-decoration: none; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

img { max-width: 100%; }

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.muted { opacity: .72; }
.small { font-size: 13px; }
.tiny { font-size: 12px; }
.mt-auto { margin-top: auto; }
.row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.stack { display: flex; flex-direction: column; gap: 10px; }
.grow { flex: 1; min-width: 0; }
.h1 { font-size: 30px; line-height: 1.1; margin: 0; font-weight: normal; }
.h2 { font-size: 22px; line-height: 1.15; margin: 0; font-weight: normal; }
.h3 { font-size: 16px; margin: 0 0 6px; font-weight: normal; }

/* ===== корпус устройства ===== */
.stage { isolation: isolate; padding: 32px 20px 48px; }

.device {
    position: relative;
    max-width: 1180px;
    margin: 0 auto;
    padding: 18px 28px 20px;
    background: var(--paper);
    border: 2px solid var(--ink);
    border-radius: 40px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.device::after {
    content: "";
    position: absolute;
    inset: -2px;
    border-radius: 40px;
    transform: translate(10px, 10px);
    z-index: -1;
    background: var(--dither);
    pointer-events: none;
}

.device::before {
    content: "";
    position: absolute;
    inset: 7px;
    border: 1px dotted var(--ink);
    border-radius: 33px;
    pointer-events: none;
}

.screw {
    position: absolute;
    width: 11px; height: 11px;
    border: 1px solid var(--ink);
    border-radius: 50%;
    background: var(--paper);
    z-index: 1;
}
.screw::after {
    content: ""; position: absolute; left: 1px; right: 1px; top: 4px; height: 1px;
    background: var(--ink); transform: rotate(35deg);
}
.screw.tl { left: 16px; top: 16px; } .screw.tr { right: 16px; top: 16px; }
.screw.bl { left: 16px; bottom: 16px; } .screw.br { right: 16px; bottom: 16px; }

.dev-top {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 10px 14px; min-height: 36px; padding: 0 14px; position: relative; z-index: 1;
}

.logo { font-size: 24px; text-decoration: none; white-space: nowrap; }
.logo::after { content: "_"; margin-left: 2px; animation: caret 1s steps(1) infinite; }
.model { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; }

.tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }

.tab {
    display: inline-block;
    padding: 5px 10px;
    border: 1px solid var(--ink);
    background: var(--paper);
    color: var(--ink);
    font-size: 15px;
    font-weight: bold;
    text-decoration: none;
    box-shadow: 0 3px 0 var(--ink);
    transition: transform .08s, box-shadow .08s;
}
.tab:hover { background: var(--ink); color: var(--paper); transform: translateY(-1px); }
.tab:active { transform: translateY(3px); box-shadow: 0 0 0 var(--ink); }
.tab.on { background: var(--ink); color: var(--paper); box-shadow: 0 0 0 var(--ink); transform: translateY(3px); }
.tab .badge { display: inline-block; margin-left: 4px; padding: 0 4px; background: var(--sky); color: var(--ink); }

.leds { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.led { display: inline-block; width: 8px; height: 8px; border: 1px solid var(--ink); background: var(--paper); }
.led.on { background: var(--ink); animation: blink 2.6s steps(1) infinite; }
.led.net { background: var(--sky); animation: ledp 1.2s steps(1) infinite; }
.led.off { background: var(--paper); }

@keyframes blink { 0%, 90% { opacity: 1; } 91%, 100% { opacity: .2; } }
@keyframes ledp { 50% { background: var(--paper); } }
@keyframes caret { 50% { opacity: 0; } }

.bezel {
    background: var(--ink);
    border-radius: 18px;
    padding: 12px;
    position: relative; z-index: 1;
}

.screen {
    position: relative;
    overflow: hidden;
    background: var(--paper);
    border-radius: 8px;
    min-height: 560px;
    display: flex;
    flex-direction: column;
    animation: crt-on .7s steps(7) both;
}

@keyframes crt-on {
    0% { clip-path: inset(50% 0 50% 0); filter: invert(1); }
    40% { clip-path: inset(49% 0 49% 0); filter: invert(1); }
    70% { clip-path: inset(0 0 0 0); filter: invert(1); }
    100% { clip-path: inset(0 0 0 0); filter: none; }
}

.scan {
    position: absolute; inset: 0; pointer-events: none; z-index: 20;
    background: repeating-linear-gradient(0deg, rgba(0, 0, 0, .05) 0 1px, transparent 1px 3px);
}

.tbar {
    flex: none;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    min-height: 32px; padding: 4px 12px;
    background: repeating-linear-gradient(var(--ink) 0 1px, var(--paper) 1px 2px);
    border-bottom: 1px solid var(--ink);
    font-size: 14px;
}
.tbar > * { background: var(--paper); padding: 0 6px; }
.tbar .push { margin-left: auto; }

.screen-body { flex: 1; min-height: 0; display: flex; }
.screen-main { flex: 1; min-width: 0; padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; overflow: auto; }
.panel {
    width: 340px; flex: none;
    border-left: 2px solid var(--ink);
    padding: 14px 16px;
    display: flex; flex-direction: column; gap: 12px;
    overflow: auto;
}
.panel.narrow { width: 220px; border-left: 0; border-right: 2px solid var(--ink); order: -1; }

.dev-bottom {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: 14px 22px; min-height: 64px; padding: 0 18px; position: relative; z-index: 1;
}
.grille {
    width: 90px; height: 40px;
    background-image: radial-gradient(var(--ink) 2px, transparent 2.3px);
    background-size: 9px 9px;
}
.hint { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; }
.sticker {
    margin-left: auto;
    padding: 3px 12px;
    background: var(--sky);
    border: 1px solid var(--ink);
    font-size: 14px;
    transform: rotate(-2deg);
    box-shadow: 0 2px 0 var(--ink);
}
.sticker.ink { background: var(--ink); color: var(--paper); }

/* ===== элементы ===== */
.key {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 44px; padding: 0 18px;
    border: 2px solid var(--ink);
    border-radius: 4px;
    background: var(--paper);
    color: var(--ink);
    font-size: 17px;
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 5px 0 var(--ink);
    transition: transform .06s, box-shadow .06s;
}
.key.sky { background: var(--sky); }
.key.ink { background: var(--ink); color: var(--paper); }
.key.sm { min-height: 34px; padding: 0 12px; font-size: 15px; box-shadow: 0 4px 0 var(--ink); }
.key:hover { background: var(--ink); color: var(--paper); box-shadow: 0 6px 0 var(--ink); transform: translateY(-1px); }
.key:active { transform: translateY(5px); box-shadow: 0 0 0 var(--ink); }
.key:disabled { opacity: .45; cursor: not-allowed; }

.link-btn {
    padding: 0 2px; border: 0; background: none; cursor: pointer;
    text-decoration: underline; font-weight: bold;
}
.link-btn:hover { background: var(--ink); color: var(--paper); text-decoration: none; }
.link-btn.danger { font-weight: normal; }

.fl {
    display: inline-flex; align-items: center; min-height: 30px; padding: 0 10px;
    border: 1px solid var(--ink); background: var(--paper);
    font-size: 14px; text-decoration: none; cursor: pointer;
}
.fl.on { background: var(--ink); color: var(--paper); }

.chip { font-size: 13px; padding: 0 6px; border: 1px solid var(--ink); white-space: nowrap; }
.chip.ink { background: var(--ink); color: var(--paper); }
.chip.sky { background: var(--sky); }

.field, .file {
    width: 100%;
    padding: 6px 8px;
    border: 1px solid var(--ink);
    background: #fff;
    color: var(--ink);
}
textarea.field { resize: vertical; min-height: 64px; }
select.field { padding: 5px 6px; }
.file { background: var(--paper); border-style: dashed; padding: 5px; font-size: 13px; }

.form-row { display: flex; flex-direction: column; gap: 4px; }
.form-row > label { font-size: 13px; }
.form-row .help { font-size: 12px; }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
.form-grid .wide { grid-column: 1 / -1; }
.checks { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 14px; }
.checks label { display: flex; align-items: center; gap: 6px; }
.errorlist { margin: 0; padding: 0; list-style: none; font-weight: bold; font-size: 13px; }
ul.choices { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 14px; }
ul.choices label { display: flex; gap: 6px; align-items: center; }

.box { border: 1px solid var(--ink); background: var(--paper); padding: 10px 12px; position: relative; }
.box.dashed { border-style: dashed; }
.box.sky { background: var(--sky); }
.box.ink { background: var(--ink); color: var(--paper); }
.shadowed { position: relative; }
.shadowed::after {
    content: ""; position: absolute; inset: 0; transform: translate(5px, 5px);
    z-index: -1; background: var(--dither); pointer-events: none;
}

.win { border: 1px solid var(--ink); background: var(--paper); position: relative; z-index: 0; }
.win::after {
    content: ""; position: absolute; inset: -1px; transform: translate(5px, 5px);
    z-index: -1; background: var(--dither); pointer-events: none;
}
.win-head {
    display: flex; justify-content: space-between; gap: 10px; align-items: baseline;
    padding: 3px 8px; border-bottom: 1px solid var(--ink);
    background: repeating-linear-gradient(var(--ink) 0 1px, var(--paper) 1px 2px);
}
.win-head > * { background: var(--paper); padding: 0 6px; }
.win-body { padding: 10px 12px; }

.tok {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; flex: none;
    background: var(--ink); color: var(--paper); font-size: 14px;
}
.tok.me { background: var(--sky); color: var(--ink); outline: 2px solid var(--ink); outline-offset: 1px; animation: hop .5s cubic-bezier(.2, 1.8, .4, 1) both; }
@keyframes hop { 0% { transform: translateY(-22px) scale(.6); opacity: 0; } 100% { transform: none; opacity: 1; } }

.dots::after { content: ""; display: inline-block; width: 1.4em; text-align: left; animation: dots 1.2s steps(1) infinite; }
@keyframes dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }

.placeholder-art {
    background-color: var(--paper);
    background-image: repeating-conic-gradient(var(--ink) 0 25%, transparent 0 50%);
    background-size: 4px 4px;
    border: 1px solid var(--ink);
}
.checker-bg {
    background-color: var(--paper);
    background-image: repeating-conic-gradient(var(--sky-soft) 0 25%, transparent 0 50%);
    background-size: 8px 8px;
}

/* сообщения */
.toasts {
    position: absolute; left: 14px; right: 14px; bottom: 14px; z-index: 30;
    display: flex; flex-direction: column; gap: 6px; pointer-events: none;
}
.toast {
    pointer-events: auto;
    padding: 6px 10px; background: var(--ink); color: var(--paper); font-size: 14px;
    animation: toast 4.5s both;
}
.toast.error { background: var(--paper); color: var(--ink); border: 2px solid var(--ink); }
@keyframes toast { 0% { transform: translateY(10px); opacity: 0; } 6%, 88% { transform: none; opacity: 1; } 100% { opacity: 0; visibility: hidden; } }

.pop { animation: pop .35s cubic-bezier(.2, 1.6, .4, 1) both; }
@keyframes pop { 0% { transform: translateY(8px) scale(.97); opacity: 0; } 100% { transform: none; opacity: 1; } }
.slide { animation: slide .35s cubic-bezier(.2, 1.4, .4, 1) both; }
@keyframes slide { 0% { transform: translateX(18px); opacity: 0; } 100% { transform: none; opacity: 1; } }

.ticker-wrap { flex: 1; min-width: 0; overflow: hidden; }
.ticker { display: inline-block; white-space: nowrap; animation: tick 30s linear infinite; }
@keyframes tick { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ===== каталог ===== */
.cards { display: flex; flex-direction: column; gap: 12px; }
.card {
    display: block; text-decoration: none; color: var(--ink);
    border: 1px solid var(--ink); background: var(--paper); padding: 10px 12px;
    box-shadow: 0 4px 0 var(--ink);
    transition: transform .12s, box-shadow .12s;
}
.card:hover { background: var(--ink); color: var(--paper); transform: translateY(-2px); box-shadow: 0 6px 0 var(--ink); }
.card.on { background: var(--sky); color: var(--ink); }
.card .t { font-size: 20px; margin: 4px 0 2px; }
.card .meta { display: flex; gap: 12px; font-size: 13px; margin-top: 6px; }
.status-led { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; margin-left: auto; }

.cover { width: 140px; height: 104px; flex: none; object-fit: cover; border: 1px solid var(--ink); image-rendering: pixelated; }
.heroes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.hero { display: flex; gap: 10px; border: 1px solid var(--ink); padding: 8px; background: #fff; }
.hero .pic { width: 54px; height: 54px; flex: none; object-fit: contain; display: flex; align-items: flex-end; justify-content: center; }
.hero .who { font-size: 15px; }
.hero .role { font-size: 13px; text-decoration: underline; }
.hero p { margin: 4px 0 0; font-size: 13px; }

/* ===== карта ===== */
.map-wrap { position: relative; flex: 1; min-height: 360px; overflow: auto; border: 1px solid var(--ink);
    background-color: var(--paper);
    background-image: linear-gradient(var(--sky-soft) 1px, transparent 1px), linear-gradient(90deg, var(--sky-soft) 1px, transparent 1px);
    background-size: 24px 24px; }
.map { position: relative; }
.map svg { position: absolute; inset: 0; pointer-events: none; }
.room {
    position: absolute; width: 160px; height: 90px;
    border: 2px solid var(--ink); background: var(--paper);
    padding: 6px 8px; text-align: left; color: var(--ink);
    display: flex; flex-direction: column; justify-content: space-between;
}
.room .name { font-size: 15px; line-height: 1.15; }
.room .badge { font-size: 12px; margin-left: auto; }
.room .people { display: flex; gap: 4px; min-height: 24px; }
.room form { position: absolute; inset: 0; }
.room button.go { position: absolute; inset: 0; width: 100%; background: none; border: 0; cursor: pointer; }
.room.adj { box-shadow: 0 4px 0 var(--ink); background: #fff; transition: transform .12s, box-shadow .12s; }
.room.adj:hover { transform: translateY(-3px); box-shadow: 0 7px 0 var(--ink); }
.room.adj:hover .name { background: var(--ink); color: var(--paper); }
.room.here { background: var(--sky); animation: here 1.6s steps(2) infinite; }
@keyframes here { 50% { box-shadow: 0 0 0 4px var(--paper), 0 0 0 6px var(--ink); } }
.room.locked { background-color: var(--paper); background-image: repeating-conic-gradient(var(--sky-soft) 0 25%, transparent 0 50%); background-size: 4px 4px; }
.room .icon { position: absolute; right: 6px; bottom: 6px; width: 30px; height: 30px; object-fit: contain; image-rendering: pixelated; }
.legend { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 13px; align-items: center; }
.cta { animation: cta 1.6s steps(2) infinite; }
@keyframes cta { 50% { transform: translateY(-2px); } }

/* ===== беседа ===== */
.scene-body { flex: 1; min-height: 0; display: flex; }
.scene {
    position: relative; flex: 1; min-width: 0; min-height: 460px; overflow: hidden;
    background-color: var(--paper);
    background-image: repeating-conic-gradient(var(--sky-soft) 0 25%, transparent 0 50%);
    background-size: 4px 4px;
    background-position: center;
}
.scene.has-bg { background-size: cover; background-repeat: no-repeat; }
.scene .floor { position: absolute; left: 0; right: 0; bottom: 0; height: 120px; background: var(--ink); border-top: 4px solid var(--sky); }
.scene.has-bg .floor { display: none; }
.scene .fg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: bottom; z-index: 3; pointer-events: none; }
.scene .loc-tag { position: absolute; left: 12px; top: 10px; z-index: 6; font-size: 13px; background: var(--paper); border: 1px solid var(--ink); padding: 1px 6px; }
.scene .sound-btn { position: absolute; right: 12px; top: 10px; z-index: 6; }

.slot { position: absolute; bottom: 92px; width: 34%; display: flex; flex-direction: column; align-items: center; transition: left .5s cubic-bezier(.3, 1.5, .5, 1); z-index: 2; }
.slot.front { z-index: 4; }
.slot[data-pos="left"] { left: 0; }
.slot[data-pos="center"] { left: 33%; }
.slot[data-pos="right"] { left: 66%; }
.sprite-tag { font-size: 13px; background: var(--paper); border: 1px solid var(--ink); padding: 0 6px; margin-bottom: 6px; white-space: nowrap; }
.sprite { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 300px; transform-origin: bottom center; transition: opacity .3s; }
.sprite img { max-height: 320px; max-width: 280px; object-fit: contain; display: block; }
.slot.dim .sprite { opacity: .55; }
.slot.speaking .sprite { animation: bob 1.2s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(-5px); } }
.sprite .ph-head { width: 88px; height: 88px; border-radius: 50%; position: relative; z-index: 1; }
.sprite .ph-body { width: 150px; height: 140px; margin-top: -12px; border-radius: 60px 60px 8px 8px; display: flex; align-items: center; justify-content: center; }
.sprite .ph-body span { font-size: 13px; background: var(--paper); border: 1px solid var(--ink); padding: 1px 6px; }
.slot.enter .sprite { animation: enter .35s ease-out; }
@keyframes enter { 0% { opacity: 0; transform: translateY(14px); } 100% { opacity: 1; transform: none; } }

.dbox {
    position: absolute; left: 16px; right: 16px; bottom: 16px; z-index: 5;
    min-height: 112px; padding: 22px 22px 14px;
    background: var(--ink); color: var(--paper);
    border: 0; text-align: left; cursor: pointer;
    box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--ink);
    font-size: 19px; line-height: 1.45;
}
.dbox .nametag {
    position: absolute; left: 14px; top: -15px;
    background: var(--sky); color: var(--ink); padding: 1px 12px; font-size: 17px;
    border: 2px solid var(--ink);
}
.dbox .nametag:empty { display: none; }
.dbox .caret { position: absolute; right: 16px; bottom: 8px; animation: caret 1s steps(1) infinite; }
.dbox.action .text { font-style: italic; }
.dbox .waiting { opacity: .7; }

.shout {
    position: absolute; inset: 0; z-index: 8;
    display: none; align-items: center; justify-content: center; overflow: hidden;
    background: rgba(252, 247, 253, .6);
}
.shout.on { display: flex; }
.shout .rays { position: absolute; inset: -40%; background: repeating-conic-gradient(from 0deg, rgba(0, 0, 0, .16) 0 7deg, transparent 7deg 15deg); animation: spin 6s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.shout .word {
    position: relative; font-size: clamp(54px, 9vw, 100px); color: var(--paper);
    text-shadow: 3px 0 0 #000, -3px 0 0 #000, 0 3px 0 #000, 0 -3px 0 #000, 3px 3px 0 #000, -3px -3px 0 #000, 3px -3px 0 #000, -3px 3px 0 #000, 9px 9px 0 var(--sky);
    animation: stamp .55s cubic-bezier(.2, 1.7, .4, 1) both;
}
.shout img.word-img { position: relative; max-width: 70%; max-height: 70%; animation: stamp .55s cubic-bezier(.2, 1.7, .4, 1) both; }
.shout .by { position: absolute; bottom: 30%; font-size: 14px; background: var(--ink); color: var(--paper); padding: 2px 10px; }
@keyframes stamp { 0% { transform: rotate(-7deg) scale(2.6); opacity: 0; } 100% { transform: rotate(-7deg) scale(1); opacity: 1; } }
.shake { animation: shake .5s; }
@keyframes shake { 0%, 100% { transform: translate(0, 0); } 15% { transform: translate(-9px, 4px); } 30% { transform: translate(8px, -5px); } 45% { transform: translate(-6px, 3px); } 60% { transform: translate(5px, -2px); } 80% { transform: translate(-2px, 1px); } }

.log {
    position: absolute; left: 14px; right: 14px; top: 42px; max-height: 58%; overflow: auto; z-index: 7;
    background: var(--ink); color: var(--paper); padding: 10px 14px; font-size: 15px; display: none;
}
.log.on { display: block; }
.log .l { margin-bottom: 5px; }
.log .who { background: var(--sky); color: var(--ink); padding: 0 4px; margin-right: 4px; }
.log .ooc { opacity: .75; }

.emo-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.emo {
    position: relative; height: 62px; padding: 0 0 3px;
    display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
    border: 1px solid var(--ink); background: var(--paper); cursor: pointer; font-size: 13px; overflow: hidden;
    transition: transform .1s;
}
.emo:hover { transform: translateY(-2px); }
.emo .th { position: absolute; inset: 3px 3px 18px; display: flex; align-items: flex-end; justify-content: center; }
.emo .th img { max-height: 100%; max-width: 100%; object-fit: contain; }
.emo .lb { position: relative; z-index: 1; background: var(--paper); padding: 0 4px; }
.emo.on { background: var(--ink); }
.emo.on .lb { background: var(--ink); color: var(--paper); }
.emo .pend { position: absolute; top: 2px; right: 2px; font-size: 11px; background: var(--sky); padding: 0 3px; z-index: 1; }

.seg { display: flex; gap: 2px; padding: 2px; border: 1px solid var(--ink); }
.seg button { flex: 1; min-height: 30px; border: 0; background: transparent; cursor: pointer; font-size: 14px; }
.seg button.on { background: var(--ink); color: var(--paper); }

.controls { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; width: 100%; }
.dpad { display: grid; grid-template-columns: repeat(3, 42px); grid-template-rows: repeat(3, 42px); }
.dpad button { background: var(--ink); color: var(--paper); border: 0; font-size: 15px; cursor: pointer; box-shadow: inset 0 -3px 0 var(--sky); }
.dpad button:hover { background: var(--sky); color: var(--ink); }
.dpad button:active { transform: translateY(2px); box-shadow: none; }
.dpad .c { background: var(--ink); }
.reacts { display: flex; gap: 12px; flex-wrap: wrap; margin: 0 auto; justify-content: center; }
.reacts .key { min-width: 120px; min-height: 54px; font-size: 19px; }
.round {
    width: 62px; height: 62px; border-radius: 50%;
    border: 2px solid var(--ink); box-shadow: 0 5px 0 var(--ink);
    font-size: 22px; cursor: pointer; background: var(--ink); color: var(--paper);
    transition: transform .06s, box-shadow .06s;
}
.round.sky { background: var(--sky); color: var(--ink); }
.round:hover { filter: invert(1); }
.round:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--ink); }
.ab { display: flex; gap: 16px; align-items: flex-end; }
.ab > div { display: flex; flex-direction: column; align-items: center; gap: 4px; font-size: 13px; }
.ab > div:first-child { margin-bottom: 16px; }

/* ===== студия ===== */
.list-btn {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 6px 8px; border: 0; text-decoration: none; font-size: 15px; color: var(--ink);
}
.list-btn:hover { background: var(--ink); color: var(--paper); }
.list-btn.on { background: var(--sky); color: var(--ink); outline: 1px solid var(--ink); }
.slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
.slot-card { border: 1px solid var(--ink); background: #fff; display: flex; flex-direction: column; animation: pop .35s both; }
.slot-card.on { outline: 3px solid var(--sky); }
.slot-card .thumb { height: 110px; display: flex; align-items: flex-end; justify-content: center; border-bottom: 1px solid var(--ink); cursor: pointer; padding: 0; border-width: 0 0 1px; width: 100%; }
.slot-card .thumb img { max-height: 104px; max-width: 100%; object-fit: contain; }
.slot-card .meta { padding: 6px 8px; display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.slot-card form { display: flex; flex-direction: column; gap: 4px; padding: 0 8px 8px; }
.frames { display: flex; gap: 4px; font-size: 12px; }
.frames span::before { content: "○ "; }
.frames span.on::before { content: "● "; }
.preview {
    position: relative; height: 240px; border: 2px solid var(--ink); overflow: hidden;
    background-color: var(--paper); background-image: repeating-conic-gradient(var(--sky-soft) 0 25%, transparent 0 50%);
    background-size: 4px 4px; background-position: center;
}
.preview.has-bg { background-size: cover; }
.preview .pv-sprite { position: absolute; left: 0; right: 0; bottom: 36px; display: flex; justify-content: center; z-index: 1; }
.preview .pv-sprite.front { z-index: 3; }
.preview .pv-sprite > div { transform-origin: bottom center; }
.preview .pv-sprite img { max-height: 180px; max-width: 220px; object-fit: contain; display: block; }
.preview .pv-fg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: bottom; z-index: 2; }
.preview .pv-line { position: absolute; left: 8px; right: 8px; bottom: 6px; z-index: 4; background: var(--ink); color: var(--paper); font-size: 13px; padding: 4px 8px; }
.preview .pv-line b { background: var(--sky); color: var(--ink); padding: 0 4px; margin-right: 4px; font-weight: normal; }
.range-row { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.range-row input[type=range] { flex: 1; accent-color: var(--ink); }
.layer-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.layer { border: 1px dashed var(--ink); min-height: 120px; padding: 8px; display: flex; flex-direction: column; gap: 6px; justify-content: flex-end; background-size: cover; background-position: center; }
.layer .lbl { align-self: flex-start; background: var(--paper); padding: 0 6px; border: 1px solid var(--ink); font-size: 14px; }

/* ===== модерация ===== */
.assets { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.asset { border: 1px solid var(--ink); background: #fff; display: flex; flex-direction: column; animation: pop .35s both; }
.asset .pv { position: relative; height: 110px; display: flex; align-items: flex-end; justify-content: center; gap: 6px; border-bottom: 1px solid var(--ink); padding: 4px; }
.asset .pv img { max-height: 100px; max-width: 48%; object-fit: contain; }
.asset .pv .lbl { position: absolute; left: 4px; top: 4px; font-size: 12px; background: var(--paper); border: 1px solid var(--ink); padding: 0 4px; }
.asset .stamp {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.asset .stamp span { font-size: 20px; border: 3px solid var(--ink); background: rgba(252, 247, 253, .92); padding: 1px 10px; transform: rotate(-9deg); animation: stamp2 .45s cubic-bezier(.2, 1.7, .4, 1) both; }
.asset .stamp.approved span { background: var(--sky); }
@keyframes stamp2 { 0% { transform: rotate(-9deg) scale(2.4); opacity: 0; } 100% { transform: rotate(-9deg) scale(1); opacity: 1; } }
.asset .info { padding: 6px 8px; font-size: 13px; flex: 1; }
.asset .info b { font-size: 15px; font-weight: normal; display: block; }
.asset .acts { display: flex; border-top: 1px solid var(--ink); }
.asset .acts button { flex: 1; min-height: 34px; border: 0; background: var(--paper); cursor: pointer; font-size: 14px; }
.asset .acts button + button { border-left: 1px solid var(--ink); }
.asset .acts button:hover { background: var(--ink); color: var(--paper); }
.asset details { border-top: 1px solid var(--ink); padding: 6px 8px; font-size: 13px; }
.asset details summary { cursor: pointer; }
.asset .note { padding: 6px 8px; font-size: 13px; background: var(--sky); border-top: 1px solid var(--ink); }
.mx { border-collapse: collapse; width: 100%; font-size: 13px; }
.mx th, .mx td { border: 1px solid var(--ink); padding: 4px; text-align: center; }
.mx th { background: var(--ink); color: var(--paper); font-weight: normal; }
.mx td:first-child, .mx th:first-child { text-align: left; }
.members { list-style: none; margin: 0; padding: 0; border: 1px solid var(--ink); }
.members li { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-bottom: 1px solid var(--ink); font-size: 14px; flex-wrap: wrap; }
.members li:last-child { border-bottom: 0; }
.members form { display: flex; gap: 6px; margin-left: auto; align-items: center; }
.members select { padding: 2px 4px; border: 1px solid var(--ink); background: #fff; }

/* ===== вход ===== */
.auth { max-width: 420px; margin: 40px auto; width: 100%; }

/* ===== адаптив ===== */
@media (max-width: 900px) {
    .stage { padding: 14px 10px 30px; }
    .device { border-radius: 22px; padding: 12px 12px 14px; }
    .device::after, .device::before { border-radius: 22px; }
    .device::after { transform: translate(6px, 6px); }
    .screw { display: none; }
    .dev-top { padding: 0 4px; }
    .tabs { margin-left: 0; width: 100%; }
    .leds { display: none; }
    .bezel { padding: 6px; border-radius: 12px; }
    .screen-body, .scene-body { flex-direction: column; }
    .panel, .panel.narrow { width: auto; border-left: 0; border-right: 0; border-top: 2px solid var(--ink); order: 0; }
    .scene { min-height: 420px; }
    .sprite { height: 220px; }
    .sprite img { max-height: 230px; max-width: 160px; }
    .sprite .ph-body { width: 100px; height: 110px; }
    .sprite .ph-head { width: 64px; height: 64px; }
    .dbox { font-size: 16px; min-height: 100px; }
    .heroes, .form-grid, .layer-grid { grid-template-columns: 1fr; }
    .dev-bottom { padding: 0 4px; }
    .grille, .hint { display: none; }
    .controls { justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* выбор файла в стиле терминала */
input[type=file]::file-selector-button {
    margin-right: 8px; padding: 2px 10px;
    border: 1px solid var(--ink); background: var(--paper); color: var(--ink);
    font: inherit; cursor: pointer; box-shadow: 0 2px 0 var(--ink);
}
input[type=file]::file-selector-button:hover { background: var(--ink); color: var(--paper); }
.panel.narrow { width: 250px; }
.panel.narrow .seg { flex-wrap: wrap; }
.panel.narrow .seg .fl { padding: 0 6px; font-size: 13px; }

/* ===== план локации (точки внутри) ===== */
.map-wrap { min-height: 300px; }
.plan {
    position: relative; aspect-ratio: 16 / 9; max-height: 420px; width: 100%;
    background-color: var(--paper);
    background-image: repeating-conic-gradient(var(--sky-soft) 0 25%, transparent 0 50%);
    background-size: 4px 4px; background-position: center;
}
.plan.has-bg { background-size: cover; }
.spot {
    position: absolute; transform: translate(-50%, -100%);
    display: flex; flex-direction: column; align-items: center; gap: 3px; z-index: 1;
    transition: transform .25s ease;
}
.spot button {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    border: 0; background: none; padding: 0; cursor: pointer; color: var(--ink);
}
.spot .lbl { background: var(--paper); border: 1px solid var(--ink); padding: 0 6px; font-size: 13px; white-space: nowrap; box-shadow: 0 2px 0 var(--ink); }
.spot .pin { width: 12px; height: 12px; background: var(--paper); border: 2px solid var(--ink); transform: rotate(45deg); order: 2; }
.spot button:hover .lbl { background: var(--ink); color: var(--paper); }
.spot button:hover { transform: translateY(-2px); }
.spot.here { z-index: 2; }
.spot.here .lbl { background: var(--sky); }
.spot.here .pin { background: var(--sky); box-shadow: 0 0 0 4px rgba(122, 158, 236, .45); animation: pulse-soft 2.4s ease-in-out infinite; }
.spot.locked .lbl { border-style: dashed; }
.spot button:disabled { cursor: not-allowed; opacity: .7; }
.spot .people { display: flex; gap: 2px; min-height: 0; }
.spot .people .tok { width: 18px; height: 18px; font-size: 11px; }
.spot.common { left: 10px; bottom: 10px; top: auto; transform: none; flex-direction: row; align-items: center; }
.spot.common .pin { order: 0; }
.spot.common button { flex-direction: row; gap: 6px; }
@keyframes pulse-soft { 50% { box-shadow: 0 0 0 8px rgba(122, 158, 236, 0); } }
.spot-form.active { outline: 3px solid var(--sky); }
[data-plan] { cursor: crosshair; }

/* ===== сцена-ансамбль ===== */
.actors { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.actor {
    --s: 1;
    position: absolute; bottom: 92px; left: 50%;
    display: flex; flex-direction: column; align-items: center;
    transform: translateX(-50%) scale(var(--s));
    transform-origin: bottom center;
    transition: left .6s cubic-bezier(.25, .9, .3, 1), bottom .6s cubic-bezier(.25, .9, .3, 1),
                transform .6s cubic-bezier(.25, .9, .3, 1), opacity .45s ease, filter .45s ease;
}
.actor[data-row="back"] { bottom: 150px; opacity: .55; filter: contrast(.7) brightness(1.08); }
.actor[data-row="back"] .sprite-tag { font-size: 15px; }
.actor.dim { opacity: .78; }
.actor.entering { opacity: 0; transform: translateX(-50%) translateY(18px) scale(var(--s)); }
.actor.leaving { opacity: 0; transform: translateX(-50%) translateY(18px) scale(var(--s)); }
.actor.in-front-layer[data-row="front"] { z-index: 4 !important; }
.actor .body { display: flex; justify-content: center; align-items: flex-end; height: 300px; transform-origin: bottom center; transition: transform .4s ease; }
.actor .frames { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; }
.actor .frames img { display: block; max-height: 320px; max-width: 280px; object-fit: contain; }
.actor .frames .f-talk { position: absolute; left: 0; right: 0; bottom: 0; margin: 0 auto; opacity: 0; }
.actor.talking .frames .f-talk { opacity: 1; }
.actor.talking .frames .f-idle { opacity: 0; }
.actor .frames.in { animation: frames-in .25s ease-out both; }
.actor .frames.out { position: absolute; bottom: 0; animation: frames-out .25s ease-in both; }
@keyframes frames-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes frames-out { from { opacity: 1; } to { opacity: 0; } }
.actor.speaking .body { animation: bob 2.4s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(-4px); } }
.actor.targeted .sprite-tag { background: var(--sky); }
.actor.targeted .sprite-tag::before { content: "◆ "; }
.actor .ph-head { width: 88px; height: 88px; border-radius: 50%; position: relative; z-index: 1; }
.actor .ph-body { width: 150px; height: 140px; margin-top: -12px; border-radius: 60px 60px 8px 8px; display: flex; align-items: center; justify-content: center; }
.actor .ph-body span { font-size: 13px; background: var(--paper); border: 1px solid var(--ink); padding: 1px 6px; }

.cast {
    position: absolute; left: 12px; top: 38px; z-index: 6; max-width: calc(100% - 24px);
    display: flex; flex-wrap: wrap; align-items: center; gap: 3px;
    background: var(--paper); border: 1px solid var(--ink); padding: 3px 6px 3px 4px;
}
.cast:empty { display: none; }
.cast-count { font-size: 13px; padding: 0 6px 0 2px; }
.cast .tok { width: 20px; height: 20px; font-size: 12px; transition: background .3s, color .3s, transform .3s; }
.cast .tok.back { background: var(--paper); color: var(--ink); border: 1px solid var(--ink); }
.cast .tok.speaking { background: var(--sky); color: var(--ink); transform: translateY(-2px); outline: 1px solid var(--ink); }

@media (max-width: 900px) {
    .actor .body { height: 220px; }
    .actor .frames img { max-height: 230px; max-width: 160px; }
    .actor[data-row="back"] { bottom: 130px; }
    .actor .ph-body { width: 100px; height: 110px; }
    .actor .ph-head { width: 64px; height: 64px; }
}

/* ===== мягкие переходы (вместо ступенчатых вспышек) ===== */
.screen { animation: power-on .6s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes power-on {
    0% { opacity: 0; clip-path: inset(47% 0 47% 0); filter: brightness(1.5); }
    45% { opacity: 1; clip-path: inset(0 0 0 0); filter: brightness(1.15); }
    100% { opacity: 1; clip-path: inset(0 0 0 0); filter: none; }
}
/* при переходе между экранами — только лёгкое проявление */
html.booted .screen { animation: screen-in .28s ease-out both; }
@keyframes screen-in { from { opacity: .4; transform: translateY(3px); } to { opacity: 1; transform: none; } }
html.leaving .screen { opacity: .5; transition: opacity .15s ease; }

.led.on { animation: led-soft 3.2s ease-in-out infinite; }
.led.net { animation: led-net 2.4s ease-in-out infinite; }
@keyframes led-soft { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@keyframes led-net { 0%, 100% { background: var(--sky); } 50% { background: var(--paper); } }
.room.here { animation: here-soft 2.4s ease-in-out infinite; }
@keyframes here-soft { 0%, 100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); } 50% { box-shadow: 0 0 0 4px var(--paper), 0 0 0 6px var(--ink); } }
.cta { animation: cta-soft 2.4s ease-in-out infinite; }
@keyframes cta-soft { 50% { transform: translateY(-2px); } }

.tab, .fl, .card, .list-btn, .key, .link-btn, .room.adj .name, .asset .acts button, a {
    transition: background-color .15s ease, color .15s ease, transform .12s ease, box-shadow .12s ease;
}
.toast { animation-timing-function: ease; }

/* тень окна под окном, а не поверх него */
.win { z-index: auto; }
.file-cur { display: inline-flex; gap: 4px; align-items: center; font-size: 13px; background: var(--paper); padding: 0 6px; border: 1px solid var(--ink); align-self: flex-start; }
.file-cur label { display: inline-flex; gap: 4px; align-items: center; }
.layer .file-cur { margin-bottom: 2px; }
.actor[data-row="back"] { bottom: 215px; opacity: .6; }
.actor[data-row="back"] .sprite-tag { font-size: 17px; }
@media (max-width: 900px) { .actor[data-row="back"] { bottom: 170px; } }
/* подписи заднего ряда не уменьшаются вместе со спрайтом */
.actor .sprite-tag { transform: scale(calc(1 / var(--s))); transform-origin: bottom center; margin-bottom: calc(6px / var(--s)); transition: background-color .3s ease; }
.actor[data-row="back"] .sprite-tag { font-size: 13px; }
.actor.targeted[data-row="back"] { opacity: .95; filter: none; }
@media (max-width: 900px) {
    /* на узком экране подписи заднего ряда прячем — их имена есть в полоске состава */
    .actor[data-row="back"]:not(.targeted) .sprite-tag { visibility: hidden; }
    .actor .sprite-tag { font-size: 12px; }
}

/* ===== поле локации: ширина × высота в клетках задаются через --gw и --gh ===== */
.world > summary { cursor: pointer; list-style: none; }
.world > summary::-webkit-details-marker { display: none; }
.world > summary::before { content: "▸ "; }
.world[open] > summary::before { content: "▾ "; }
.world .map-wrap { min-height: 0; max-height: 330px; }
.board-wrap {
    --gw: 12; --gh: 12;
    width: 100%; margin: 0 auto;
    /* квадратное поле — до 720 px; широкое растягивается, высокое не вылезает за экран */
    max-width: min(calc(720px * max(1, var(--gw) / var(--gh))), calc((var(--screen-h) - 150px) * var(--gw) / var(--gh)));
}
.board {
    position: relative; width: 100%; aspect-ratio: var(--gw) / var(--gh); container-type: inline-size;
    border: 2px solid var(--ink); background-color: var(--paper);
    background-size: cover; background-position: center; image-rendering: pixelated;
    cursor: pointer; outline-offset: 3px; user-select: none; overflow: hidden;
}
.board.no-bg { background-image: repeating-conic-gradient(var(--sky-soft) 0 25%, transparent 0 50%); background-size: 8px 8px; }
.b-grid {
    position: absolute; inset: 0; pointer-events: none; z-index: 1;
    background-image: linear-gradient(rgba(0, 0, 0, .22) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 0, 0, .22) 1px, transparent 1px);
    background-size: calc(100% / var(--gw)) calc(100% / var(--gh));
}
.b-layer { position: absolute; inset: 0; pointer-events: none; }
#b-objects { z-index: 2; }
#b-items { z-index: 3; }
#b-marks { z-index: 4; }
#b-chips { z-index: 6; }
.b-hover { position: absolute; display: none; z-index: 5; pointer-events: none; outline: 2px dashed var(--ink); outline-offset: -2px; background: rgba(122, 158, 236, .25); transition: left .08s ease, top .08s ease; }
.obj {
    position: absolute; pointer-events: auto; padding: 2px; border: 0; background: transparent; cursor: help;
    display: flex; align-items: center; justify-content: center;
}
.obj img { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }
.obj .obj-name { font-size: 11px; line-height: 1.1; background: var(--paper); border: 1px solid var(--ink); padding: 1px 3px; text-align: center; }
.obj.solid:not(:has(img)) { background: repeating-conic-gradient(var(--ink) 0 25%, transparent 0 50%) 0 0 / 4px 4px; border: 1px solid var(--ink); }
.obj:not(.solid):not(:has(img)) { border: 1px dashed var(--ink); }
.obj:hover, .obj.on { outline: 2px solid var(--sky); outline-offset: -2px; }
.item-on-floor { position: absolute; display: flex; align-items: center; justify-content: center; }
.item-on-floor img { width: 62%; height: 62%; object-fit: contain; image-rendering: pixelated; filter: drop-shadow(1px 1px 0 var(--paper)) drop-shadow(-1px -1px 0 var(--paper)); animation: item-float 3s ease-in-out infinite; }
.item-on-floor .glyph { font-size: 18px; color: var(--ink); text-shadow: 1px 1px 0 var(--paper); animation: item-float 3s ease-in-out infinite; }
.item-on-floor .count { position: absolute; right: 2px; bottom: 1px; font-size: 11px; background: var(--ink); color: var(--paper); padding: 0 3px; }
@keyframes item-float { 50% { transform: translateY(-2px); } }
.ring { position: absolute; border: 1px dashed var(--ink); background: rgba(122, 158, 236, .14); transition: left .3s ease, top .3s ease; }
.talk-mark { position: absolute; display: flex; align-items: flex-start; justify-content: flex-end; }
.talk-mark .bubble { margin: -6px -6px 0 0; background: var(--paper); border: 1px solid var(--ink); font-size: 12px; padding: 0 3px; min-width: 22px; height: 16px; line-height: 14px; }
.pawn {
    position: absolute; width: calc(100% / var(--gw) * .66); aspect-ratio: 1; transform: translate(-50%, -50%);
    transition: left .35s ease, top .35s ease, width .25s ease, opacity .3s ease;
    display: flex; flex-direction: column; align-items: center;
}
.pawn.walking { transition: left .12s linear, top .12s linear; }
.pawn-face {
    width: 100%; height: 100%; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--ink); color: var(--paper); border: 2px solid var(--paper); box-shadow: 0 0 0 1px var(--ink), 0 3px 0 var(--ink);
    font-size: min(15px, calc(100cqw / var(--gw) * .32));
}
.pawn.me .pawn-face { background: var(--sky); color: var(--ink); }
.pawn.me::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 1px solid var(--ink); animation: pulse-ring 2.4s ease-in-out infinite; }
@keyframes pulse-ring { 50% { transform: scale(1.12); opacity: .4; } }
.pawn.small { width: calc(100% / var(--gw) * .42); }
.pawn.small .pawn-face { font-size: 11px; border-width: 1px; }
.pawn.hidden { opacity: 0; }
.pawn.gone { opacity: 0; }
.pawn-name { position: absolute; top: 100%; margin-top: 3px; font-size: 11px; white-space: nowrap; background: var(--paper); border: 1px solid var(--ink); padding: 0 3px; opacity: 0; transition: opacity .2s; }
.pawn.me .pawn-name, .board:hover .pawn:not(.small) .pawn-name { opacity: 1; }
.board-toast { position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%); z-index: 8; background: var(--ink); color: var(--paper); font-size: 13px; padding: 2px 10px; opacity: 0; pointer-events: none; }
.board-toast.on { animation: btoast 2.2s ease both; }
@keyframes btoast { 0% { opacity: 0; transform: translate(-50%, 6px); } 10%, 80% { opacity: 1; transform: translate(-50%, 0); } 100% { opacity: 0; } }
.legend-ring { display: inline-block; width: 12px; height: 12px; border: 1px dashed var(--ink); background: rgba(122, 158, 236, .3); vertical-align: -1px; }
.legend-bubble { display: inline-block; border: 1px solid var(--ink); background: var(--paper); padding: 0 2px; min-width: 20px; font-size: 11px; }
.inv-item { border: 1px solid var(--ink); background: #fff; padding: 4px 6px; }
.inv-item summary { display: flex; align-items: center; gap: 8px; cursor: pointer; list-style: none; font-size: 14px; }
.inv-item summary::-webkit-details-marker { display: none; }
.inv-item[open] { background: var(--paper); }
.inv-item p { margin: 6px 0; }
.inv-pic { width: 28px; height: 28px; flex: none; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--ink); background: var(--paper); }
.inv-pic img { max-width: 100%; max-height: 100%; image-rendering: pixelated; }

/* ===== беседа: только говорящий ===== */
.speaker { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.solo {
    position: absolute; left: 50%; bottom: 92px;
    transform: translateX(-50%); transform-origin: bottom center;
    display: flex; flex-direction: column; align-items: center;
    transition: opacity .35s ease, transform .4s cubic-bezier(.25, .9, .3, 1);
}
.solo.entering { opacity: 0; transform: translateX(calc(-50% + 40px)); }
.solo.leaving { opacity: 0; transform: translateX(calc(-50% - 40px)); }
.solo .body { display: flex; justify-content: center; align-items: flex-end; height: 340px; transform-origin: bottom center; }
.solo .frames { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; }
.solo .frames img { display: block; max-height: 360px; max-width: 340px; object-fit: contain; }
.solo .frames .f-talk { position: absolute; left: 0; right: 0; bottom: 0; margin: 0 auto; opacity: 0; }
.solo.talking .frames .f-talk { opacity: 1; }
.solo.talking .frames .f-idle { opacity: 0; }
.solo .frames.in { animation: frames-in .25s ease-out both; }
.solo .frames.out { position: absolute; bottom: 0; animation: frames-out .25s ease-in both; }
.solo .ph-head { width: 100px; height: 100px; border-radius: 50%; position: relative; z-index: 1; }
.solo .ph-body { width: 170px; height: 160px; margin-top: -12px; border-radius: 70px 70px 8px 8px; display: flex; align-items: center; justify-content: center; }
.solo .ph-body span { font-size: 13px; background: var(--paper); border: 1px solid var(--ink); padding: 1px 6px; }
.person { padding: 2px 4px; transition: background-color .25s ease; }
.person.speaking { background: var(--sky); }
.person.speaking::after { content: "говорит"; margin-left: auto; font-size: 11px; }
.evidence { position: absolute; right: 14px; top: 44px; width: min(320px, 60%); z-index: 6; }
.evidence img { width: 64px; height: 64px; object-fit: contain; image-rendering: pixelated; flex: none; border: 1px solid var(--ink); background: var(--paper); }
.away { position: absolute; inset: 0; z-index: 9; display: flex; align-items: center; justify-content: center; background: rgba(252, 247, 253, .7); }
.away .win { width: min(360px, 90%); }
@media (max-width: 900px) {
    .solo .body { height: 240px; }
    .solo .frames img { max-height: 250px; max-width: 220px; }
}

/* ===== редактор поля в студии ===== */
.board.editor { cursor: crosshair; }
.editor-wrap { max-width: min(calc(560px * max(1, var(--gw) / var(--gh))), calc(60vh * var(--gw) / var(--gh))); margin: 0; }
.board.editor .obj, .board.editor .item-on-floor, .board.editor .spawn-mark { position: absolute; pointer-events: none; z-index: 2; }
.board.editor .obj.on { outline: 3px solid var(--sky); outline-offset: -3px; z-index: 3; }
.board.editor .new-marker { background: rgba(122, 158, 236, .35); border: 2px dashed var(--ink); }
.spawn-mark { width: calc(100% / var(--gw)); height: calc(100% / var(--gh)); display: flex; align-items: center; justify-content: center; font-size: 10px; border: 2px dotted var(--ink); background: rgba(252, 247, 253, .7); }
.cell-form.active { outline: 3px solid var(--sky); }
.cell-form > summary { cursor: pointer; list-style: none; gap: 8px; }
.cell-form > summary::-webkit-details-marker { display: none; }

/* радиокнопки режима мира */
.form-row ul, .form-row div[id$="mode"] { list-style: none; margin: 0; padding: 0; display: flex; gap: 6px 16px; flex-wrap: wrap; }
.form-row ul label, .form-row div[id$="mode"] label { display: flex; gap: 6px; align-items: center; }

/* ===== кубики d6 ===== */
.dice { display: inline-flex; gap: 6px; align-items: center; }
.die {
    display: inline-grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
    width: 34px; height: 34px; padding: 4px; gap: 2px;
    background: var(--paper); border: 2px solid var(--ink); box-shadow: 0 3px 0 var(--ink);
}
.die i { display: block; }
.die i.on { background: var(--ink); border-radius: 0; margin: 1px; }
.die.rolling { animation: die-shake .14s steps(2) infinite; }
.die.landed { animation: die-land .3s cubic-bezier(.2, 1.6, .4, 1); }
@keyframes die-shake { 50% { transform: translate(1px, -2px) rotate(8deg); } }
@keyframes die-land { 0% { transform: translateY(-6px) scale(1.15); } 100% { transform: none; } }
.dice-pop {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 9;
    min-width: 260px; max-width: 86%; background: var(--paper); border: 2px solid var(--ink);
    box-shadow: 6px 6px 0 var(--ink); padding: 12px 14px; display: flex; flex-direction: column; gap: 8px;
    animation: pop .3s cubic-bezier(.2, 1.6, .4, 1) both; cursor: pointer;
}
.dice-pop .verdict { font-size: 20px; }
.dice-pop .verdict.ok { background: var(--sky); padding: 0 6px; align-self: flex-start; }
.dice-pop .verdict.fail { background: var(--ink); color: var(--paper); padding: 0 6px; align-self: flex-start; }

/* ===== RPG на поле ===== */
.squad {
    position: absolute; pointer-events: auto; border: 0; padding: 0; background: transparent; cursor: crosshair;
    display: flex; align-items: center; justify-content: center;
}
.squad img { width: 86%; height: 86%; object-fit: contain; image-rendering: pixelated; animation: squad-idle 1.6s steps(2) infinite; }
.squad .glyph { font-size: 20px; background: var(--ink); color: var(--paper); width: 76%; height: 76%; display: flex; align-items: center; justify-content: center; }
.squad .cnt { position: absolute; right: 0; bottom: 0; background: var(--paper); border: 1px solid var(--ink); font-size: 11px; padding: 0 3px; line-height: 1.3; }
.squad.near { outline: 2px dashed var(--ink); outline-offset: -2px; }
@keyframes squad-idle { 50% { transform: translateY(-1px); } }
.obj.npc::after { content: "!"; position: absolute; top: -2px; right: 2px; background: var(--sky); border: 1px solid var(--ink); font-size: 10px; padding: 0 3px; line-height: 1.2; }
.obj.shop::after { content: "$"; position: absolute; top: -2px; right: 2px; background: var(--paper); border: 1px solid var(--ink); font-size: 10px; padding: 0 3px; line-height: 1.2; }
.hp-bar { position: relative; height: 12px; border: 1px solid var(--ink); background: var(--paper); }
.hp-bar i { position: absolute; left: 0; top: 0; bottom: 0; background: repeating-conic-gradient(var(--ink) 0 25%, var(--sky) 0 50%) 0 0 / 2px 2px; transition: width .4s ease; }
.stat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; font-size: 13px; }
.stat-grid span { border: 1px solid var(--ink); padding: 1px 4px; display: flex; justify-content: space-between; }
.slots-row { display: flex; gap: 4px; flex-wrap: wrap; font-size: 12px; }
.slots-row span { border: 1px dashed var(--ink); padding: 0 4px; }
.slots-row span.full { border-style: solid; background: var(--sky); }
.check-btn { display: flex; justify-content: space-between; gap: 8px; width: 100%; text-align: left; }
.offer { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; gap: 6px; align-items: center; font-size: 13px; }
.trade-card { border: 2px solid var(--ink); background: #fff; padding: 6px 8px; font-size: 13px; }
.trade-card.incoming { background: var(--sky); }
.trade-form { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.trade-form .cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.trade-form label { display: flex; gap: 6px; align-items: center; }
.tag-eq { font-size: 11px; background: var(--ink); color: var(--paper); padding: 0 3px; margin-left: auto; }

/* ===== бой ===== */
.battle { position: relative; flex: 1; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr); gap: 14px; padding: 16px; min-height: 480px;
    background-image: repeating-conic-gradient(var(--sky-soft) 0 25%, transparent 0 50%); background-size: 6px 6px; }
.battle .side { display: flex; align-items: center; justify-content: center; }
.fighter { width: 100%; background: var(--paper); border: 2px solid var(--ink); box-shadow: 6px 6px 0 var(--ink); padding: 12px; display: flex; flex-direction: column; gap: 6px; }
.portrait { height: 150px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--ink); background: #fff; }
.portrait img { max-height: 140px; max-width: 100%; object-fit: contain; image-rendering: pixelated; }
.big-tok { width: 72px; height: 72px; font-size: 36px; }
.hp-bar.big { height: 16px; }
.stack-grid { height: 150px; display: grid; grid-template-columns: repeat(6, 1fr); gap: 3px; align-content: center; border: 1px solid var(--ink); background: #fff; padding: 6px; }
.stack-grid .unit { aspect-ratio: 1; background: var(--ink); display: flex; align-items: center; justify-content: center; transition: opacity .4s ease, transform .4s ease; }
.stack-grid .unit img { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; background: var(--paper); }
.stack-grid .unit.dead { opacity: .12; transform: scale(.7); }
.hit { animation: hit .45s ease; }
@keyframes hit { 0%, 100% { transform: none; filter: none; } 20% { transform: translateX(-6px); filter: invert(1); } 40% { transform: translateX(5px); } 60% { transform: translateX(-3px); } }
.arena { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.vs { font-size: 40px; background: var(--ink); color: var(--paper); padding: 0 14px; transform: rotate(-4deg); }
.big-dice .die { width: 52px; height: 52px; padding: 6px; }
.roll-line { min-height: 1.4em; background: var(--paper); border: 1px solid var(--ink); padding: 0 8px; }
.battle .log { position: static; display: block; width: 100%; flex: 1; max-height: 260px; min-height: 160px; overflow: auto; font-size: 13px; }
.battle .log .l { margin-bottom: 4px; padding-left: 6px; border-left: 3px solid transparent; }
.battle .log .l.who-hero { border-color: var(--sky); }
.battle .log .l.who-enemy { border-color: var(--paper); }
.battle .log .l.who-sys { color: var(--sky); }
.battle .result { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(252, 247, 253, .7); z-index: 5; }
.battle .result .win { width: min(380px, 90%); }
@media (max-width: 900px) { .battle { grid-template-columns: 1fr; } }
.slot-card .tf { display: flex; flex-direction: column; gap: 2px; border-top: 1px dotted var(--ink); padding-top: 4px; }
.slot-card .tf .range-row { gap: 4px; }
.slot-card .tf output { width: 34px; text-align: right; }
.slot-card.on { outline: 3px solid var(--sky); }
/* однострочные формы (навыки и т.п.) — поля в ряд */
form.row > .field { width: auto; flex: 1 1 160px; }

/* ===== превью в студии = уменьшенная копия сцены беседы =====
   Размер сцены — как у беседы на экране устройства (--scene-w × --scene-h). Спрайт, сдвиги, пол и окно диалога
   берут те же стили, что и в беседе (.scene, .solo, .dbox), поэтому совпадают один в один. */
.preview { position: relative; width: 100%; height: auto; aspect-ratio: var(--scene-w) / var(--scene-h); overflow: hidden; border: 2px solid var(--ink); background: none; }
.preview .pv-stage {
    --k: .4;
    position: absolute; left: 0; top: 0; width: calc(var(--scene-w) * 1px); height: calc(var(--scene-h) * 1px); min-height: 0; flex: none;
    transform: scale(var(--k)); transform-origin: 0 0;
}
.preview .pv-stage .solo .body { transition: transform .15s ease; }
.preview .pv-stage .dbox { cursor: default; }
.preview .pv-ph { display: flex; flex-direction: column; align-items: center; }
/* на узких экранах беседа показывает спрайты мельче — превью в студии остаётся «десктопным» */
@media (max-width: 900px) {
    .preview .pv-stage .solo .body { height: 340px; }
    .preview .pv-stage .solo .frames img { max-height: 360px; max-width: 340px; }
}


/* ===== звук ===== */
.sfx-btn { display: inline-flex; align-items: center; gap: 5px; margin-left: 6px; font: inherit; font-size: 12px; cursor: pointer;
    background: var(--paper); border: 1px solid var(--ink); padding: 1px 7px; box-shadow: 0 2px 0 var(--ink); }
.sfx-btn:active { transform: translateY(2px); box-shadow: none; }
.sfx-btn .led.snd { background: var(--paper); animation: none; }
.sfx-btn.on .led.snd { background: var(--sky); }
@media (max-width: 900px) {
    .leds { display: flex; position: absolute; right: 14px; top: 10px; }
    .leds > :not(.sfx-btn) { display: none; }
}

/* ===== возглас на сцене: способность ===== */
.shout { position: absolute; inset: 0; z-index: 8; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.shout span {
    font-size: clamp(34px, 7vw, 76px); line-height: 1; padding: 14px 30px 18px; color: var(--paper); background: var(--ink);
    border: 4px solid var(--paper); outline: 4px solid var(--ink); box-shadow: 10px 10px 0 var(--sky);
    transform: rotate(-6deg); text-transform: uppercase; letter-spacing: .02em; text-align: center; max-width: 90%;
    clip-path: polygon(0 8%, 6% 0, 18% 7%, 30% 0, 44% 6%, 58% 0, 72% 7%, 86% 0, 100% 6%, 96% 30%, 100% 52%, 95% 74%, 100% 94%,
                       86% 100%, 70% 93%, 54% 100%, 40% 94%, 24% 100%, 10% 93%, 0 100%, 4% 72%, 0 50%, 5% 28%);
}
.shout.on span { animation: shout-in .9s cubic-bezier(.2, 1.4, .4, 1) both; }
.shout.out span { animation: shout-out .25s ease-in both; }
@keyframes shout-in {
    0% { transform: rotate(-6deg) scale(2.4); opacity: 0; }
    35% { transform: rotate(-6deg) scale(.94); opacity: 1; }
    45% { transform: rotate(-4deg) translate(-6px, 3px) scale(1); }
    55% { transform: rotate(-7deg) translate(5px, -3px); }
    65%, 100% { transform: rotate(-6deg); }
}
@keyframes shout-out { to { transform: rotate(-6deg) scale(.8); opacity: 0; } }
.scene.flash::after { content: ""; position: absolute; inset: 0; z-index: 7; background: var(--paper); animation: flash .35s ease-out both; pointer-events: none; }
@keyframes flash { from { opacity: .9; } to { opacity: 0; } }
.evidence.pop { animation: ev-pop .45s cubic-bezier(.2, 1.5, .4, 1) both; }
@keyframes ev-pop { 0% { transform: translateX(40px) scale(.7); opacity: 0; } 100% { transform: none; opacity: 1; } }
.dbox .roll-tag { display: inline-block; margin-left: 6px; font-size: 13px; padding: 0 5px; border: 1px solid currentColor; font-style: normal; }
.dbox .roll-tag.ok { background: var(--sky); color: var(--ink); }

/* ===== беседа: показать предмет, способности ===== */
.ev-pick { display: grid; grid-template-columns: repeat(auto-fill, minmax(54px, 1fr)); gap: 4px; max-height: 136px; overflow: auto; }
.ev-pick button { position: relative; aspect-ratio: 1; padding: 3px; border: 1px solid var(--ink); background: var(--paper); cursor: pointer;
    display: flex; align-items: center; justify-content: center; font: inherit; font-size: 10px; line-height: 1.1; text-align: center; overflow: hidden; }
.ev-pick button img { max-width: 100%; max-height: 100%; object-fit: contain; image-rendering: pixelated; }
.ev-pick button.on { outline: 3px solid var(--sky); outline-offset: -3px; background: #fff; }
.ev-pick button:hover { background: #fff; }
.ev-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; background: var(--sky); border: 1px solid var(--ink); padding: 1px 6px; align-self: flex-start; }
.ev-chip button { border: 0; background: none; font: inherit; cursor: pointer; padding: 0; }
.ab-list { display: flex; flex-direction: column; gap: 4px; }
.ab-btn { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 2px 8px; align-items: center; text-align: left; font: inherit; font-size: 13px;
    border: 1px solid var(--ink); background: var(--paper); padding: 4px 6px; cursor: pointer; }
.ab-btn .inv-pic { grid-row: span 2; }
.ab-btn .tiny { grid-column: 2; }
.ab-btn.on { background: var(--sky); }
.ab-btn:disabled { opacity: .45; cursor: not-allowed; }

/* ===== бой: способности ===== */
.ab-key { position: relative; }
.ab-key .cd { position: absolute; right: -6px; top: -8px; background: var(--ink); color: var(--paper); font-size: 11px; padding: 0 4px; }
.fx-row { display: flex; gap: 4px; flex-wrap: wrap; font-size: 12px; }
.fx-row span { border: 1px solid var(--ink); background: var(--sky); padding: 0 4px; }
.battle .shout { position: absolute; }

/* ===== лавка: продажа ===== */
.offer.sell { background: #fff; border: 1px dashed var(--ink); padding: 2px 4px; }

/* ===== журнал действий ===== */
.log-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.log-table th, .log-table td { border-bottom: 1px dotted var(--ink); padding: 4px 6px; text-align: left; vertical-align: top; }
.log-table th { position: sticky; top: 0; background: var(--paper); border-bottom: 2px solid var(--ink); font-weight: normal; }
.log-table td.when { white-space: nowrap; color: #555; }
.log-table td.who { white-space: nowrap; }
.log-table .k { display: inline-block; font-size: 11px; border: 1px solid var(--ink); padding: 0 4px; white-space: nowrap; }
.log-table .k-ability, .log-table .k-battle, .log-table .k-check { background: var(--sky); }
.log-table .k-moder, .log-table .k-studio { background: var(--ink); color: var(--paper); }
.log-table .k-walk { border-style: dashed; color: #555; }
.log-filters { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.log-filters .chip-link { font-size: 12px; border: 1px solid var(--ink); padding: 1px 6px; text-decoration: none; color: inherit; background: var(--paper); }
.log-filters .chip-link.on { background: var(--ink); color: var(--paper); }
.pager { display: flex; gap: 10px; align-items: center; justify-content: center; font-size: 13px; }
.dbox .text { white-space: pre-line; }
.ev-tabs { display: flex; }
.ev-tabs button { flex: 1; justify-content: center; font-size: 12px; }
.ev-pick .ev-empty { grid-column: 1 / -1; }
.dev-top .leds { margin-left: auto; }

/* ===== экран устройства всегда одного размера =====
   Высота экрана не зависит от страницы: длинное содержимое (журнал, студия, каталог) прокручивается внутри
   своих колонок, а сцена беседы и бой занимают ровно экран. */
:root { --screen-h: 640px; --scene-w: 766; --scene-h: 608; }  /* --screen-h — для телефона; --scene-* уточняет device.js */
.screen { height: var(--screen-h); min-height: 0; }
.screen > .screen-body, .screen > .scene-body, .screen > .battle, .screen > .screen-main { flex: 1 1 auto; min-height: 0; }
.screen-body, .scene-body { overflow: hidden; }
.screen-body > .screen-main, .screen-body > .panel { min-height: 0; overflow: auto; overscroll-behavior: contain; }
.scene-body > .panel { min-height: 0; overflow: auto; overscroll-behavior: contain; }
.scene { min-height: 0; }
.battle { min-height: 0; overflow: auto; }
@media (max-width: 900px) {
    /* на телефоне колонки идут друг под другом — там экран растёт по содержимому */
    .screen { height: auto; min-height: 560px; }
    .screen-body, .scene-body { overflow: visible; }
    .scene { min-height: 420px; }
}

/* ===== фон беседы: не растягивается, видна выбранная часть ===== */
.scene-bg {
    position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0;
    object-fit: cover; object-position: 50% 50%; pointer-events: none; user-select: none;
}
.scene.has-bg { background-image: none; }

/* рамка выбора в студии: вся картинка, поверх — прямоугольник того, что попадёт в кадр */
.framer { position: relative; display: block; width: 100%; border: 1px solid var(--ink); background: #fff; user-select: none; touch-action: none; overflow: hidden; }
.framer > img { display: block; width: 100%; height: auto; pointer-events: none; }
.framer .frame { position: absolute; border: 2px solid var(--ink); outline: 2px dashed var(--paper); outline-offset: -4px; cursor: grab;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, .35); overflow: hidden; }
.framer .frame:active { cursor: grabbing; }
.framer-tools { display: grid; grid-template-columns: auto minmax(0, 1fr) 46px; gap: 4px 8px; align-items: center; font-size: 13px; }
.framer-tools output { text-align: right; }

/* ===== музыка беседы: своя громкость ===== */
.scene .music { position: absolute; right: 12px; top: 10px; z-index: 6; display: flex; align-items: center; gap: 6px;
    background: var(--paper); border: 1px solid var(--ink); padding: 2px 6px; font-size: 13px; }
.scene .music button { border: 0; background: none; font: inherit; cursor: pointer; padding: 0 2px; }
.scene .music button.on { background: var(--sky); }
.scene .music input[type=range] { width: 90px; accent-color: var(--ink); }
.scene .music output { width: 32px; text-align: right; }
.framer-tools input[type=range] { accent-color: var(--ink); border: 0; padding: 0; background: none; width: 100%; }

/* ===== устройство на весь экран браузера =====
   На компьютере корпус занимает ровно окно: без прокрутки страницы, поля и рамки поуже,
   экран растягивается на всё оставшееся место и одинаков на всех страницах.
   Размер сцены беседы (--scene-w × --scene-h) меряет device.js — по нему живут превью и кадр фона. */
@media (min-width: 901px) {
    html, body { height: 100%; }
    body { min-height: 0; overflow: hidden; }
    .stage { box-sizing: border-box; height: 100dvh; min-height: 600px; padding: 10px 18px 16px 12px; display: flex; }
    .device { flex: 1; min-width: 0; max-width: none; height: 100%; box-sizing: border-box; padding: 8px 20px 8px; gap: 8px; border-radius: 28px; }
    .device::after { border-radius: 28px; transform: translate(6px, 6px); }
    .device::before { inset: 5px; border-radius: 23px; }
    .screw.tl { left: 11px; top: 11px; } .screw.tr { right: 11px; top: 11px; }
    .screw.bl { left: 11px; bottom: 11px; } .screw.br { right: 11px; bottom: 11px; }
    .screw { width: 9px; height: 9px; }
    .screw::after { top: 3px; }

    .dev-top { flex: none; min-height: 32px; padding: 0 12px; gap: 6px 12px; flex-wrap: nowrap; }
    .logo { font-size: 20px; }
    .model { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
    .tabs { flex-wrap: nowrap; gap: 5px; }
    .tab { padding: 3px 9px; font-size: 14px; box-shadow: 0 2px 0 var(--ink); }
    .tab.on { transform: translateY(2px); }
    .dev-top .leds { margin-left: 4px; flex: none; }

    .bezel { flex: 1; min-height: 0; display: flex; padding: 8px; border-radius: 14px; }
    .screen { flex: 1; min-width: 0; height: auto; min-height: 0; }

    .dev-bottom { flex: none; min-height: 40px; padding: 0 12px; gap: 8px 18px; flex-wrap: nowrap; }
    .grille { width: 64px; height: 26px; background-size: 8px 8px; }
    .hint { font-size: 12px; }
    .sticker { font-size: 13px; padding: 2px 10px; }

    /* пульт беседы и боя: ниже и плотнее */
    .controls { gap: 16px; flex-wrap: nowrap; }
    .dpad { grid-template-columns: repeat(3, 28px); grid-template-rows: repeat(3, 28px); }
    .dpad button { font-size: 12px; box-shadow: inset 0 -2px 0 var(--sky); }
    .round { width: 44px; height: 44px; font-size: 17px; box-shadow: 0 3px 0 var(--ink); }
    .ab { gap: 12px; align-items: center; }
    .ab > div { flex-direction: row; gap: 6px; font-size: 12px; }
    .ab > div:first-child { margin-bottom: 0; }
}
@media (min-width: 901px) {
    /* нижняя полоса одной высоты на всех страницах — тогда и экран везде одинаковый */
    .dev-bottom { height: 58px; min-height: 0; overflow: visible; }
    .dpad { grid-template-columns: repeat(3, 19px); grid-template-rows: repeat(3, 19px); }
    .dpad button { font-size: 9px; padding: 0; }
    .round { width: 42px; height: 42px; font-size: 16px; }
    .controls .tiny { font-size: 11px; line-height: 1.3; }
}
@media (min-width: 901px) {
    /* поле растёт вместе с экраном, но всегда целиком помещается по высоте */
    .board-wrap { max-width: calc((var(--screen-h) - 150px) * var(--gw) / var(--gh)); }
}

/* ===== без нижней полосы: всё место — экрану =====
   Кнопки беседы (A — далее, B — лог) стоят прямо на сцене, действия боя — под ареной. */
.stage-keys { position: absolute; right: 12px; top: 46px; z-index: 6; display: flex; flex-direction: column; gap: 10px; }
.stage-keys .round { width: 40px; height: 40px; font-size: 15px; box-shadow: 0 3px 0 var(--ink); border-color: var(--ink); }
.battle-actions { grid-column: 1 / -1; display: flex; justify-content: center; padding-top: 4px; border-top: 1px dotted var(--ink); }
.battle-actions .reacts .key { min-height: 44px; min-width: 0; font-size: 16px; }
@media (min-width: 901px) {
    .stage { padding-bottom: 14px; }
    .device { padding-bottom: 14px; }
}
.battle { grid-template-rows: minmax(0, 1fr) auto; }
.battle-actions { align-self: end; }
.battle-actions .reacts { align-items: center; margin: 0; }
.battle-actions .reacts .key { height: 44px; min-height: 0; padding-top: 0; padding-bottom: 0; display: inline-flex; align-items: center; }

/* ===== зум поля локации =====
   Окно поля (.board-view) остаётся прежнего размера, внутри — поле, увеличенное в --zoom раз.
   Всё на поле в процентах, поэтому фишки, объекты и клики масштабируются сами. */
.board-wrap { position: relative; }
.board-view {
    --zoom: 1;
    position: relative; width: 100%; aspect-ratio: var(--gw) / var(--gh);
    overflow: auto; scrollbar-width: thin; overscroll-behavior: contain;
}
.board-view > .board { width: calc(100% * var(--zoom)); max-width: none; }
.board-view.zoomed { outline: 2px solid var(--ink); outline-offset: -2px; }
.board-view.zoomed > .board { border-width: 0; }
.board-view.panning, .board-view.panning .board { cursor: grabbing; }
.zoom-bar { position: absolute; right: 8px; top: 8px; z-index: 9; display: flex; gap: 4px; }
.zoom-bar .key.sm { min-width: 30px; height: 30px; padding: 0 6px; justify-content: center; font-size: 15px; background: var(--paper); }
.zoom-bar .zoom-val { min-width: 54px; font-size: 12px; }
.zoom-bar .key.sm:disabled { opacity: .4; }

/* ===== музыка поверх поля и боя ===== */
.music { display: flex; align-items: center; gap: 6px; background: var(--paper); border: 1px solid var(--ink); padding: 2px 6px; font-size: 13px; }
.music button { border: 0; background: none; font: inherit; cursor: pointer; padding: 0 2px; }
.music button.on { background: var(--sky); }
.music input[type=range] { width: 90px; accent-color: var(--ink); }
.music output { width: 32px; text-align: right; }
.music.floating { position: absolute; left: 8px; top: 8px; z-index: 9; }
.battle { position: relative; }
.battle .music.floating { left: auto; right: 8px; }

/* ===== спрайты ходьбы ===== */
/* спрайт не ограничен клеткой: размер — доля клетки × масштаб героя, ноги стоят в клетке */
.pawn.walker { width: calc(100% / var(--gw) * var(--ls, 1)); aspect-ratio: auto; transform: translate(-50%, -100%); margin-top: calc(100% / var(--gw) * .42); }
.pawn.walker .pawn-face { display: none; }
.pawn-sprite {
    display: block; width: 100%; aspect-ratio: 1 / 1; background-repeat: no-repeat;
    image-rendering: pixelated; filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .35));
}
.pawn.walker.me::after { inset: auto 15% -6% 15%; height: 14%; border-radius: 50%; border: 0; background: var(--sky); opacity: .7; z-index: -1; animation: none; }
.pawn.walker.small { width: calc(100% / var(--gw) * .7 * var(--ls, 1)); }
.pawn.walker .pawn-name { margin-top: 1px; }

@keyframes em-pop { from { transform: translateX(-50%) scale(0); } to { transform: translateX(-50%) scale(1); } }

/* ===== облачко реплики над фишкой ===== */
.say-bubble {
    position: absolute; left: 50%; bottom: 100%; z-index: 4; margin-bottom: 8px; transform: translateX(-50%);
    width: max-content; max-width: 220px; padding: 4px 8px; background: var(--paper); border: 2px solid var(--ink);
    box-shadow: 3px 3px 0 var(--ink); font-size: 13px; line-height: 1.3; white-space: normal; text-align: left;
    pointer-events: none; animation: em-pop .25s cubic-bezier(.2, 1.4, .4, 1) both;
}
.say-bubble::after { content: ""; position: absolute; left: 50%; top: 100%; margin-left: -5px; border: 5px solid transparent; border-top-color: var(--ink); }
.say-bubble.mode-me { font-style: italic; background: #fff; }
.say-bubble.mode-ooc { border-style: dashed; color: #444; }
.say-bubble.mode-roll { display: flex; align-items: center; gap: 6px; background: var(--sky); }
.dice.mini { gap: 3px; }
.dice.mini .die { width: 22px; height: 22px; padding: 2px; gap: 1px; border-width: 1px; box-shadow: 0 2px 0 var(--ink); }
.dice.mini .die i.on { margin: 0; }

/* ===== чат мира — колонка слева от поля ===== */
.wc-log { flex: 1; min-height: 80px; overflow: auto; display: flex; flex-direction: column; gap: 2px; overscroll-behavior: contain; scrollbar-width: thin; }
.wc-msg { line-height: 1.35; overflow-wrap: anywhere; }
.wc-msg .wc-time { color: #666; font-size: 11px; margin-right: 4px; }
.wc-msg .wc-place { font-size: 11px; border: 1px solid var(--ink); padding: 0 3px; margin-right: 4px; }
.wc-msg.mode-me .wc-text { font-style: italic; }
.wc-msg.mode-ooc { color: #555; }
.wc-msg.mode-roll { background: var(--sky); padding: 1px 4px; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
.wc-form { display: flex; flex-direction: column; gap: 5px; }
.wc-modes { display: flex; }
.wc-modes button { flex: 1; font-size: 12px; padding: 2px 0; }
.wc-modes button:disabled { opacity: .4; cursor: not-allowed; }
.wc-row { gap: 5px; flex-wrap: nowrap; }
.wc-row .field { flex: 1; min-width: 0; padding: 4px 6px; font-size: 14px; }
.wc-row .key.sm { padding: 2px 8px; }
.emote-key { min-width: 34px; justify-content: center; }
.emote-key img { height: 20px; width: auto; image-rendering: pixelated; }

/* ===== кубики на сцене беседы ===== */
.stage-dice { position: absolute; left: 50%; top: 30%; z-index: 7; transform: translate(-50%, -50%); display: flex; align-items: center; gap: 12px;
    background: var(--paper); border: 2px solid var(--ink); box-shadow: 6px 6px 0 var(--sky); padding: 10px 16px; animation: em-pop-c .3s cubic-bezier(.2, 1.5, .4, 1) both; }
.stage-dice .die { width: 46px; height: 46px; padding: 6px; }
.stage-dice-sum { font-size: 28px; min-width: 48px; }
.stage-dice.out { opacity: 0; transition: opacity .3s; }
@keyframes em-pop-c { from { transform: translate(-50%, -50%) scale(.4); opacity: 0; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } }

/* ===== студия: превью ходьбы и свои анимации ===== */
.walk-preview { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.walk-dir { display: flex; flex-direction: column; align-items: center; gap: 2px; border: 1px dotted var(--ink); padding: 4px 2px; background: #fff; }
.walk-dir .pawn-sprite { width: 48px; }
.emote-card { display: flex; flex-direction: column; align-items: center; gap: 2px; border: 1px solid var(--ink); padding: 4px 6px; background: #fff; }
.emote-card img { height: 64px; width: auto; image-rendering: pixelated; }

/* ===== карта: чат слева, поле на всё оставшееся место ===== */
.map-layout > .chat-col { width: 300px; flex: 0 0 300px; display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
.chat-col .wc-form { flex: 0 0 auto; }
.wc-dice-row { display: flex; gap: 5px; align-items: center; flex-wrap: wrap; }
.wc-dice-row select.field { flex: 1; min-width: 0; padding: 3px 4px; font-size: 13px; }
.wc-dice-row input.field { width: 64px; padding: 3px 4px; font-size: 13px; }
.verdict { margin-left: 6px; padding: 0 5px; border: 1px solid var(--ink); font-size: 11px; background: var(--paper); }
.verdict.ok { background: var(--ink); color: var(--paper); }
.verdict.no { text-decoration: line-through; }
.say-bubble .verdict { margin-left: 4px; }
.screen-main.map-main { overflow: hidden; }
.map-main > .board-wrap { flex: 1 1 auto; min-height: 0; max-width: none; width: 100%; display: flex; flex-direction: column; }
.map-main .board-view {
    flex: 1 1 auto; min-height: 160px; aspect-ratio: auto; background: #000;
    cursor: grab; scrollbar-color: var(--sky) #000;
}
/* сцена поля: не меньше окна, поле по центру — пустое место вокруг становится чёрными полосами */
.board-stage { min-width: 100%; min-height: 100%; width: max-content; height: max-content; display: grid; place-items: center; overflow: clip; }
.map-main .board-view .board { width: calc(var(--fit-w, 100%) * var(--zoom)); max-width: none; overflow: visible; border-width: 0; }
.map-main .board-view.zoomed { outline: 0; }
.map-main .legend { flex: 0 0 auto; }
.map-main .world { flex: 0 0 auto; }
.pawn-sprite.flip { transform: scaleX(-1); }
@media (max-width: 900px) {
    .map-layout { flex-direction: column; }
    .map-layout > .chat-col { width: auto; flex: 0 0 auto; max-height: 40vh; order: 2; }
    .map-main .board-view { min-height: 55vh; }
}

/* ===== студия: внешность героя на поле ===== */
.look-grid { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 14px; align-items: start; }
/* превью: клетка внизу, масштаб подбирается так, чтобы спрайт любого роста влез целиком (--cell считает studio.js) */
.look-stage { --cell: 80px; --floor: 40px; position: relative; aspect-ratio: 5 / 6; border: 2px solid var(--ink); overflow: hidden; }
.look-cell { position: absolute; left: calc(50% - var(--cell) / 2); bottom: var(--floor); width: var(--cell); height: var(--cell); outline: 2px dashed var(--sky); }
.look-pawn { position: absolute; left: 50%; top: calc(100% - var(--floor) - var(--cell) / 2); width: calc(var(--cell) * .66); aspect-ratio: 1; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; }
.look-pawn .pawn-face { width: 100%; height: 100%; border-radius: 50%; border: 2px solid var(--ink); background: var(--sky); display: flex; align-items: center; justify-content: center; font-size: 18px; }
.look-pawn .pawn-sprite { display: none; }
.look-pawn.walker { width: calc(var(--cell) * var(--ls, 1)); aspect-ratio: auto; transform: translate(-50%, -100%); margin-top: calc(var(--cell) * .42); }
.look-pawn.walker .pawn-sprite { display: block; }
.look-pawn.walker .pawn-face { display: none; }
.look-zoom { position: absolute; right: 4px; top: 4px; font-size: 11px; background: var(--paper); border: 1px solid var(--ink); padding: 0 4px; }
.look-dirs { position: absolute; left: 4px; bottom: 4px; display: flex; gap: 2px; z-index: 2; }
.look-dirs .key.sm { min-width: 26px; height: 26px; padding: 0; justify-content: center; background: var(--paper); }
.look-dirs .key.sm.on { background: var(--sky); }
.look-choice { border: 1px dotted var(--ink); padding: 4px 8px 6px; margin: 0; display: flex; flex-direction: column; gap: 2px; }
.look-choice > div, .look-choice ul { display: contents; }
.walk-uploads { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
.walk-up { display: flex; flex-direction: column; gap: 2px; border: 1px dotted var(--ink); padding: 4px 6px; background: #fff; min-width: 0; }
.walk-up input[type=file] { max-width: 100%; font-size: 11px; }
@media (max-width: 700px) { .look-grid { grid-template-columns: 1fr; } }

/* ===== беседа: A и B в панели справа — их не закрывает показанный предмет ===== */
.ab-pad { display: flex; align-items: center; gap: 6px; padding-bottom: 8px; border-bottom: 1px dotted var(--ink); }
.ab-pad .round { width: 40px; height: 40px; font-size: 15px; box-shadow: 0 3px 0 var(--ink); border-color: var(--ink); }
.ab-pad .tiny { margin-right: 10px; }
.stage-dice { flex-wrap: wrap; justify-content: center; max-width: 80%; }
.stage-dice-verdict { flex-basis: 100%; text-align: center; font-size: 15px; padding: 2px 8px; border: 1px solid var(--ink); }
.stage-dice-verdict.ok { background: var(--ink); color: var(--paper); }

/* карта шире: боковые колонки ужаты, подсказки свёрнуты в одну строку */
@media (min-width: 901px) {
    .map-layout > .chat-col { width: 270px; flex-basis: 270px; padding-left: 12px; padding-right: 12px; }
    .map-layout > .panel:not(.chat-col) { width: 280px; flex: 0 0 280px; }
    .map-main.screen-main { padding: 10px 12px; gap: 8px; }
}
.legend-d { flex: 0 0 auto; }
.legend-d > summary { cursor: pointer; list-style: none; display: inline-block; }
.legend-d > summary::-webkit-details-marker { display: none; }
.legend-d[open] > summary { margin-bottom: 4px; }
.look-choice label { display: flex; flex-direction: row; align-items: center; gap: 6px; cursor: pointer; }
.look-choice input[type=radio] { margin: 0; width: auto; flex: none; accent-color: var(--ink); }
#look-form .range-row input[type=number] { width: 70px; flex: none; }
.look-dirs { right: 4px; flex-wrap: wrap; }
.look-dirs [data-move] { min-width: 0; padding: 0 6px; font-size: 11px; }
.look-dirs [data-move="1"] { margin-right: auto; }
/* запас над полем под высокие спрайты (--head — в клетках, считает board.js) */
.map-main .board-stage { padding-top: calc(var(--fit-w, 0px) * var(--zoom) / var(--gw) * var(--head, 0)); box-sizing: border-box; }

/* ===== палитра анимаций: значки над героем и анимации героя ===== */

/* ===== окно анимаций героя ===== */
.emo-dialog { padding: 0; border: 0; background: transparent; width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow: visible; }
.emo-dialog::backdrop { background: rgba(0, 0, 0, .45); }
.emo-dialog .win { box-shadow: 6px 6px 0 var(--sky); border-width: 2px; }
.emo-dialog .win-body { max-height: calc(100vh - 140px); overflow: auto; }
.emo-x { border: 1px solid var(--ink); background: var(--paper); color: var(--ink); margin-left: auto; position: relative; z-index: 1; font: inherit; font-size: 18px; line-height: 1; cursor: pointer; padding: 0 4px; }
.emo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; }
.emo-card {
    display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 6px 4px 5px;
    border: 2px solid var(--ink); background: var(--paper); font: inherit; color: inherit; cursor: pointer;
    box-shadow: 3px 3px 0 var(--ink); text-align: center;
}
.emo-card:hover { background: #fff; }
.emo-card:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
.emo-card:focus-visible { outline: 2px solid var(--sky); outline-offset: 2px; }
.emo-card.on { background: var(--sky); }
.emo-pic { width: 100%; height: 88px; display: flex; align-items: flex-end; justify-content: center; border: 1px solid var(--ink); overflow: hidden; }
.emo-pic img { max-width: 100%; max-height: 100%; image-rendering: pixelated; }
.emo-name { font-size: 13px; overflow-wrap: anywhere; }

/* ===== студия: размер и сдвиг анимаций героя ===== */
.emo-edit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; }
.emo-edit { display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--ink); padding: 6px; background: #fff; min-width: 0; }
.emo-stage { position: relative; height: 190px; border: 1px solid var(--ink); overflow: hidden; }
.emo-cell { position: absolute; outline: 2px dashed var(--sky); }
.emo-ghost { position: absolute; background-repeat: no-repeat; background-position: 0 100%; opacity: .3; image-rendering: pixelated; filter: grayscale(1); }
.emo-img { position: absolute; image-rendering: pixelated; }
.emo-edit .field { padding: 3px 6px; font-size: 13px; }
.emo-edit input[type=number] { width: 64px; flex: none; }
.emo-edit .range-row input[type=range] { min-width: 0; flex: 1; }
.emo-edit input[type=file] { max-width: 100%; font-size: 11px; }
/* анимация на поле: свой размер и сдвиг (в клетках) */
.pawn.walker.posing { margin-left: calc(100% / var(--gw) * var(--pox, 0)); margin-top: calc(100% / var(--gw) * (.42 + var(--poy, 0))); }
