:root {
  --bg: #0f1115;
  --panel: #1a1e26;
  --text: #e8eaed;
  --muted: #9aa0a6;
  --accent: #e8b923;
  --border: #2a303c;
  --map-bg: #0b0d10;
  --ad: #252a33;
  --ad-border: #3a4250;
  --radius: 10px;
  --side-w: 316px;  /* 300x250 廣告放得下 */
  --top-ad-h: 90px;
  font-family: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif;
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
}

.layout {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  grid-template-columns: var(--side-w) 1fr;
  height: 100%;
  min-height: 100dvh;
}

.header {
  grid-column: 1 / -1;
  padding: 12px 16px 8px;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
}

.header h1 {
  margin: 0 0 4px;
  font-size: 1.15rem;
  font-weight: 700;
}

.header .sub {
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
}

.ad-top {
  grid-column: 1 / -1;
  min-height: var(--top-ad-h);
  margin: 8px 12px 0;
  border: 1px dashed var(--ad-border);
  border-radius: var(--radius);
  background: var(--ad);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 0.8rem;
}

.side {
  grid-row: 3;
  grid-column: 1;
  padding: 12px;
  border-right: 1px solid var(--border);
  background: var(--panel);
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow: auto;
}

.main {
  grid-row: 3;
  grid-column: 2;
  position: relative;
  background: var(--map-bg);
  min-height: 0;
}

#viewer {
  width: 100%;
  height: 100%;
  background: var(--map-bg);
}

.footer {
  grid-column: 1 / -1;
  padding: 8px 16px;
  border-top: 1px solid var(--border);
  background: var(--panel);
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1.4;
}

.footer a {
  color: var(--accent, #c9a227);
  text-decoration: none;
}

.footer a:hover {
  text-decoration: underline;
}

label {
  display: block;
  font-size: 0.75rem;
  color: var(--muted);
  margin-bottom: 4px;
}

select {
  width: 100%;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
}

#floor-select {
  font-weight: 600;
  max-height: none;
}

#floor-select option:disabled {
  color: var(--muted);
  font-weight: 400;
}

.hint {
  font-size: 0.75rem;
  color: var(--muted);
  line-height: 1.35;
}

.coords {
  font-family: ui-monospace, monospace;
  font-size: 0.8rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
}

.ad-side {
  margin-top: auto;
  min-height: 250px;
  border: 1px dashed var(--ad-border);
  border-radius: var(--radius);
  background: var(--ad);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--muted);
  font-size: 0.75rem;
  padding: 8px;
}

/* 手機專用：地圖下方那格。桌機由 data-ad-ready="off" ＋ min-width:801px 兩道收起。 */
.ad-below {
  grid-column: 1 / -1;
  min-height: 250px;
  margin: 8px 12px;
  border: 1px dashed var(--ad-border);
  border-radius: var(--radius);
  background: var(--ad);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--muted);
  font-size: 0.75rem;
  padding: 8px;
}

.loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,0.45);
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s;
}

.loading.show { opacity: 1; }

@media (max-width: 800px) {
  /* 手機改文件流。舊版把 .layout 鎖在 100dvh，`1fr` 的地圖又帶 min-height:55dvh，
     擠掉的高度全由 .side 吸收——而 .side 是 overflow:auto，於是控制面板下半截
     （遊戲座標、說明）與整格 .ad-side 都被裁在捲動區裡看不到。地圖改固定 60dvh，
     其餘內容往下排，捲得到就看得到。 */
  html, body { height: auto; }
  .layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto auto auto auto;
    height: auto;
    min-height: 100dvh;
  }
  /* 每一列都寫死。舊版只給 .side/.main 指定 grid-row，footer 靠自動排版；
     一旦 .ad-top 被 display:none 拿掉，footer 就遞補到第 2 列，
     免責聲明會出現在標題正下方（實測 390px 寬確認）。 */
  /* 手機把地圖排在控制面板「之前」。控制面板實測 430px 高（換行成兩欄後還是這麼高，
     而 #t-about 那段是給爬蟲吃的排名文字、行動優先索引下不能藏），排在地圖上面會把
     地圖推到 y=611，844px 的手機開畫面只看得到 233px 地圖——使用者是為了看地圖來的。
     改成 標題→橫幅→地圖→控制→地圖下方廣告→頁尾：390x844 下整張地圖（506px）都在
     第一屏內，控制面板從下緣露出來提示可捲。 */
  .header   { grid-row: 1; grid-column: 1; }
  .ad-top   { grid-row: 2; grid-column: 1; }
  .side     {
    grid-row: 4;
    grid-column: 1;
    border-right: none;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    overflow: visible;
  }
  .side > * { flex: 1 1 140px; }
  .main {
    grid-row: 3;
    grid-column: 1;
    height: 60dvh;
    min-height: 0;
  }
  .ad-below { grid-row: 5; grid-column: 1; }
  .footer   { grid-row: 6; grid-column: 1; }
}

.goto-btn {
  margin-top: 6px;
  width: 100%;
  background: var(--accent);
  color: #111;
  border: none;
  border-radius: 8px;
  padding: 8px;
  font-weight: 700;
  cursor: pointer;
}

#status {
  min-height: 1.2em;
  color: #e8b923;
}

.main { position: relative; overflow: hidden; }

.poi-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
}

.poi {
  position: absolute;
  transform: translate(-50%, -100%);
  pointer-events: auto;
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
}

.poi.city {
  background: rgba(0, 0, 0, 0.65);
  color: #ffe082;
  border: 1px solid #e8b923;
  border-radius: 6px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 700;
  text-shadow: 0 1px 2px #000;
}

.poi.rec {
  color: #ffd54f;
  font-size: 16px;
  filter: drop-shadow(0 1px 2px #000);
}

/* Community / recommended / in-game-label markers with hover name */
.poi.comm, .poi.rec, .poi.lm {
  transform: translate(-50%, -50%);
  z-index: 4;
}
.poi.lm { z-index: 6; }
.poi.lm .poi-dot {
  border-color: #e8b923;
  background: rgba(0, 0, 0, 0.72);
}
.poi-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(15, 17, 21, 0.82);
  border: 1px solid rgba(232, 185, 35, 0.65);
  font-size: 12px;
  line-height: 1;
  box-shadow: 0 1px 4px rgba(0,0,0,0.55);
}
.poi.cat-fire .poi-dot { border-color: #ff7043; }
.poi.cat-police .poi-dot { border-color: #42a5f5; }
.poi.cat-hospital .poi-dot { border-color: #ef5350; }
.poi.cat-gas .poi-dot { border-color: #66bb6a; }
.poi.cat-gun .poi-dot { border-color: #ab47bc; }
.poi.cat-warehouse .poi-dot { border-color: #8d6e63; }

.poi-tip {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  transform: translateX(-50%);
  background: rgba(10, 12, 16, 0.94);
  color: #ffe082;
  border: 1px solid #e8b923;
  border-radius: 6px;
  padding: 3px 8px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease;
  z-index: 6;
  text-shadow: 0 1px 2px #000;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.poi:hover .poi-tip,
.poi:focus-within .poi-tip {
  opacity: 1;
  visibility: visible;
}
.poi.city { z-index: 5; }

/* Global ad placeholders — never cover map / never block pointer on main */
.ad-top[data-ad-ready="placeholder"],
.ad-side[data-ad-ready="placeholder"] {
  font-size: 0.75rem;
  letter-spacing: 0.02em;
}
.ad-top[data-ad-ready="live"],
.ad-side[data-ad-ready="live"] {
  border-style: solid;
  overflow: hidden;
}
/* keep ads out of map hit-testing */
.ad-top, .ad-side { pointer-events: auto; }
.main, #viewer, .poi-layer { z-index: 1; }

/* Wider controls so place names are not clipped */
.side select {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  text-overflow: ellipsis;
}
.side select option {
  max-width: none;
}
/* Professional city label */
.poi.city {
  transform: translate(-50%, -120%);
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.poi.comm, .poi.rec, .poi.lm {
  transform: translate(-50%, -50%);
}

/* --- v14: 自製 minimap（取代 OSD navigator：整張 DZI 縮到 145px 後幾乎全黑） --- */
.minimap {
  position: absolute;
  right: 12px;
  bottom: 12px;
  width: 240px;
  border: 1px solid rgba(232, 185, 35, 0.45);
  border-radius: 6px;
  overflow: hidden;
  background: #0b0d10;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.55);
  line-height: 0;
  cursor: crosshair;
  z-index: 5;
  user-select: none;
}
.minimap[hidden] { display: none; }
.minimap img {
  width: 100%;
  height: auto;
  display: block;
  /* 縮圖偏暗，稍微提亮才看得出地形 */
  filter: brightness(1.18) saturate(1.05);
}
.minimap canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
@media (max-width: 900px) {
  .minimap { width: 150px; right: 8px; bottom: 8px; }
}

/* --- v14: 廣告位不得吃掉地圖（固定尺寸單元，不裁切） --- */
.ad-top[data-ad-ready="live"],
.ad-side[data-ad-ready="live"],
.ad-below[data-ad-ready="live"] {
  padding: 0;
  border-style: solid;
}
.ad-top[data-ad-ready="live"] { min-height: var(--top-ad-h); }
.ad-side[data-ad-ready="live"] { min-height: 250px; }
.ad-below[data-ad-ready="live"] { min-height: 250px; }

/* data-ad-ready="off" ＝ 這個尺寸不投放，deploy 腳本已把 <ins> 移除、連 request 都不發。
   舊版是把「已經 push 出去、AdSense 也回填了」的 .ad-top 用 display:none 藏起來
   （實測手機 data-ad-status="filled" 但 rect 0x0）——那是白燒庫存又踩可見度政策。
   要不投放就別 push，不是出了再藏。 */
.ad-top[data-ad-ready="off"],
.ad-side[data-ad-ready="off"],
.ad-below[data-ad-ready="off"] { display: none; }

/* 桌機不放這格（deploy 腳本不給 data-pz-d，會被標成 off）；這行只是雙保險。 */
@media (min-width: 801px) {
  .ad-below { display: none; }
}
