:root { --cell: 30px; --colw: 30px; --tiantou: calc(var(--cell) * 2); --note-font: calc(var(--cell) * 0.45); --main-font: calc(var(--cell) * 0.73); --ink: #222; --frame: #a33; --grid: #e6d7c8; }
* { box-sizing: border-box; }
body { margin: 0; font-family: "Noto Serif CJK TC", "Source Han Serif TC", "TW-Kai", "PMingLiU", serif; color: var(--ink); background: #faf6f0; }
/* 考訂本字與增補平面的字：網頁字型（fonts/fonts.css 由建置生成，只含用到的切片）。順序是對著抄本字形挑的：TW-Sung 最像，缺的用 BabelStone Han，再缺用 WFG FSung */
.rare, .cell.rare { font-family: "TW-Sung", "BabelStone Han Basic", "BabelStone Han Extra", "WFG FSung", "Noto Serif CJK TC", "Source Han Serif TC", "TW-Kai", "PMingLiU", serif; }
/* 直排格點不能靠字型的直排步進：BabelStone Han、WFG FSung 的切片沒有 vmtx，瀏覽器拿 ascent+descent（1.2em 上下）當步進，
   一格之後整欄往下推。所以和 sprite 字一樣，rare 格固定佔 1em 見方，字距用外邊距補 */
.cell.rare { display: inline-block; width: 1em; height: 1em; line-height: 1; letter-spacing: 0; vertical-align: baseline; margin-inline-end: var(--ls, 0px); overflow: visible; }
.mapped, .pua, .cell.pua { cursor: help; }
/* 控制列一行排完：檢索框吃剩下的寬度、可縮，翻葉與開關不縮；真放不下（手機）才折行 */
header { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; padding: 8px 16px; background: #fff; border-bottom: 1px solid #ddd; }
header h1 { font-size: 16px; margin: 0; white-space: nowrap; flex: none; display: flex; align-items: center; gap: 8px; }
/* 左上角的圖標就是目錄開關：旁邊一個隨開合翻向的小箭頭提示它能點，手機上再標「目錄」二字 */
#tocBtn { display: flex; align-items: center; gap: 4px; padding: 2px 6px 2px 2px; border: 1px solid transparent; border-radius: 6px; background: none; cursor: pointer; font: inherit; color: #666; }
#tocBtn:hover { border-color: #ccc; background: #f3ede4; }
#tocBtn .logo { width: 28px; height: 28px; display: block; }
#tocBtn .caret { width: 0; height: 0; border: 5px solid transparent; border-right: 6px solid #999; border-left: 0; transition: transform .15s; }
body:not(.toc-open) #tocBtn .caret { transform: rotate(180deg); }   /* 開著時箭頭指向左（收起方向），收起時指向右 */
#tocBtn .lbl { display: none; font-size: 13px; }
@media (max-width: 800px) { #tocBtn .lbl { display: inline; } }
#searchForm { position: relative; display: flex; align-items: center; gap: 4px; flex: 1 1 140px; min-width: 0; max-width: 360px; }
#searchForm input { flex: 1 1 auto; width: 0; min-width: 80px; padding: 4px 6px; }
#searchStat { font-size: 12px; color: #777; white-space: nowrap; }
/* 書名自動完成：浮在檢索框下方；一行書名，右邊淡字標分類與葉數 */
#sugg { position: absolute; left: 0; top: 100%; margin: 2px 0 0; padding: 4px 0; width: 360px; max-width: calc(100vw - 32px); max-height: 60vh; overflow: auto; list-style: none; background: #fff; border: 1px solid #ccc; border-radius: 6px; box-shadow: 0 4px 12px rgba(0, 0, 0, .12); z-index: 30; font-size: 14px; }
#sugg li { padding: 5px 10px; cursor: pointer; display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
#sugg li .n { color: #999; font-size: 12px; white-space: nowrap; }
#sugg li:hover, #sugg li.active { background: #fff3d6; }
#sugg li mark { background: none; color: #a33; font-weight: bold; }
#pager { display: flex; align-items: center; gap: 4px; flex: none; white-space: nowrap; font-size: 14px; }
#pager button, #searchForm button { padding: 4px 8px; white-space: nowrap; }
#pager #jump { width: 110px; padding: 4px 6px; }
#pager .modes { margin-left: 10px; }
#pager label { display: inline-flex; align-items: center; gap: 2px; }
/* 中等寬度：先收掉站名（圖標仍在，分頁標題也有），擠得下就不折行 */
@media (max-width: 1080px) { header h1 { display: none; } #pager .modes { margin-left: 4px; } }
/* 手機：一行放不下，翻葉那組自己折行，不撐出橫向捲軸 */
@media (max-width: 800px) { #pager { flex-wrap: wrap; flex: 1 1 100%; white-space: normal; row-gap: 6px; } #searchForm { max-width: none; } #pager button { padding: 4px 6px; } #pager #jump { width: 84px; } #pager .modes { margin-left: 0; } }
#main { display: flex; min-height: calc(100vh - 50px); }
/* 目錄抽屜：桌面是左側一欄，可收起；手機上滿版蓋在上面，選了葉就自動收起 */
#side { width: 240px; flex: none; display: flex; flex-direction: column; max-height: calc(100vh - 50px); border-right: 1px solid #ddd; background: #fff; }
body:not(.toc-open) #side { display: none; }
#side .side-bar { display: none; align-items: center; justify-content: space-between; padding: 8px 12px; border-bottom: 1px solid #ddd; font-weight: bold; }
#side .side-bar button { padding: 4px 10px; }
#toc { flex: 1; overflow: auto; padding: 8px; font-size: 14px; }
@media (max-width: 800px) {
  #side { position: fixed; inset: 0; width: 100%; max-height: none; z-index: 20; border-right: 0; }
  #side .side-bar { display: flex; }
}
#toc .hd { cursor: pointer; padding: 4px 6px; border-radius: 4px; user-select: none; }
#toc .hd:hover { background: #f3ede4; }
#toc .tri { display: inline-block; width: 0; height: 0; margin-right: 6px; border: 5px solid transparent; border-left: 6px solid #999; border-right: 0; vertical-align: 1px; transition: transform .15s; }
#toc .open > .hd .tri { transform: rotate(90deg); }
#toc .toc-cat > .hd { font-weight: bold; color: #444; }
#toc .toc-cat.open > .hd { color: #a33; }
#toc .hd .n { float: right; color: #999; font-size: 12px; font-weight: normal; }
#meta .patched { color: #27a; }
#toc .toc-roll.open > .hd { background: #fff3d6; }
#toc .toc-leaves { display: grid; grid-template-columns: repeat(5, 1fr); gap: 3px; margin: 4px 0 6px 18px; }
#toc .leaf { display: block; text-align: center; padding: 2px 0; border: 1px solid #e3dccf; border-radius: 3px; color: #246; text-decoration: none; font-size: 12px; }
body.busy { cursor: progress; }
#toc .toc-roll.single > .hd.leaf { display: block; text-align: left; border: 0; border-radius: 4px; font-size: 14px; color: inherit; padding: 4px 6px; }   /* 單葉卷段：卷名即那一葉，沒有抽屜 */
#toc .toc-roll.single > .hd.leaf.cur { background: #ffe9b0; font-weight: bold; }
#toc .toc-roll.single > .hd.leaf.patched { color: #27a; }
#toc .leaf.cur { background: #ffe9b0; border-color: #e0b84a; font-weight: bold; }
#toc .leaf.plate { color: #999; border-style: dashed; }
#toc .leaf.patched { border-color: #7ab; }
#view { flex: 1; padding: 12px 16px; overflow: auto; }
#meta { font-size: 14px; color: #555; margin-bottom: 8px; }
#meta a { color: #246; }
#leafWrap { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
#scan { max-width: 720px; }
#scan .crop { overflow: hidden; border: 1px solid #ccc; position: relative; min-height: 120px; }
#scan .crop.loading::before { content: ''; position: absolute; inset: 0; background: rgba(250, 246, 240, .7); z-index: 1; }
#scan .crop.loading::after { content: ''; position: absolute; left: 50%; top: 50%; width: 36px; height: 36px; margin: -18px 0 0 -18px; border: 4px solid #ddd; border-top-color: #a33; border-radius: 50%; animation: spin .9s linear infinite; z-index: 2; }
@keyframes spin { to { transform: rotate(360deg); } }
#scan img { display: block; width: 100%; }
#scan .cap { font-size: 13px; color: #777; margin-top: 4px; }
#results { width: 340px; flex: none; overflow: auto; max-height: calc(100vh - 50px); padding: 8px; border-left: 1px solid #ddd; background: #fff; font-size: 13px; }
#results .res-bar { display: flex; align-items: center; justify-content: space-between; padding: 2px 4px 8px; margin-bottom: 4px; border-bottom: 1px solid #ddd; font-weight: bold; }
#results .res-bar button { padding: 2px 8px; }
#results .none { padding: 16px 4px; color: #777; text-align: center; }
#results .hit { padding: 6px 4px; border-bottom: 1px solid #eee; cursor: pointer; }
#results .hit:hover { background: #fff6dd; }
#results .hit .where { color: #777; font-size: 12px; }
#results mark, .cell.hl { background: #ffd54a; }
/* 原盤「字位過密無法显示」：字透明、格子畫斜線，連起來是一條佔位帶；字還在，複製檢索照舊 */
.cell.lost { color: transparent; background: repeating-linear-gradient(45deg, #d8cabb 0 1.5px, transparent 1.5px 5px); cursor: help; }
.cell.lost.hl { background-color: #ffd54a; }
/* 橫排：豎排版式轉九十度。格寬按每欄字數收，窄螢幕上整葉（天頭兩格＋版框 cap 格）也放得下；--cap 由 app.js 設 */
#plain { --cell: min(22px, calc((100vw - 56px) / (var(--cap, 21) + 2.5))); --colw: calc(var(--cell) * 1.6); --tiantou: calc(var(--cell) * 2); color: var(--ink); }
#plain h3 { font-size: 14px; color: #a33; margin: 12px 0 6px; font-weight: normal; }
#plain h3:first-child { margin-top: 0; }
/* 版框只圍住 cap 格；左邊的天頭留給抬頭的字凸出去。每行的字號跟著該行的格寬（密排的行字也縮） */
.hhalf { position: relative; width: calc(var(--tiantou) + var(--cell) * var(--cap) + 4px); }
.hhalf::before { content: ''; position: absolute; top: 0; bottom: 0; left: var(--tiantou); right: 0; border: 2px solid var(--frame); background: #fffdf8; pointer-events: none; }
.hrow { position: relative; height: var(--colw); --main-font: calc(var(--cell) * 0.82); --note-font: calc(var(--cell) * 0.55); }
.hrow.grid::before { content: ''; position: absolute; bottom: 0; right: 2px; left: calc(var(--tiantou) - var(--cell) * var(--gup, 0)); border-bottom: 1px solid var(--grid); }
.hnotch { position: absolute; top: 0; height: 100%; left: calc(var(--tiantou) - var(--cell) * var(--r)); width: calc(var(--cell) * var(--r) + 2px); background: #fffdf8; border-left: 2px solid var(--frame); pointer-events: none; }
.hnotch i { position: absolute; left: -2px; height: 0; }
.hnotch i.t { top: 0; border-top: 2px solid var(--frame); }
.hnotch i.b { bottom: 0; border-bottom: 2px solid var(--frame); }
#plain .vt { writing-mode: horizontal-tb; }
#plain .run { top: 0; left: calc(var(--tiantou) + var(--cell) * var(--at, 0)); width: auto; height: var(--colw); }
#plain .run.note { flex-direction: column; }
#plain .run.note .line { width: auto; height: calc(var(--colw) / 2); }
#plain .run.note .seg { top: 0; left: calc(var(--cell) * var(--off, 0)); }
/* 橫排：漢字字身底邊在基線下約一成，圖片跟著沉一點 */
#plain img.pua-img, #plain .cell img.glyph, #plain .cell span.glyph { vertical-align: -0.12em; }
.modes label { margin-right: 4px; }

/* 一葉：右半葉在右、左半葉在左，中間版心 */
.folio { display: flex; flex-direction: row-reverse; gap: 0; }
/* 版框只圍住 cap 格；上方的天頭留給抬頭的字凸出去，不畫在框裡 */
.half { position: relative; padding: 0; }
.half::before { content: ''; position: absolute; left: 0; right: 0; top: var(--tiantou); bottom: 0; border: 2px solid var(--frame); background: #fffdf8; pointer-events: none; }
.half.a::before { border-left-width: 2px; }     /* 版心兩側與外框同粗 */
.half.b::before { border-right-width: 2px; }
.banxin { width: calc(var(--colw) * 0.9); margin-top: var(--tiantou); border-top: 2px solid var(--frame); border-bottom: 2px solid var(--frame); writing-mode: vertical-rl; font-size: 12px; color: #a33; text-align: center; padding-top: 6px; background: #fffdf8; }
.cols { display: flex; flex-direction: row-reverse; position: relative; height: 100%; }
.col { position: relative; width: var(--colw); }
.col.grid::before { content: ''; position: absolute; left: 0; top: calc(var(--tiantou) - var(--cell) * var(--gup, 0)); bottom: 0; border-left: 1px solid var(--grid); }   /* --gup：兩邊都抬頭的相鄰欄，格線也跟著往上伸進凹槽 */
/* 抬頭：原刻版框在那一欄凸出一個凹槽把凸出去的字圍住（相鄰幾欄同抬就連成一片，高低不齊就成階梯）。
   凹槽是一個背景色方塊蓋掉版框上緣那一段，上緣畫粗線；兩側的粗線只畫到鄰欄凹槽頂為止（i.l / i.r 各管一邊） */
.notch { position: absolute; left: 0; width: 100%; background: #fffdf8; border-top: 2px solid var(--frame); pointer-events: none; }
.notch i { position: absolute; top: -2px; width: 0; }
.notch i.l { left: 0; border-left: 2px solid var(--frame); }
.notch i.r { right: 0; border-right: 2px solid var(--frame); }
/* 字是行內元素、容器直排：每字進位 = 字號 + letter-spacing = 一格，選取複製時字與字之間不會夾空格或換行 */
.run { position: absolute; left: 0; top: calc(var(--tiantou) + var(--cell) * var(--at, 0)); width: var(--colw); }
.vt { writing-mode: vertical-rl; text-orientation: upright; white-space: nowrap; }
.run.text { font-size: var(--main-font); --ls: calc(var(--cell) - var(--main-font)); letter-spacing: var(--ls); line-height: var(--colw); padding-inline-start: calc((var(--cell) - var(--main-font)) / 2); }
.cell { display: inline; }
.run.note { display: flex; flex-direction: row-reverse; }
.run.note .line { position: relative; width: calc(var(--colw) / 2); font-size: var(--note-font); --ls: calc(var(--cell) - var(--note-font)); letter-spacing: var(--ls); line-height: calc(var(--colw) / 2); }
.run.note .seg { position: absolute; left: 0; top: calc(var(--cell) * var(--off, 0)); padding-inline-start: calc((var(--cell) - var(--note-font)) / 2); }
/* 以圖代字：letter-spacing 對圖片不生效，所以用 margin-inline-end 補上同樣的字距，讓圖片也佔滿一格；
   私用區字的圖已在 app.js 裡按墨跡裁成正方形，這裡只管佔位與置中；
   直排裡 vertical-align 管的是左右：baseline 正好讓圖片中心對齊字身中心，middle 會往右偏 */
.cell img.glyph, img.pua-img { height: 1em; width: 1em; object-fit: contain; vertical-align: baseline; margin-inline-end: var(--ls, 0px); }
.cell span.glyph { display: inline-block; height: 1em; width: 1em; vertical-align: baseline; margin-inline-end: var(--ls, 0px); background-repeat: no-repeat; }   /* sprite 大圖裁出來的字，座標由 app.js 算 */
.plate { display: block; max-width: 100%; }
.plate.missing { width: 480px; max-width: 100%; display: flex; align-items: center; justify-content: center; color: #aaa; font-size: 13px; border: 1px dashed #ccc; background: #f5f1ea; }
.empty { color: #aaa; font-size: 14px; padding: 20px; }
#meta .dim { color: #999; font-size: 12px; }

/* 純影像的葉／書：原盤沒有文字，景印本就是內容 */
.scanonly { color: #a33; font-size: 12px; margin-left: 4px; }
.toc-book .hd .scanonly { border: 1px solid #d8b0b0; border-radius: 3px; padding: 0 3px; margin-left: 6px; }
body.scan-fallback #leaf, body.scan-fallback #plain { flex: 0 0 auto; max-width: 240px; }
body.scan-fallback #scan { max-width: min(1000px, 100%); }
.empty.scanonly { color: #a33; }
/* 隱藏的 wiki 模式（#mode=wiki）：Page: 頁的 wikitext，與整頁影印本左右並排 */
body.wiki #plain { flex: 1 1 420px; min-width: 0; }
body.wiki #scan { flex: 1 1 420px; }
.wiki-bar { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; font-size: 14px; margin-bottom: 6px; }
.wiki-bar a { color: var(--frame); }
.wiki-bar .stat { color: var(--frame); font-size: 12px; }
.wiki-src { display: block; width: 100%; box-sizing: border-box; height: 70vh; padding: 8px; font: 13px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--ink); background: #fffdf8; border: 1px solid var(--grid); white-space: pre; overflow: auto; resize: vertical; }
.wiki-bar .dim, .wiki-note { color: #999; font-size: 12px; }
.wiki-note { margin-top: 4px; }
