: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; }
header { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; padding: 8px 16px; background: #fff; border-bottom: 1px solid #ddd; }
header h1 { font-size: 16px; margin: 0; }
#searchForm input { width: 260px; padding: 4px 6px; }
#pager button, #searchForm button { padding: 4px 10px; }
#pager input { width: 130px; padding: 4px 6px; }
#main { display: flex; min-height: calc(100vh - 50px); }
#toc { width: 240px; flex: none; overflow: auto; max-height: calc(100vh - 50px); padding: 8px; border-right: 1px solid #ddd; font-size: 14px; background: #fff; }
#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; }
#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 .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; }
#plain { white-space: pre-wrap; font-size: 17px; line-height: 1.8; color: #333; max-width: 46em; }
#plain img.pua-img { vertical-align: -0.12em; }   /* 橫排：漢字字身底邊在基線下約一成，圖片跟著沉一點 */
#plain h3 { font-size: 14px; color: #a33; margin: 12px 0 4px; border-bottom: 1px solid var(--grid); }
#plain .col-line { padding-left: 1em; text-indent: -1em; }
.modes label { margin-right: 6px; }

/* 一葉：右半葉在右、左半葉在左，中間版心 */
.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: var(--tiantou); bottom: 0; border-left: 1px solid var(--grid); }
/* 字是行內元素、容器直排：每字進位 = 字號 + letter-spacing = 一格，選取複製時字與字之間不會夾空格或換行 */
.run { position: absolute; left: 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-top: 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; padding-top: 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.taitou { color: #7a2; }
.plate { display: block; max-width: 100%; }
.empty { color: #aaa; font-size: 14px; padding: 20px; }
