/* 像素小镇页面样式 (PSO 蓝色调像素风) */

* { box-sizing: border-box; }

/* 真机专属: iOS 横屏会自动放大文字(挤坏 HUD) → 锁定 100%; 全屏游戏禁下拉刷新/橡皮筋回弹 */
html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    overscroll-behavior: none;
    overscroll-behavior-y: none;
}
body.touch { overscroll-behavior: none; }

.town-body {
    margin: 0;
    min-height: 100vh;
    min-height: 100dvh;   /* 移动端动态视口: 地址栏展开/收起时不跳 */
    background: #060b1a;
    background-image:
        radial-gradient(1200px 500px at 50% -10%, #14264d 0%, rgba(20, 38, 77, 0) 70%),
        repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.015) 0 1px, transparent 1px 4px);
    color: #cfe0ff;
    font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
    display: flex;
    flex-direction: column;
}

/* ---------- 顶栏 ---------- */
.town-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 18px;
    background: linear-gradient(180deg, rgba(16, 30, 62, 0.95), rgba(10, 20, 44, 0.9));
    border-bottom: 1px solid #27407a;
}
.town-header-left { display: flex; align-items: baseline; gap: 14px; }
.town-back {
    color: #6fa8e8; text-decoration: none; font-size: 13px;
    padding: 3px 8px; border: 1px solid #27407a; border-radius: 4px;
}
.town-back:hover { background: #1a2f5c; }
.town-logo {
    font-size: 18px; font-weight: bold; color: #eaf3ff;
    text-shadow: 0 0 12px rgba(90, 168, 255, 0.55);
    letter-spacing: 2px;
}
.town-sub { font-size: 10px; color: #4a6a9f; letter-spacing: 4px; }
.town-user { font-size: 12px; color: #8aa8d8; }

/* ---------- 未登录门 ---------- */
.town-gate { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 16px; }
.town-gate-box {
    max-width: 520px; text-align: center; padding: 44px 36px;
    background: rgba(14, 26, 54, 0.85);
    border: 1px solid #2c4a86; border-radius: 10px;
    box-shadow: 0 0 40px rgba(40, 90, 190, 0.25) inset;
}
.town-gate-title { font-size: 24px; color: #eaf3ff; font-weight: bold; letter-spacing: 4px; margin-bottom: 18px; }
.town-gate-desc { font-size: 14px; line-height: 2; color: #9db6e4; margin-bottom: 26px; }

/* ---------- 按钮 ---------- */
.town-btn-primary {
    display: inline-block; cursor: pointer; text-decoration: none;
    background: linear-gradient(180deg, #3f7fd6, #2a5cad);
    color: #fff; font-size: 15px; letter-spacing: 2px;
    padding: 10px 34px; border: 1px solid #6aa8ff; border-radius: 6px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
.town-btn-primary:hover { filter: brightness(1.15); }
.town-btn-primary:disabled { filter: grayscale(0.7) brightness(0.6); cursor: not-allowed; }
.town-btn-ghost {
    cursor: pointer; background: transparent; color: #9db6e4;
    border: 1px solid #2c4a86; border-radius: 6px; padding: 8px 16px; font-size: 13px;
}
.town-btn-ghost:hover { background: #16294f; }

/* ---------- 选角 ---------- */
.town-select-wrap { flex: 1; display: flex; align-items: flex-start; justify-content: center; padding: 26px 16px; }
.town-select-panel {
    width: 100%; max-width: 980px;
    background: rgba(13, 24, 50, 0.9);
    border: 1px solid #2c4a86; border-radius: 10px;
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5);
}
.town-select-head {
    padding: 16px 22px 10px;
    border-bottom: 1px solid #1d3260;
}
.town-select-title { font-size: 18px; color: #eaf3ff; letter-spacing: 2px; }
.town-select-tip { font-size: 12px; color: #7e9ccb; margin-top: 6px; min-height: 16px; }
.town-select-body { display: flex; gap: 18px; padding: 18px 22px; }
.town-select-grid {
    flex: 1; display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 12px; align-content: start;
}
.town-select-card {
    background: rgba(22, 38, 76, 0.7);
    border: 1px solid #2c4a86; border-radius: 8px;
    padding: 12px 8px; text-align: center; cursor: pointer;
    transition: transform 0.08s, border-color 0.08s;
}
.town-select-card:hover { transform: translateY(-2px); border-color: #4a7ad2; }
.town-select-card.active {
    border-color: #6ab8ff;
    box-shadow: 0 0 0 1px #6ab8ff, 0 0 18px rgba(106, 184, 255, 0.35);
    background: rgba(30, 52, 102, 0.9);
}
.town-select-sprite { image-rendering: pixelated; max-width: 100%; }
.town-select-name { font-size: 14px; font-weight: bold; margin-top: 6px; text-shadow: 0 1px 2px #000; }
.town-select-meta { font-size: 11px; color: #8aa8d8; margin-top: 4px; }
.town-select-lv { color: #ffd24d; font-weight: bold; }
.town-select-ap { font-size: 10px; color: #6f8cba; margin-top: 3px; }
.town-select-right { width: 250px; display: flex; flex-direction: column; gap: 10px; }
.town-select-preview-title { font-size: 13px; color: #9db6e4; }
.town-select-preview {
    min-height: 180px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 12px;
    background: rgba(10, 20, 44, 0.8);
    border: 1px dashed #2c4a86; border-radius: 8px;
}
.town-select-preview canvas { image-rendering: pixelated; }
/* 角色简要数据 (等级/经验/Section/颜色ID, 标签与英雄榜一致) */
.town-preview-info { width: 100%; display: flex; flex-direction: column; gap: 3px; margin-top: 4px; }
.town-pv-row {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    font-size: 11px; color: #8aa8d8; line-height: 1.7;
}
.town-pv-row span { color: #6f8cba; flex: 0 0 auto; }
.town-pv-row b { color: #dce8ff; font-weight: bold; text-align: right; }
.town-pv-row.col { display: block; }
.town-pv-row.col b { display: block; text-align: left; }
.town-pv-sw {
    display: inline-block; width: 11px; height: 11px; margin-right: 3px; vertical-align: -1px;
    border: 1px solid #000;
}
.town-select-hint { font-size: 12px; color: #6f8cba; line-height: 1.9; }
.town-select-foot { padding: 6px 22px 20px; text-align: center; }

/* ---------- 小镇布局 ---------- */
.town-game-wrap {
    flex: 1; display: flex; gap: 14px; padding: 14px 16px;
    align-items: flex-start; justify-content: center;
    flex-wrap: wrap;
}
.town-stage {
    flex: 3 1 640px; min-width: 320px; max-width: 1600px;
    display: flex; flex-direction: column; gap: 0;
    background: rgba(13, 24, 50, 0.9);
    border: 1px solid #2c4a86; border-radius: 10px; overflow: hidden;
}
.town-stage-bar {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    padding: 8px 14px; background: rgba(16, 30, 62, 0.9);
    border-bottom: 1px solid #1d3260; font-size: 12px;
}
.town-stage-name { color: #eaf3ff; font-weight: bold; letter-spacing: 2px; }
.town-stage-info { color: #8aa8d8; }
.town-stage-info b { color: #59f2ff; }
.town-self-name { color: #ffd24d; }
.town-stage-keys { margin-left: auto; color: #55719f; font-size: 11px; }
.town-canvas-box {
    flex: 1; display: flex; align-items: center; justify-content: center;
    width: 100%;
    max-height: calc(100dvh - 150px); min-height: 0;
    background: #02060f; padding: 0;
    position: relative; overflow: hidden;
}
/* 画面容器: 固定 16:9 画布 (1024x576)。窗口模式 JS 取最大 16:9 矩形(随窗口放大), 全屏铺满 */
.town-view { position: relative; overflow: hidden; }
/* 战斗界面层: 设计空间固定 1024x576 (与画布位图同坐标系), JS 按画面缩放比 scale 拉伸对齐;
   容器自身不拦事件 (战斗根 #tb-root 自带 pointer-events:auto), 否则点不到画布 */
#town-fx { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; }
/* 游戏 UI 覆盖层容器: JS 设 width/height = 画面尺寸/ts 并 transform: scale(ts),
   于是菜单/聊天/提示框等全部随画面等比缩放 (基准: 画面宽 1024)。
   同样不拦事件, 只有真正的控件容器才收事件 —— 否则画布上的"点地移动"会失效 */
#town-ui { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; }
#town-ui .town-hud-menu, #town-ui .town-dpad, #town-ui .town-dialog, #town-ui .town-bag { pointer-events: auto; }
/* 只声明 pixelated: Chrome 里后面的 crisp-edges 会覆盖它并退化成锐化滤镜(画面发糊) */
#town-canvas {
    width: 100%; height: 100%; display: block;
    image-rendering: pixelated;
    cursor: pointer; touch-action: manipulation;
}
body.touch #town-canvas { touch-action: none; }   /* 触屏: 摇杆+点地, 画布不参与手势 */

/* ---------- 虚拟方向键 (触屏) ---------- */
.town-dpad {
    display: none; position: absolute; left: 16px; bottom: 16px;
    width: 156px; height: 156px; z-index: 6;
    grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
    gap: 5px; opacity: 0.85;
}
body.touch .town-dpad { display: grid; }
.town-dpad button {
    border: 1px solid #3d6099; border-radius: 12px;
    background: rgba(14, 26, 56, 0.72); color: #cfe0ff;
    font-size: 22px; line-height: 1; padding: 0;
    touch-action: none; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
}
.town-dpad button.on { background: rgba(46, 111, 208, 0.85); color: #fff; }
.town-dpad .dp-u { grid-area: 1 / 2; }
.town-dpad .dp-l { grid-area: 2 / 1; }
.town-dpad .dp-r { grid-area: 2 / 3; }
.town-dpad .dp-d { grid-area: 3 / 2; }

/* ---------- 侧栏 ---------- */
.town-side {
    flex: 1 1 320px; min-width: 280px; max-width: 380px;
    display: flex; flex-direction: column; gap: 12px;
}
.town-side-box {
    background: rgba(13, 24, 50, 0.9);
    border: 1px solid #2c4a86; border-radius: 10px;
    display: flex; flex-direction: column; overflow: hidden;
}
.town-side-title {
    padding: 8px 14px; font-size: 13px; color: #9db6e4; letter-spacing: 2px;
    background: rgba(16, 30, 62, 0.9); border-bottom: 1px solid #1d3260;
}
.town-online-box { flex: 0 0 auto; max-height: 240px; }
.town-online-list { overflow-y: auto; padding: 8px 10px; }
.town-online-item {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 6px; font-size: 13px; border-radius: 4px;
}
.town-online-item.me { background: rgba(60, 110, 210, 0.18); }
.town-online-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.town-online-class { margin-left: auto; font-size: 11px; color: #6f8cba; }

.town-chat-box { flex: 1 1 260px; min-height: 300px; }
.town-chat-toggle { display: none; }   /* 只在手机竖屏显示 (默认折叠态) */
.town-chat-log {
    flex: 1; overflow-y: auto; padding: 10px 12px;
    font-size: 13px; line-height: 1.7; min-height: 180px;
}
.town-msg { word-break: break-all; }
.town-msg-time { color: #55719f; font-size: 11px; }
.town-msg-name { font-weight: bold; }
.town-msg-sys { color: #7e9ccb; font-style: italic; }
.town-msg-tip { color: #ffd24d; font-style: normal; font-weight: bold; }   /* 系统播报的「提示:」前缀 */
.town-chat-tip { min-height: 18px; font-size: 11px; color: #ff9a8a; padding: 0 12px; }
.town-chat-input-row {
    display: flex; gap: 8px; padding: 10px 12px 12px;
    border-top: 1px solid #1d3260;
}
.town-chat-input {
    flex: 1; background: #0a1530; color: #cfe0ff;
    border: 1px solid #2c4a86; border-radius: 6px;
    padding: 8px 10px; font-size: 13px; outline: none;
}
.town-chat-input:focus { border-color: #4a7ad2; }
.town-chat-send {
    cursor: pointer; background: #2a5cad; color: #fff;
    border: 1px solid #6aa8ff; border-radius: 6px; padding: 8px 16px; font-size: 13px;
}
.town-chat-send:hover { filter: brightness(1.15); }
.town-side-actions { padding: 2px 0 12px; text-align: center; }

/* ---------- 失效弹层 ---------- */
.town-fatal {
    position: fixed; inset: 0; z-index: 50;
    background: rgba(4, 8, 18, 0.85);
    display: flex; align-items: center; justify-content: center;
}
.town-fatal-box { text-align: center; }
.town-fatal-text { color: #ffb9a0; font-size: 16px; margin-bottom: 22px; letter-spacing: 1px; }

/* ---------- 移动端 ---------- */
@media (max-width: 1100px) {
    .town-select-body { flex-direction: column; }
    .town-select-right { width: 100%; }
    .town-stage-keys { display: none; }
    /* 小屏: 上画布下侧栏, 画布收窄, 输入加大防 iOS 聚焦缩放 */
    .town-game-wrap { padding: 8px; gap: 8px; }
    /* min-width 必须清掉: 基类 .town-stage 是 min-width:320px, 320px 宽的机减去 wrap 内边距只剩 316px
       → 撑出 4px 横向溢出 (真机 320x568 实测复现) */
    .town-stage { max-width: 100%; min-width: 0; }
    .town-canvas-box { min-height: 240px; padding: 4px; }
    .town-side { flex: 1 1 100%; max-width: 100%; min-width: 0; flex-direction: row; flex-wrap: wrap; }
    .town-online-box { flex: 1 1 100%; }
    .town-online-list { max-height: 96px; }
    .town-chat-box { flex: 1 1 100%; min-height: 190px; }
    .town-chat-log { max-height: 150px; }
    .town-chat-input, .town-chat-send { font-size: 16px; }
    .town-chat-send { padding: 7px 18px; }
    .town-dpad { width: 126px; height: 126px; left: 8px; bottom: 8px; }
}

/* ---------- 竖屏专项 (手机竖着拿): 画面贴顶满宽, 侧栏在下 ---------- */
@media (max-width: 1100px) and (orientation: portrait) {
    body.town-body { padding: 4px 0; }
    /* justify-content 必须一起改: 基类是桌面横向排版的 justify-content:center, 竖屏只改 direction 的话
       内容会垂直居中 → 高屏(430x932)上画面浮在屏幕正中, 头顶/脚下各留 152px 空白(真机实测) */
    .town-game-wrap { padding: 4px; gap: 4px; flex-direction: column; justify-content: flex-start;
        flex-wrap: nowrap; }   /* wrap 会让子项各占一条线, 剩余高度不分配 → 侧栏长不起来 */
    /* 剩余高度交给侧栏(居民在线/聊天)吃掉, 免得底部留一大片空背景 */
    .town-side { flex: 1 1 auto; min-height: 0; }
    .town-online-box, .town-chat-box { flex: 1 1 100%; min-height: 0; }
    .town-stage { flex: none; width: 100%; max-width: 100%; border-radius: 6px; }
    .town-stage-bar { padding: 4px 8px; font-size: 10px; gap: 8px; }
    .town-canvas-box { min-height: 0; padding: 0; max-height: none; aspect-ratio: 16 / 9; }
    /* 原先这里写 .town-side{flex:none} 把侧栏钉在内容高度 → 高屏(430x932)底部空 300px。
       去掉, 让上面那条 flex:1 1 auto 生效, 剩余高度由侧栏吃掉 */
    .town-chat-box { min-height: 130px; }
    .town-chat-log { max-height: 84px; }
    /* 摇杆: 竖屏更低更小 (拇指弧) */
    /* 摇杆: 138px + 3px 缝 → 每格 (138-6)/3 = 44px, 正好落 Apple 最小触控目标。
       原来 92px/5px 缝只有 27px, 真机实测拇指按不准(邻键误触)。
       bottom 用 max() 避开 iPhone 底部 Home 横条 (安全区); 桌面 env=0 不影响 */
    .town-dpad { width: 138px; height: 138px; gap: 3px; left: max(6px, env(safe-area-inset-left));
        bottom: max(6px, env(safe-area-inset-bottom)); }
    /* 聊天: 竖屏折叠成 💬 按钮 (不占画面); 点开才展开完整聊天 */
    .town-chat { width: 60%; max-width: 200px; right: max(8px, env(safe-area-inset-right));
        left: auto; bottom: max(8px, env(safe-area-inset-bottom)); }
    /* 44px = Apple 触控最小目标 (34px 手指点不准) */
    .town-chat-toggle { display: block; margin-left: auto; width: 44px; height: 44px; font-size: 20px;
        background: rgba(18, 18, 102, 0.9); border: 2px solid #d8dcf4; color: #fff; cursor: pointer;
        pointer-events: auto; -webkit-tap-highlight-color: transparent; }
    .town-chat:not(.open) .town-chat-log,
    .town-chat:not(.open) .town-chat-tip,
    .town-chat:not(.open) .town-chat-input-row { display: none; }
    .town-chat.open { bottom: 8px; }
    /* 菜单回画面左上 (body 前缀提特异性 —— 基础规则 left/bottom 在文件更后, 会被它盖掉跑到左下角与摇杆重叠) */
    body .town-hud-menu { left: max(4px, env(safe-area-inset-left)); right: auto;
        top: max(4px, env(safe-area-inset-top)); bottom: auto; }
    /* 竖屏画面只有 ~214px 高: 弹层铺成一行 7 格 (高 ~56px), 别 4x2 盖住半个画面。
       ★ 这里一律用 **#id 提特异性**, 不要只用 body 前缀 —— 文件更后面还有一条
         `body.touch .town-menu-pop button { min-width: 62px }` (特异性 0,2,2), 它会把
         `body .town-menu-pop button` (0,1,2) 的 `min-width: 0` 压掉, 于是 7 列每列都撑到 62px、
         整排 468px 撑破 360px 的弹层框向右溢出 (用户反馈"菜单列表突破了菜单框")。 */
    /* ★ 宽度必须用 vw 不能用 %: 弹层的包含块是菜单按钮 (~72px 宽), 100% 会把它压成 72px
       而 7 列内容要 430px+ → 内容溢出屏幕 (用户反馈"菜单超出屏幕") */
    /* ★ 宽度跟着【画面】走, 不能跟视口 (vw): 低分辨率/全屏横带时画面比视口窄,
       用 vw 会让弹层比画面还宽 (320 宽的手机实测占画面 97%)。
       --ui-w 由 town.js 的 viewportResize 写 (#town-ui 的设计空间宽, 已扣掉缩放)。 */
    body #town-menu-pop { grid-template-columns: repeat(7, 1fr); left: 0; right: auto;
        width: min(calc(var(--ui-w, 360px) - 12px), 360px); padding: 5px; gap: 4px; }
    body #town-menu-pop button { min-width: 0; padding: 6px 1px 4px; font-size: 17px; }
    body #town-menu-pop button span { font-size: 9px; }
}

/* 极窄屏 (<=350px, 画布按 16:9 只有 ~190px 高): 138px 摇杆会往上顶到左上角菜单。
   收到 120px (每格 38px, 仍优于原来的 27px); 360px 以上不受影响 */
@media (max-width: 1100px) and (orientation: portrait) and (max-width: 350px) {
    .town-dpad { width: 120px; height: 120px; }
}

/* ---------- 横屏专项 (手机横着拿): 画面为主, 侧栏藏为抽屉 ---------- */
@media (max-width: 1100px) and (orientation: landscape) {
    body.town-body { padding: 0; }
    .town-game-wrap { padding: 2px; gap: 2px; }
    .town-stage { flex: 1 1 100%; max-width: 100%; border-radius: 4px; }
    .town-stage-bar { padding: 3px 8px; font-size: 10px; }
    .town-canvas-box { min-height: 0; max-height: none; padding: 0; }
    /* 横屏: 侧栏整体隐藏 (聊天/在线在画面内的 UI 已够用), 腾出全部空间给画面。
       限 body.touch: 1024x768 这类【桌面窄窗口】也命中 max-width:1100 + landscape,
       不加限定会把桌面用户的侧栏一起藏掉(断点 900→1100 时带进来的) */
    body.touch .town-side { display: none; }
    /* 摇杆: 横屏左下角 (左手拇指) */
    .town-dpad { width: 138px; height: 138px; gap: 3px; left: max(10px, env(safe-area-inset-left));
        bottom: max(10px, env(safe-area-inset-bottom)); }
    /* 菜单: 摇杆右侧贴下边 (拇指够得着, 不挡画面中央) → 弹层改为向上展开 */
    body .town-hud-menu { left: calc(max(10px, env(safe-area-inset-left)) + 148px); right: auto;
        top: auto; bottom: max(12px, env(safe-area-inset-bottom)); }
    body .town-menu-pop { top: auto; bottom: calc(100% + 6px); }
    /* 聊天: 横屏贴右上 (不挡摇杆) */
    .town-chat { width: 38%; max-width: 180px; right: max(6px, env(safe-area-inset-right));
        left: auto; bottom: max(6px, env(safe-area-inset-bottom)); }
    /* 横屏画面高度只有 ~330px, 展开态聊天(120px)占掉 1/3 画面 → 同样保留折叠按钮, 默认收起 */
    .town-chat-toggle { display: block; margin-left: auto; width: 44px; height: 44px; font-size: 20px;
        background: rgba(18, 18, 102, 0.9); border: 2px solid #d8dcf4; color: #fff; cursor: pointer;
        pointer-events: auto; -webkit-tap-highlight-color: transparent; }
    /* 折叠规则只在竖屏块里写过, 横屏缺了 → 不写 open 类也照样显示全部内容 */
    .town-chat:not(.open) .town-chat-log,
    .town-chat:not(.open) .town-chat-tip,
    .town-chat:not(.open) .town-chat-input-row { display: none; }
    .town-chat-log { max-height: 60px; }
    /* 交互提示条位置由基类的 body.touch 规则统一管 (文件更后, 此处不要再覆盖) */
    /* 横屏高度紧张: 隐藏页面标题栏与页脚, 把高度全留给游戏画面 (画面从 55% → 满高比例)。
       同样限 body.touch, 桌面窄窗口不该丢页头/页脚 */
    body.touch .town-header, body.touch .town-credit { display: none; }
    .town-stage-bar { padding: 2px 6px; font-size: 10px; }
    /* body.touch 前缀提特异性: 下面 398 行那条 body.touch .town-stage-keys{display:block}
       会盖掉这里的 .town-stage-bar .town-stage-keys —— 横屏屏高只有 430px, 顶栏 90px 太亏 */
    body.touch .town-stage-bar .town-stage-keys { display: none; }
    /* 横屏高度金贵: 弹层格子略收 (4 列 × 52 = 208px 也够点) */
    .town-menu-pop button { min-width: 48px; padding: 8px 2px 6px; font-size: 19px; }
    .town-menu-pop button span { font-size: 9px; }
}

/* ---------- 素材授权署名 ---------- */
.town-credit {
    text-align: center; color: #5a6f96; font-size: 11px; padding: 10px 8px 14px;
}
.town-credit a { color: #7fa4e0; text-decoration: none; }
.town-credit a:hover { text-decoration: underline; }

/* ---------- 角色头像 (PSIV) ---------- */
.town-online-avatar {
    width: 24px; height: 24px; flex: 0 0 auto;
    image-rendering: pixelated; border-radius: 3px;
    background: rgba(8, 14, 30, 0.6);
}
.town-preview-face { image-rendering: pixelated; border-radius: 6px; }
.town-preview-body { image-rendering: pixelated; }

/* 触屏: 提示条改短文案并保持显示 */
body.touch .town-stage-keys { display:block; margin-left:0; width:100%; font-size:10px; color:#6f8cba; }

/* ---------- 全屏模式 ---------- */
.town-fs-btn {
    margin-left: 10px; padding: 3px 12px; font-size: 12px; cursor: pointer;
    background: rgba(29, 49, 87, 0.9); color: #cfe0ff;
    border: 1px solid #3d6099; border-radius: 6px;
    -webkit-tap-highlight-color: transparent;
}
.town-fs-btn:hover { filter: brightness(1.2); }
/* GM 专属: 地图编辑器入口 (顶栏 + 场景条) */
.town-gm-link { text-decoration: none; display: inline-block; }
a.town-gm-link {
    margin-left: 10px; padding: 3px 12px; font-size: 12px;
    background: linear-gradient(180deg, #1f6b3a 0%, #14472a 100%);
    color: #d8ffe4; border: 1px solid #46c46f; border-radius: 6px;
}
a.town-gm-link:hover { filter: brightness(1.18); }
/* 原生全屏: 铺满整屏 (解除窗口模式的 1600 宽度上限) */
.town-stage:fullscreen { max-width: none; border-radius: 0; }
.town-stage:fullscreen .town-canvas-box { min-height: 0; flex: 1; }
/* CSS 伪全屏回退 (iOS Safari): 固定覆盖 */
.town-stage.fs-fake {
    position: fixed; inset: 0; z-index: 999; max-width: none;
    border-radius: 0; background: #060c1c;
}
.town-stage.fs-fake .town-canvas-box { min-height: 0; flex: 1; }
@media (max-width: 1100px) {
}

/* ---------- 背包 (游戏画面内 · PSIV/RPG 菜单窗) ---------- */
/* 容器在 .town-canvas-box 内, 只盖画布区域, 游戏在底下继续渲染 */
.town-bag { position: absolute; inset: 0; z-index: 8; display: flex; align-items: stretch; padding: 10px 0 10px 12px; }
.town-bag-mask { position: absolute; inset: 0; background: rgba(3, 5, 18, 0.42); }
.town-bag-panel {
    position: relative; width: min(56%, 380px); display: flex; flex-direction: column;
    background: linear-gradient(180deg, #1b1b86 0%, #121266 30%, #0d0d4e 100%);
    border: none; border-radius: 0;
    box-shadow:
        0 0 0 2px #05052a,
        0 0 0 4px #d8dcf4,
        0 0 0 6px #05052a,
        0 10px 30px rgba(0, 0, 0, 0.55);
}
.town-bag-head {
    display: flex; align-items: center; gap: 8px; padding: 8px 12px;
    background: linear-gradient(180deg, #2a2ab0, #16167a);
    border-bottom: 2px solid #d8dcf4; box-shadow: 0 2px 0 #05052a;
}
.town-bag-title { font-weight: bold; color: #ffd24d; letter-spacing: 3px; text-shadow: 1px 1px 0 #05052a; }
.town-bag-count { color: #9fb0f0; font-size: 11px; }
.town-bag-close { margin-left: auto; background: #121266; color: #ffd24d; border: 2px solid #d8dcf4; padding: 1px 9px; cursor: pointer; font-size: 13px; font-weight: bold; }
.town-bag-close:hover { background: #2a2ab0; color: #fff; }
.town-bag-filter { display: flex; gap: 4px; padding: 8px 8px 4px; flex-wrap: wrap; }
.town-bag-tab {
    background: #0d0d4e; color: #c8d2ff; border: 2px solid #6a6ad8;
    padding: 2px 9px; font-size: 11px; cursor: pointer;
    text-shadow: 1px 1px 0 #05052a;
}
.town-bag-tab.on { background: #3a3ad0; color: #fff; border-color: #d8dcf4; }
.town-bag-tab.on::before { content: "▶ "; color: #ff5a5a; font-size: 8px; }
/* 星级筛选 (第二行): 比类型行更紧凑, 用金色区分 */
.town-bag-filter2 { padding-top: 2px; }
.town-bag-star { padding: 1px 7px; font-size: 10px; }
.town-bag-star.on { background: #8a6a10; border-color: #ffd24d; color: #fff8dc; }
/* 物品竖列 (RPG 清单式) */
.town-bag-list { flex: 1; overflow-y: auto; padding: 4px 6px; }
.town-bag-row {
    display: flex; align-items: center; gap: 7px; padding: 5px 7px;
    border-bottom: 1px solid #26267a; cursor: pointer; min-height: 30px;
}
.town-bag-row:hover { background: rgba(58, 58, 176, 0.45); }
.town-bag-row.sel { background: #2a2ab0; box-shadow: inset 0 0 0 1px #6a6ad8; }
.town-bag-row .cur { flex: 0 0 10px; color: #ff5a5a; font-size: 10px; visibility: hidden; }
.town-bag-row.sel .cur { visibility: visible; }
.town-bag-row .ico { font-size: 17px; flex: 0 0 auto; filter: drop-shadow(1px 1px 0 #05052a); }
.town-bag-row .nm { flex: 1; font-size: 12px; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-shadow: 1px 1px 0 #05052a; }
.town-bag-row.s9 .nm { color: #ff8a8a; }
.town-bag-row.s10 .nm { color: #ffd24d; }
.town-bag-row .eqt { flex: 0 0 auto; font-size: 10px; color: #05252e; background: #6ef2ff; border: 1px solid #d8dcf4; padding: 0 4px; font-weight: bold; }
.town-bag-row .cnt { flex: 0 0 auto; font-size: 11px; color: #ffd24d; text-shadow: 1px 1px 0 #05052a; }
.town-bag-row .stars { color: #ffd24d; font-size: 10px; flex: 0 0 auto; }
.town-bag-empty { text-align: center; color: #6a7ac0; padding: 32px 0; font-size: 12px; }
/* 底部描述行 (RPG 菜单说明栏) */
.town-bag-desc {
    min-height: 36px; padding: 6px 10px; border-top: 2px solid #3a3a9e;
    color: #c8d2ff; font-size: 11px; line-height: 1.5;
    background: rgba(5, 5, 42, 0.6);
}
.town-bag-foot { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 7px; border-top: 2px solid #3a3a9e; }
.town-bag-sub { color: #8a96c8; font-size: 10px; margin-left: 8px; }
.town-bag-nav { background: #121266; color: #c8d2ff; border: 2px solid #6a6ad8; padding: 2px 12px; cursor: pointer; font-size: 11px; }
.town-bag-nav:hover:not(:disabled) { background: #2a2ab0; color: #fff; }
.town-bag-nav:disabled { opacity: 0.3; cursor: default; }
.town-bag-page { color: #9fb0f0; font-size: 11px; min-width: 56px; text-align: center; }@media (max-width: 1100px) {
    .town-bag { padding: 6px; }
    .town-bag-panel { width: min(92%, 340px); }
}

/* ---------- 游戏内聊天 (常态近透明, 输入时变实) ---------- */
.town-chat {
    position: absolute; right: 8px; bottom: 6px; z-index: 5;
    width: min(44%, 360px); display: flex; flex-direction: column; pointer-events: none;
}
.town-chat-log {
    max-height: min(30vh, 240px); overflow-y: auto; padding: 4px 8px;
    font-size: 11px; line-height: 1.55; color: #dfe9ff;
    text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.9);
    background: rgba(5, 10, 26, 0.18);
    border-radius: 4px; pointer-events: auto;
    scrollbar-width: thin;
}
.town-chat.active .town-chat-log { background: rgba(5, 10, 26, 0.72); }
.town-chat-tip { min-height: 14px; font-size: 10px; color: #ff9a8a; padding: 0 6px; }
.town-chat-input-row { display: flex; gap: 6px; pointer-events: auto; opacity: 0; transition: opacity 0.18s; }
.town-chat.active .town-chat-input-row,
.town-chat-input-row:focus-within { opacity: 1; }
.town-chat-input {
    flex: 1; background: rgba(5, 10, 26, 0.78); color: #eaf3ff;
    border: 2px solid #6a6ad8; border-radius: 4px; padding: 5px 10px; font-size: 13px;
}
.town-chat-input:focus { border-color: #d8dcf4; outline: none; }
.town-chat-send {
    background: #121266; color: #ffd24d; border: 2px solid #6a6ad8; border-radius: 4px;
    padding: 5px 16px; cursor: pointer; font-size: 12px;
}
.town-chat-send:hover { background: #2a2ab0; color: #fff; }
@media (max-width: 1100px) { .town-chat-input, .town-chat-send { font-size: 16px; } }

/* ---------- 左下角主菜单 (RPG HUD) ---------- */
.town-hud-menu {
    position: absolute; left: 8px; bottom: 8px; z-index: 6;
    display: flex; gap: 5px;
}
.town-hud-menu button {
    background: rgba(18, 18, 102, 0.88); color: #d8dcf4;
    border: 2px solid #d8dcf4; outline: 1px solid #05052a;
    padding: 4px 10px; font-size: 12px; cursor: pointer;
    text-shadow: 1px 1px 0 #05052a; border-radius: 0;
    -webkit-tap-highlight-color: transparent;
}
.town-hud-menu button:hover { background: #3a3ad0; color: #fff; }
.town-hud-menu button.on { background: #3a3ad0; color: #fff; }
.town-hud-menu #hud-set { font-size: 15px; padding: 3px 8px; }
/* 触屏: 主要入口按钮拉到 44px (Apple HIG 最小触控目标); 只作用于 ☰/⚙ 两个直接子按钮, 不动弹层格子 */
body.touch .town-hud-menu > button { min-width: 44px; min-height: 44px; font-size: 18px; padding: 0 10px; }
/* ☰ 菜单弹层: 图标网格, 从菜单按钮上方展开 */
.town-hud-menu { position: absolute; }
.town-menu-pop { display: none; position: absolute; left: 0; bottom: calc(100% + 8px); grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 8px; background: rgba(13, 16, 48, 0.96); border: 2px solid #6a6ad8; box-shadow: 0 0 0 2px #05052a, 0 8px 20px rgba(0,0,0,.6); z-index: 40; }
.town-menu-pop.open { display: grid; }
.town-menu-pop button { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 58px; padding: 8px 4px 6px; font-size: 20px; background: rgba(26, 29, 74, 0.9); border: 2px solid #2a2a5a; }
.town-menu-pop button span { font-size: 11px; color: #c8d2ff; }
.town-menu-pop button:hover { background: #2b2f7e; border-color: #6a6ad8; }
/* 移动端: 格子加大触区 */
@media (max-width: 1100px) {
    /* 菜单按钮在左上角 (top 定位) → 弹层改从按钮【下方】展开,
       否则向上弹出 .town-view 的 overflow:hidden 边界被剪掉 (菜单被遮挡) */
    .town-menu-pop { bottom: auto; top: calc(100% + 6px); gap: 5px; padding: 6px; }
    .town-menu-pop button { min-width: 52px; padding: 10px 2px 8px; font-size: 22px; }
    .town-menu-pop button span { font-size: 10px; }
}
body.touch .town-menu-pop button { min-width: 62px; padding: 12px 2px 10px; }
/* ---- 画面矮时的 HUD 紧凑档 (#town-ui.ui-compact, 由 town.js 按画面高度切换) ----
   来历: HUD 的缩放 ts 有【下限 1】(当年为了"手机字够大"特意设的), 所以小画面上 HUD 仍按
   1024 宽的设计空间 1:1 显示 —— 菜单弹层 ~79px 高, 在 174px 高的画面上占掉 45%, 很挡
   (用户: "低分辨率挡整个屏幕了")。
   这里不整体缩放 HUD (字会小到看不清), 只把【格子】收一档。
   ★ `line-height` 是关键: 格子是 flex 列, 里面的 emoji 文本节点按回退字体的行盒算 ——
   15px 的 emoji 行盒能到 36px, 把格子顶到 59px。不压它, 光改 padding/字号几乎没有效果 (实测过)。
   用 #id 提特异性: 要压过 body.touch / body #town-menu-pop 那几条。 */
#town-ui.ui-compact .town-menu-pop { padding: 4px; gap: 3px; }
#town-ui.ui-compact .town-menu-pop button { padding: 6px 1px 4px; font-size: 15px; line-height: 1.2; }
#town-ui.ui-compact .town-menu-pop button span { font-size: 8px; }
/* 触屏才保 44px 触控目标; 鼠标的小窗口不用被它撑高。
   ★ 用【固定 height + 溢出裁掉】而不是 min-height: 格子里的 emoji 文本节点会带一个很大的
   行盒 (实测 15px 字撑到 ~43px 内容高, 改 line-height/flex-direction 都不动它),
   给 min-height 没用 (57 仍大于 44)。固定 44 + 居中 + overflow:hidden 才压得住,
   emoji 字形本身比它的行盒小, 实测不切边。 */
body.touch #town-ui.ui-compact .town-menu-pop button { height: 44px; min-height: 0; justify-content: center; overflow: hidden; }
#town-ui.ui-compact .town-menu-pop button { height: 42px; min-height: 0; justify-content: center; overflow: hidden; }
/* 紧凑档里格子只有 ~44px 高, 角标再内联就会压到标签 (实测"任务"上叠了数字) → 改成右上角的通知点 */
#town-ui.ui-compact .town-menu-pop button { position: relative; }
#town-ui.ui-compact .town-menu-pop button .hud-badge {
    position: absolute; top: 1px; right: 1px; margin: 0; padding: 0 3px;
    min-width: 12px; font-size: 9px; line-height: 1.35; border-radius: 6px;
}
/* 大屏触屏 (平板/触屏本, 宽度 > 1100): 摇杆 156px 在左下 → 菜单同样放【摇杆右侧贴下边】
   (原来写 bottom:154px 会让菜单浮在摇杆正上方与它重叠) */
@media (min-width: 1101px) {
    body.touch .town-hud-menu { left: 176px; right: auto; top: auto;
        bottom: max(8px, env(safe-area-inset-bottom)); }
    body.touch .town-menu-pop { top: auto; bottom: calc(100% + 8px); }
}

/* ---------- 人物/队伍/任务/设置 面板 (PSIV 窗, 半透明) ---------- */
.town-stats, .town-party, .town-quest, .town-settings { position: absolute; inset: 0; z-index: 9; pointer-events: none; }
.town-stats-panel, .town-party-panel, .town-quest-panel, .town-settings-panel {
    position: absolute; pointer-events: auto;
    background: linear-gradient(180deg, rgba(27, 27, 134, 0.93) 0%, rgba(18, 18, 102, 0.93) 30%, rgba(13, 13, 78, 0.95) 100%);
    box-shadow: 0 0 0 2px #05052a, 0 0 0 4px #d8dcf4, 0 0 0 6px #05052a, 0 10px 30px rgba(0, 0, 0, 0.5);
    display: flex; flex-direction: column; overflow: hidden;
}
.town-stats-panel { right: 8px; top: 8px; bottom: 8px; width: min(38%, 260px); }
.town-party-panel { right: 8px; top: 8px; bottom: 8px; width: min(48%, 330px); }
.town-quest-panel { left: 50%; transform: translateX(-50%); top: 6%; bottom: 6%; width: min(70%, 430px); }
.town-settings-panel { right: 8px; top: 8px; bottom: 8px; width: min(44%, 280px); }
.town-stats-body { flex: 1; overflow-y: auto; padding: 10px; font-size: 12px; color: #c8d2ff; }
.town-stat-row { display: flex; justify-content: space-between; padding: 4px 2px; border-bottom: 1px solid #26267a; }
.town-stat-row b { color: #fff; }
.town-stat-sect { color: #ffd24d; }
.town-party-body, .town-quest-body, .town-settings-body { flex: 1; overflow-y: auto; padding: 8px 10px; }
.town-party-sec { color: #9fb0f0; font-size: 11px; margin: 8px 0 4px; letter-spacing: 1px; }
.town-party-member { display: flex; align-items: center; gap: 7px; padding: 5px 7px; border-bottom: 1px solid #26267a; font-size: 12px; color: #fff; }
.town-party-member .ldr { color: #ffd24d; font-size: 10px; border: 1px solid #ffd24d; padding: 0 4px; }
.town-party-member .scn { margin-left: auto; color: #6a7ac0; font-size: 10px; }
.town-party-item { display: flex; align-items: center; gap: 7px; padding: 5px 7px; border-bottom: 1px solid #26267a; font-size: 12px; }
.town-party-item .nm2 { flex: 1; color: #fff; }
.town-party-item button, .town-quest-item button, .town-quest-form button {
    background: #121266; color: #ffd24d; border: 2px solid #6a6ad8; padding: 2px 10px;
    cursor: pointer; font-size: 11px; border-radius: 0;
}
.town-party-item button:hover, .town-quest-item button:hover, .town-quest-form button:hover { background: #2a2ab0; color: #fff; }
.town-party-create { display: flex; gap: 6px; padding: 4px 0 8px; }
.town-party-create input {
    flex: 1; background: rgba(5, 5, 42, 0.8); color: #eaf3ff;
    border: 2px solid #6a6ad8; border-radius: 0; padding: 4px 8px; font-size: 12px;
}
.town-quest-item { border-bottom: 1px solid #26267a; padding: 7px 4px; }
.town-quest-item .qt { font-size: 13px; color: #fff; }
.town-quest-item .qd { font-size: 11px; color: #9fb0f0; margin: 3px 0; line-height: 1.5; }
.town-quest-item .qr { font-size: 11px; color: #ffd24d; }
.town-quest-item .taken { color: #6ef2ff; font-size: 11px; }
.town-quest-form { border-top: 2px solid #3a3a9e; margin-top: 8px; padding-top: 8px; display: flex; flex-direction: column; gap: 5px; }
.town-quest-form input, .town-quest-form textarea {
    background: rgba(5, 5, 42, 0.8); color: #eaf3ff; border: 2px solid #6a6ad8;
    border-radius: 0; padding: 4px 8px; font-size: 12px; font-family: inherit;
}
.town-quest-form textarea { resize: vertical; min-height: 44px; }
.town-set-row { display: flex; align-items: center; gap: 8px; padding: 7px 4px; border-bottom: 1px solid #26267a; font-size: 12px; color: #c8d2ff; cursor: pointer; }
.town-set-row input { accent-color: #3a3ad0; width: 15px; height: 15px; }
.town-empty-tip { text-align: center; color: #6a7ac0; padding: 24px 0; font-size: 12px; }
@media (max-width: 1100px) {
    .town-stats-panel { width: 46%; }
    .town-party-panel { width: 62%; }
    .town-quest-panel { width: 94%; }
    .town-settings-panel { width: 66%; }
}

/* 人物弹窗时背包半透明 */
.town-bag.trans .town-bag-panel {
    background: linear-gradient(180deg, rgba(27, 27, 134, 0.88) 0%, rgba(18, 18, 102, 0.88) 30%, rgba(13, 13, 78, 0.9) 100%);
}
/* 鼠标移到聊天区输入行也浮现 (便于点击) */
.town-chat:hover .town-chat-input-row { opacity: 1; }
/* 移动端: 画面小 (竖屏约 360x200), 覆盖层要省地方
   - HUD 菜单挪到画面左上 (左下留给摇杆); 聊天靠右下并限高, 不再超出画面被裁切 */
@media (max-width: 1100px) {
    .town-chat { width: 52%; max-width: 240px; }
    .town-chat-log { max-height: 64px; min-height: 0; }
    .town-chat-tip { min-height: 0; font-size: 10px; padding: 0 6px; }
    .town-chat-input-row { padding: 4px 6px 5px; gap: 5px; }
    .town-chat-input { font-size: 14px; padding: 4px 8px; }
    .town-chat-send { font-size: 13px; padding: 4px 12px; }
    /* 定位交给 orientation 专项块 (竖屏左上 / 横屏摇杆右侧); 这里只管尺寸
       ★ 不能在这里写定位: 本块在 CSS 末尾, 会覆盖前面的横屏规则 (踩过) */
    .town-hud-menu { gap: 4px; }
    .town-hud-menu button { font-size: 11px; padding: 3px 7px; }
}

/* ================= 全屏适配 (原生 fullscreen 与 iOS 伪全屏同规则) ================= */
.town-stage:fullscreen, .town-stage.fs-fake { background: #060c1c; }
.town-stage:fullscreen .town-canvas-box, .town-stage.fs-fake .town-canvas-box { min-height: 0; }
/* 顶栏瘦身 + 隐藏操作提示 */
.town-stage:fullscreen .town-stage-bar, .town-stage.fs-fake .town-stage-bar { padding: 5px 14px; }
.town-stage:fullscreen .town-stage-keys, .town-stage.fs-fake .town-stage-keys { display: none; }
/* 注: 全屏不再单独放大面板/聊天/摇杆/按钮 —— #town-ui 已按画面宽等比缩放, 重复放大会双重放大 */

/* ---------- 全屏: 顶栏占一行(不悬浮遮挡面板), 画布区吃掉剩余高度 ---------- */
.town-stage:fullscreen .town-canvas-box, .town-stage.fs-fake .town-canvas-box {
    flex: 1; height: auto; min-height: 0; max-height: none;
}
.town-stage:fullscreen, .town-stage.fs-fake { display: flex; flex-direction: column; }

/* ---------- 人物面板头像 / 队伍标记 / 任务状态 ---------- */
.town-stats-avatar { text-align: center; padding: 4px 0 8px; }
.town-stats-avatar canvas { image-rendering: pixelated; border: 2px solid #d8dcf4; background: #05052a; max-width: 100%; }
.town-party-badge {
    display: inline-block; font-size: 10px; color: #05252e; background: #6ef2ff;
    border: 1px solid #d8dcf4; padding: 0 4px; margin-left: 4px; vertical-align: 1px;
}
.town-hud-menu button .hud-badge {
    display: inline-block; min-width: 14px; margin-left: 3px; padding: 0 4px;
    font-size: 10px; color: #12203a; background: #ffd24d; border-radius: 7px; font-weight: bold;
}
.town-quest-item .qstate { font-size: 11px; padding: 0 6px; border: 1px solid #6a6ad8; }
.town-quest-item .qstate.s0 { color: #ffd24d; }
.town-quest-item .qstate.s1 { color: #9fd8ff; }
.town-quest-item .qstate.s2 { color: #7ef29a; border-color: #7ef29a; }
.town-quest-item.mine { background: rgba(30, 60, 110, 0.35); }
.town-quest-pending { border-top: 2px solid #ffd24d; margin-top: 8px; padding-top: 6px; }
.town-quest-pending .row2 { display: flex; align-items: center; gap: 6px; padding: 4px 2px; font-size: 12px; }
.town-quest-pending .row2 span.nm2 { flex: 1; color: #fff; }

/* ---------- NPC 对话 (PSIV 样式) ---------- */
.town-dialog {
    position: absolute; left: 50%; transform: translateX(-50%); bottom: 14px;
    width: min(78%, 680px); min-height: 76px;
    padding: 12px 16px 14px;
    background: linear-gradient(180deg, #1b1b86 0%, #121266 30%, #0d0d4e 100%);
    box-shadow: 0 0 0 2px #05052a, 0 0 0 4px #d8dcf4, 0 0 0 6px #05052a;
    z-index: 40; image-rendering: pixelated;
}
.town-dialog-name {
    position: absolute; top: -12px; left: 14px; padding: 1px 10px;
    background: #05052a; color: #ffd24d; font-size: 12px; font-weight: bold;
    box-shadow: 0 0 0 2px #d8dcf4;
}
.town-dialog-text { color: #eef3ff; font-size: 13px; line-height: 1.85; white-space: pre-wrap; word-break: break-word; }
.town-dialog-more { position: absolute; right: 12px; bottom: 6px; color: #ffd24d; font-size: 12px; animation: tdBounce 0.9s infinite; }
/* 对话里的 Yes/No 选项 (原版剧本 $F5): 翻到最后一页才亮出来, 点它或按 Y/N 生效 */
.town-dialog-choices { display: flex; gap: 8px; justify-content: flex-end; margin-top: 8px; }
.town-dialog-choice {
    padding: 5px 16px; font: inherit; font-size: 13px; color: #dfe3ea;
    background: rgba(5, 5, 42, 0.9); border: 0; cursor: pointer; min-height: 30px;
    box-shadow: 0 0 0 2px #05052a, 0 0 0 3px #8b93b8;
    -webkit-tap-highlight-color: transparent;
}
.town-dialog-choice.on { color: #1a1a2e; background: #ffd24d; box-shadow: 0 0 0 2px #05052a, 0 0 0 3px #ffd24d; }
@media (pointer: coarse) { .town-dialog-choice { min-height: 44px; padding: 8px 20px; } }
/* 切场景/进镇后的场景名提示 (JRPG 那种"到某地了"的条):
   · 淡入淡出 + 轻微上浮;  pointer-events:none 保证不挡点地移动/摇杆;
   · 定位在画面上 1/4 处居中, 不压对话框和底部菜单。
   ★ 配色必须跟面板/菜单同一套语言, 三个值都直接抄现有元素:
     底 = 对话框的深蓝渐变 (.town-dialog) · 描边 = 交互提示条的双层 (.town-interact-hint)
     字 = 面板标题的金 (.town-bag-title / .shop-wallet)。
     之前我用了 `#6a6ad8` 单描边 —— 那是**控件边框色**(菜单/tab 的外框), 不是面板配色,
     和菜单列表摆在一起就显生 (用户: "风格与菜单列表不搭")。别再改回去。 */
.town-scene-toast {
    position: absolute; left: 50%; top: 22%; transform: translate(-50%, -8px);
    padding: 5px 22px 6px; font-size: 14px; font-weight: bold; letter-spacing: 3px; white-space: nowrap;
    color: #ffd24d;
    background: linear-gradient(180deg, #1b1b86 0%, #121266 30%, #0d0d4e 100%);
    box-shadow: 0 0 0 2px #05052a, 0 0 0 3px #d8dcf4;
    text-shadow: 1px 1px 0 #05052a;
    opacity: 0; visibility: hidden;
    transition: opacity .3s ease, transform .3s ease;
    pointer-events: none; z-index: 30;
}
.town-scene-toast.on { opacity: 1; visibility: visible; transform: translate(-50%, 0); }
/* 竖屏/小画面: 字号收一点; 位置下移到 26% —— 顶部 4~48px 留给交互提示条, 别重叠 */
@media (max-width: 1100px) {
    .town-scene-toast { font-size: 13px; letter-spacing: 2px; padding: 4px 16px 5px; top: 26%; }
}
@keyframes tdBounce { 0%,100% { transform: translateY(0); } 50% { transform: translateY(3px); } }
.town-interact-hint {
    position: absolute; left: 50%; transform: translateX(-50%); bottom: 104px;
    padding: 3px 12px; font-size: 12px; color: #fff3cf;
    background: rgba(5, 5, 42, 0.82);
    box-shadow: 0 0 0 2px #05052a, 0 0 0 3px #d8dcf4;
    z-index: 35;
    pointer-events: auto; cursor: pointer; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent;
}
.town-interact-hint:active { filter: brightness(1.3); }
/* 触屏: 挪到画面【顶部居中】。
   来历: 原来它放在 bottom:128px 正横在画面中央列, 玩家点地走路会被它吃掉变交谈 (真机实测)
   → 被赶到右上角。但右上角是小地图, 面板的关闭键也在右上角 → 一点提示就挡东西
   (用户反馈"挡到了列表关闭按键")。现在放顶部居中: 避开左上菜单键 / 右上小地图 / 底部摇杆聊天。
   ★ **必须保留 pointer-events:auto** —— 它上面写着「👆 交谈 · xx」, 本身就是触摸端【主要的交互按钮】
   (小人只有几十像素, 戳不准; 这个条 44px 高且就在眼前)。我一度因为"会吃掉点地走路"改成 none,
   结果直接把手机上的交互入口关掉了 (用户: "点击交互又点不了了")。
   现在靠"面板打开时 updateInteractHint 收起它"来解决挡按键, 不靠 pointer-events。
   transform 必须用 translateX(-50%) 居中 (基类就是 left:50%)。 */
body.touch .town-interact-hint {
    top: 4px; left: 50%; right: auto; bottom: auto; transform: translateX(-50%);
    padding: 10px 16px; font-size: 12px; max-width: min(64%, 320px); min-height: 44px;
    display: flex; align-items: center;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    pointer-events: auto;
}

/* ---- 战斗进行中: 隐藏小镇 HUD / 聊天 / 虚拟键盘, 让战斗界面独占画面 ---- */
body.town-in-battle #town-chat,
body.town-in-battle #town-hud-menu,
body.town-in-battle #town-party,
body.town-in-battle #town-interact-hint,
body.town-in-battle #town-dpad,
body.town-in-battle #town-bag,
body.town-in-battle #town-stats,
body.town-in-battle #town-quest,
body.town-in-battle #town-settings,
body.town-in-battle #town-shop,
body.town-in-battle #town-checkin,
body.town-in-battle #town-mag { display: none !important; }

/* ---------------- 玛古面板 ---------------- */
.mg-mags { display: flex; flex-direction: column; gap: 4px; margin-bottom: 2px; }
.mg-mag { display: flex; align-items: center; gap: 8px; background: #14173d; border: 2px solid #2a2a5a; padding: 5px 8px; cursor: pointer; }
.mg-mag:hover { border-color: #4a4a9a; }
.mg-mag.on { border-color: #6a6ad8; background: #1e2260; }
.mg-mag.evoing { border-color: #ffd76b; animation: mgEvoPulse 0.7s ease-in-out infinite alternate; }
@keyframes mgEvoPulse { from { box-shadow: 0 0 2px 0 rgba(255,215,107,.2); } to { box-shadow: 0 0 10px 1px rgba(255,215,107,.75); } }
.mg-mag-face { width: 48px; height: 48px; border: 2px solid #3a3a7a; background: #101338; image-rendering: pixelated; flex: none; }
.mg-mag-face canvas { width: 100%; height: 100%; image-rendering: pixelated; }
.mg-mag-face.mg-f2 { border-color: #3f7f9f; }
.mg-mag-face.mg-f3 { border-color: #b58a2e; }
.mg-mag-face.mg-f4 { border-color: #d7862e; box-shadow: 0 0 6px rgba(255,170,60,.45); }
.mg-mag-meta { flex: 1; min-width: 0; }
.mg-eq { font-size: 10px; color: #8ff; border: 1px solid #4ad; padding: 0 3px; margin-left: 2px; }
.mg-stage1, .mg-stage2, .mg-stage3, .mg-stage4 { font-size: 10px; font-weight: normal; padding: 0 4px; margin-left: 5px; border: 1px solid; }
.mg-stage1 { color: #9aa4cc; border-color: #3a3a7a; }
.mg-stage2 { color: #7fd4e8; border-color: #3f7f9f; }
.mg-stage3 { color: #ffd76b; border-color: #b58a2e; }
.mg-stage4 { color: #ffb347; border-color: #d7862e; }
.mg-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 8px; margin-top: 3px; }   /* 四维两行, 窄屏不出界 */
.mg-stat { display: flex; align-items: center; gap: 3px; font-size: 10px; color: #c8d2ff; min-width: 0; }
.mg-stat i { font-style: normal; color: #8a94b8; }
.mg-stat b { display: block; width: 34px; height: 5px; background: #0d1030; border: 1px solid #2a2a5a; }
.mg-stat u { display: block; height: 100%; background: linear-gradient(90deg, #35d0ff, #8ff2ff); text-decoration: none; }
.mg-stat em { font-style: normal; color: #eef; min-width: 15px; text-align: right; }
.mg-tgt { font-size: 11px; color: #ffd24d; flex: none; }
.mg-feedbtn { flex: none; background: #2a2a6a; border: 2px solid #6a6ad8; color: #eef; font-size: 12px; padding: 4px 10px; cursor: pointer; font-family: inherit; }
.mg-feedbtn:hover { background: #3a3a8a; border-color: #8a8af0; }
.mg-feedbtn:disabled { opacity: .5; cursor: default; }
.mg-pop-mask { position: absolute; inset: 0; background: rgba(4,6,20,.55); z-index: 5; }
.mg-feedpop { position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%); z-index: 6; width: min(300px, 92%); background: #131740; border: 2px solid #6a6ad8; box-shadow: 0 0 0 2px #05052a, 0 6px 18px rgba(0,0,0,.6); padding: 8px; }
.mg-pop-head { display: flex; align-items: center; font-size: 13px; color: #ffd24d; margin-bottom: 6px; }
.mg-pop-close { margin-left: auto; background: none; border: none; color: #aab; font-size: 14px; cursor: pointer; padding: 0 4px; }
.mg-pop-close:hover { color: #fff; }
.mg-pop-list { display: flex; flex-direction: column; gap: 4px; max-height: 240px; overflow-y: auto; }
#town-mag-body { position: relative; }   /* 喂养弹层的定位锚 */
.mg-tgt.evo { color: #ffd76b; font-size: 14px; animation: mgBlink .5s steps(2) infinite; }
@keyframes mgBlink { 50% { opacity: .3; } }
.mg-head { display: flex; align-items: center; gap: 10px; padding: 4px 2px 8px; }
.mg-face { width: 64px; height: 64px; border: 2px solid #6a6ad8; background: #101338; image-rendering: pixelated; flex: none; }
.mg-face canvas { width: 100%; height: 100%; image-rendering: pixelated; }
.mg-meta { flex: 1; min-width: 0; }
.mg-name { font-size: 14px; color: #eef; font-weight: bold; }
.mg-stage { font-size: 11px; color: #8ff; font-weight: normal; margin-left: 4px; }
.mg-lv { font-size: 12px; color: #ffd24d; margin: 2px 0; }
.mg-max { color: #ff9d2e; font-size: 10px; border: 1px solid #ff9d2e; padding: 0 3px; }
.mg-bar { height: 8px; background: #101338; border: 1px solid #3a3a7a; margin: 2px 0; }
.mg-bar i { display: block; height: 100%; background: linear-gradient(90deg, #35d0ff, #8ff2ff); }
.mg-exp { font-size: 10px; color: #9aa4cc; }
.mg-sec { font-size: 11px; color: #c8d2ff; border-top: 1px solid #2a2a5a; padding: 8px 2px 4px; margin-top: 4px; }
.mg-feed { display: flex; flex-wrap: wrap; gap: 6px; }
.mg-item { display: flex; align-items: center; gap: 6px; background: #1a1d4a; border: 2px solid #3a3a7a; color: #dfe6ff; font-size: 12px; padding: 4px 8px; cursor: pointer; }
.mg-item:hover { border-color: #6a6ad8; background: #262a6a; }
.mg-item:disabled { opacity: .5; cursor: default; }
.mg-gain { color: #7fff9d; font-size: 11px; }
.mg-tip { margin-top: 8px; font-size: 11px; padding: 5px 8px; border: 1px solid; }
.mg-tip.ok { color: #9fe8a8; border-color: #2f6b3a; background: rgba(47,107,58,.15); }
.mg-tip.err { color: #ffb0a8; border-color: #6b2f2f; background: rgba(107,47,47,.15); }

/* ---------------- 每日签到面板 ---------------- */
.ci-head { display: flex; align-items: center; gap: 10px; padding: 6px 2px 8px; font-size: 12px; color: #c8d2ff; }
.ci-head b { color: #ffd24d; font-size: 15px; }
.ci-today { margin-left: auto; padding: 1px 8px; border: 2px solid #6a6ad8; }
.ci-today.done { color: #7ef7c8; border-color: #2f8f6a; }
.ci-today.todo { color: #ffd24d; border-color: #8a6a10; }
.ci-ms { display: flex; gap: 5px; flex-wrap: wrap; padding: 2px 0 4px; }
.ci-ms-day { font-size: 11px; padding: 1px 7px; border: 2px solid #3a3a80; color: #8f9cd0; }
.ci-ms-day.on { border-color: #ffd24d; color: #fff3b0; background: #4a3a10; }
.ci-tip { font-size: 11px; color: #9fd4ff; padding-bottom: 4px; }
.ci-note { font-size: 11px; color: #a8b2e0; line-height: 17px; padding: 6px 0; border-top: 1px solid #26267a; }
.ci-note code { color: #ffe9a8; }
.ci-result { margin: 6px 0; padding: 6px 8px; font-size: 12px; border: 2px solid #6a6ad8; }
.ci-result.ok { color: #7ef7c8; border-color: #2f8f6a; }
.ci-result.bad { color: #ff9a8a; border-color: #8a2f2f; }
.ci-rws { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
.ci-rw { font-size: 11px; color: #ffe9a8; border: 1px solid #8a6a10; padding: 1px 6px; }
.ci-rw.ms { color: #ffd24d; border-color: #ffd24d; }
.ci-rw.mes { color: #9fd4ff; border-color: #2f5f8f; }
.ci-foot { padding-top: 8px; text-align: center; }
.ci-btn { width: 100%; padding: 7px 0; font: inherit; font-size: 13px; color: #fff;
    background: #3a3ad0; border: 2px solid #d8dcf4; cursor: pointer; text-shadow: 1px 1px 0 #05052a; }
.ci-btn:hover:not(:disabled) { background: #4a4ae0; }
.ci-btn:disabled { opacity: .45; cursor: default; }

/* ---------------- 系统商店面板 ---------------- */
.shop-head { display: flex; align-items: center; gap: 8px; padding: 6px 2px 8px; }
.shop-tab { padding: 2px 12px; border: 2px solid #6a6ad8; color: #c8d2ff; cursor: pointer; font-size: 12px; }
.shop-tab.on { background: #3a3ad0; color: #fff; border-color: #d8dcf4; }
.shop-wallet { margin-left: auto; color: #ffd24d; font-size: 13px; }
.shop-list { display: flex; flex-direction: column; }
.shop-row { display: flex; align-items: center; gap: 8px; padding: 5px 6px; border-bottom: 1px solid #26267a; font-size: 12px; }
.shop-row:hover { background: rgba(58,58,176,.35); }
.shop-row .nm { flex: 1; color: #dfe8ff; }
.shop-row .pr { color: #ffd24d; font-variant-numeric: tabular-nums; }
.shop-row button { padding: 2px 10px; font: inherit; font-size: 11px; color: #fff;
    background: #3a3ad0; border: 1px solid #d8dcf4; cursor: pointer; }
.shop-row button:hover:not(:disabled) { background: #4a4ae0; }
.shop-row button:disabled { opacity: .45; cursor: default; }
.shop-empty { font-size: 12px; color: #a8b2e0; padding: 12px 4px; line-height: 18px; }
.shop-note { font-size: 11px; color: #8f9cd0; padding: 8px 2px 0; border-top: 1px solid #26267a; margin-top: 6px; }
.shop-toast { position: absolute; left: 50%; bottom: 12%; transform: translateX(-50%);
    padding: 4px 14px; background: rgba(6,8,32,.92); color: #7ef7c8; border: 1px solid #2f8f6a;
    font-size: 12px; pointer-events: none; z-index: 5; }
.shop-toast.bad { color: #ff9a8a; border-color: #8a2f2f; }
.mg-sub { font-size: 10px; color: #8a94b8; margin-top: 1px; }

/* ---------------- 合成台面板 ---------------- */
.cr-rows { display: flex; flex-direction: column; gap: 5px; }
.cr-row { position: relative; background: #14173d; border: 2px solid #2a2a5a; padding: 5px 64px 5px 8px; }
.cr-row:hover { border-color: #4a4a9a; }
.cr-head { display: flex; align-items: baseline; gap: 8px; }
.cr-name { font-size: 13px; color: #eef; font-weight: bold; }
.cr-out { font-size: 12px; color: #7fff9d; }
.cr-mats { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 3px; }
.cr-mat { font-size: 11px; color: #c8d2ff; }
.cr-mat.lack { color: #ff9d8a; }
.cr-mat.fee { color: #ffd24d; }
.cr-make { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); background: #2a2a6a; border: 2px solid #6a6ad8; color: #eef; font-size: 12px; padding: 4px 12px; cursor: pointer; font-family: inherit; }
.cr-make:hover:not(:disabled) { background: #3a3a8a; border-color: #8a8af0; }
.cr-make:disabled { opacity: .4; cursor: default; }
.cr-tip { margin-top: 8px; font-size: 11px; padding: 5px 8px; border: 1px solid; }
.cr-tip.ok { color: #9fe8a8; border-color: #2f6b3a; background: rgba(47,107,58,.15); }
.cr-tip.err { color: #ffb0a8; border-color: #6b2f2f; background: rgba(107,47,47,.15); }
body.town-in-battle #town-craft { display: none !important; }

/* ---------------- 家园面板 ---------------- */
.hm-mine { background: #14173d; border: 2px solid #2a2a5a; padding: 6px 8px; }
.hm-name { font-size: 14px; color: #eef; font-weight: bold; }
.hm-new { font-size: 10px; color: #7fff9d; border: 1px solid #2f6b3a; padding: 0 4px; margin-left: 4px; }
.hm-go { margin: 5px 0; background: #2a6a3a; border: 2px solid #4aad5a; color: #fff; font-size: 13px; padding: 5px 16px; cursor: pointer; font-family: inherit; }
/* 装修入口 (次要按钮): 与 hm-go 同排, 描边弱一点 */
.hm-edit { margin: 5px 0 5px 6px; background: none; border: 2px solid #6a8ab8; color: #bcd9ff;
    font-size: 13px; padding: 5px 14px; cursor: pointer; font-family: inherit; }
.hm-edit:hover { background: #1e2f4a; color: #fff; }
.hm-go:hover { background: #3a8a4a; }
.hm-meta-row { display: flex; gap: 6px; align-items: center; margin-top: 4px; }
.hm-input { flex: 1; min-width: 0; background: #101338; border: 2px solid #3a3a7a; color: #eef; font-size: 12px; padding: 4px 6px; font-family: inherit; }
.hm-input:focus { outline: none; border-color: #6a6ad8; }
.hm-pub { font-size: 11px; color: #c8d2ff; white-space: nowrap; }
.hm-save { background: #2a2a6a; border: 2px solid #6a6ad8; color: #eef; font-size: 12px; padding: 4px 10px; cursor: pointer; font-family: inherit; }
.hm-save:disabled { opacity: .5; }
.hm-tip { font-size: 10px; color: #8a94b8; margin-top: 5px; line-height: 1.6; }
.hm-list { display: flex; flex-direction: column; gap: 3px; }
.hm-row { display: flex; align-items: center; gap: 8px; background: #14173d; border: 2px solid #2a2a5a; padding: 4px 8px; cursor: pointer; }
.hm-row:hover { border-color: #4a4a9a; }
.hm-info { flex: 1; min-width: 0; }
.hm-hname { font-size: 13px; color: #eef; }
.hm-owner { font-size: 10px; color: #8a94b8; margin-left: 8px; }
.hm-visit { background: none; border: 1px solid #6a6ad8; color: #9fb6ff; font-size: 11px; padding: 2px 8px; cursor: pointer; font-family: inherit; }
body.town-in-battle #town-home { display: none !important; }

/* 家园面板 - 公会分区 */
.hm-guild { background: #14173d; border: 2px solid #2a2a5a; padding: 6px 8px; }
.hm-memrow { display: flex; flex-wrap: wrap; gap: 4px 10px; margin: 3px 0; }
.hm-mem { font-size: 11px; color: #7a84a8; }
.hm-mem.on { color: #7fff9d; }
.hm-mem.on::before { content: '●'; font-size: 8px; margin-right: 3px; }
.hm-dim { font-size: 10px; color: #8a94b8; }
.hm-ghcreate { margin: 5px 0; background: #6a4a1a; border: 2px solid #b58a2e; color: #fff; font-size: 13px; padding: 5px 16px; cursor: pointer; font-family: inherit; }
.hm-ghcreate:hover:not(:disabled) { background: #8a6a2a; }
.hm-ghcreate:disabled { opacity: .5; }

/* ---------------- 家园种植: 选种子浮层 ---------------- */
.town-farm-pop {
    position: fixed; inset: 0; z-index: 60; display: none;
    align-items: center; justify-content: center;
    background: rgba(4, 8, 20, 0.62);
}
.town-farm-pop .tf-box {
    width: min(92vw, 420px); max-height: 76vh;
    background: #0d1030; border: 2px solid #6a6ad8;
    box-shadow: 0 0 0 2px #05052a, 0 12px 30px rgba(0,0,0,.6);
    display: flex; flex-direction: column;
}
.town-farm-pop .tf-head {
    display: flex; align-items: center; gap: 8px; padding: 8px 10px;
    background: #14173d; border-bottom: 2px solid #2a2a5a;
    color: #cfe0ff; font-size: 14px;
}
.town-farm-pop .tf-head span { flex: 1; }
.town-farm-pop .tf-close {
    background: none; border: 1px solid #6a6ad8; color: #9fb6ff;
    font-size: 13px; padding: 2px 8px; cursor: pointer; font-family: inherit;
}
.town-farm-pop .tf-body { padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.town-farm-pop .tf-empty { color: #8a94b8; font-size: 12px; padding: 14px 6px; text-align: center; }
.town-farm-pop .tf-seed {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    background: #14173d; border: 2px solid #2a2a5a; color: #eef;
    padding: 7px 9px; cursor: pointer; font-family: inherit; text-align: left; width: 100%;
}
.town-farm-pop .tf-seed:hover:not(.off) { border-color: #6a6ad8; background: #1b1f4e; }
.town-farm-pop .tf-seed.off { opacity: .42; cursor: not-allowed; }
.town-farm-pop .tf-sn { font-size: 13px; }
.town-farm-pop .tf-have { color: #ffd24d; margin-left: 6px; font-size: 12px; }
.town-farm-pop .tf-st { font-size: 11px; color: #8fd6a0; }
.town-farm-pop .tf-sy { font-size: 11px; color: #8a94b8; }
body.town-in-battle #town-farm-pop { display: none !important; }

/* ---------------- 小镇内嵌登录表单 (不用跳去账户页) ---------------- */
.town-login { display: flex; flex-direction: column; gap: 10px; width: min(88vw, 340px); margin: 0 auto; }
.town-login-row { display: flex; align-items: center; gap: 8px; }
.town-login-row span { font-size: 13px; color: #9db6e4; width: 52px; text-align: right; flex: none; }
.town-login-row input {
    flex: 1; min-width: 0; background: #101338; border: 2px solid #3a3a7a; color: #eef;
    font-size: 14px; padding: 7px 9px; font-family: inherit;
}
.town-login-row input:focus { outline: none; border-color: #6a6ad8; }
.town-login-err {
    background: #3a1620; border: 2px solid #a04050; color: #ffb8c0;
    font-size: 12px; line-height: 1.7; padding: 6px 9px; text-align: left;
}
.town-login .town-btn-primary { width: 100%; cursor: pointer; font-family: inherit; }
.town-login-links { margin-top: 16px; font-size: 12px; color: #7a86b0; line-height: 2; }
.town-login-links a { color: #9fb6ff; text-decoration: none; border-bottom: 1px dotted #4a5a9a; }
.town-login-links a:hover { color: #cfe0ff; }

/* 对话框半身立绘 (资产配了 art.front / 大头像才显示)
   立绘立在对话框【上方】(bottom:100% = 底边贴着框口), 名牌压住它的下沿 ——
   这样人物是从框里"探"出来的, 而不是把对话框内容挤到右边去。 */
.town-dialog-art {
    position: absolute; left: 10px; bottom: 100%; z-index: 1;
    image-rendering: pixelated;
    max-height: min(112px, 22vh); width: auto;
    border: 2px solid #2a2a5a; background: #0b1030;
}
/* 名牌要盖在立绘上 → z-index 比立绘高, 且晚于画布出现 (DOM 顺序也是它在后) */
.town-dialog-name { z-index: 2; }

/* ---------------- GM 场景传送面板 (☰ 菜单 → 🚀 传送, 仅 GM 可见) ----------------
   复用 .town-bag-panel 的配色与 .town-settings-panel 的右侧定位, 只加"搜索框 + 清单"两条。 */
.town-gmtp-body { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 8px 10px 10px; }
.town-gmtp-q {
    width: 100%; box-sizing: border-box; margin-bottom: 6px;
    background: #0d0d4e; color: #eef3ff; border: 2px solid #6a6ad8;
    padding: 5px 8px; font: inherit; font-size: 12px; border-radius: 0;
}
.town-gmtp-q::placeholder { color: #6a7ac0; }
.town-gmtp-list { flex: 1; min-height: 0; overflow-y: auto; }
.town-gmtp-sec { color: #ffd24d; font-size: 11px; letter-spacing: 1px; margin: 8px 0 3px; }
.town-gmtp-row {
    display: flex; align-items: center; gap: 6px; padding: 5px 6px; cursor: pointer;
    border-bottom: 1px solid #26267a; font-size: 12px; color: #fff;
}
.town-gmtp-row:hover { background: #2b2f7e; }
.town-gmtp-row .nm2 { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.town-gmtp-row .id2 { color: #6a7ac0; font-size: 10px; }
.town-gmtp-row .now { color: #ffd24d; font-size: 10px; border: 1px solid #ffd24d; padding: 0 4px; }
.town-gmtp-empty { color: #9fb0f0; font-size: 12px; padding: 10px 2px; }
