/* 리더 화면 CSS — reader.html 의 <style> 에서 프레임 안 규칙만 옮기고 앞에 .reader 를 붙였다.
   토큰(:root)·페이지 껍데기(.head/.chg/.hint/.device)는 app.html 이 가진다. 손댈 일이 있으면 reader.html 과 함께 고칠 것. */
.reader .label{font-size:12px; font-weight:800; letter-spacing:.14em}
.reader .sr{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
/* 태블릿 프레임 */
/* 판면 기하는 이 넷에서만 나온다 — 리더 엔진도 computed style 로 같은 값을 읽는다(readGeom).
   두 곳에 같은 숫자를 적으면 1px 만 어긋나도 열이 쪼개지거나 잘린다. */
.reader{position:relative; width:1180px; height:820px; background:var(--ground); border-radius:8px; overflow:hidden; --fs:17px; --lh:32px;
  --colw:480px; --gap:100px; --colh:672px; --rail-l:60px}
.reader:focus:not(:focus-visible){outline:none}
.reader:focus-visible{outline:2px solid var(--indigo); outline-offset:-2px}
/* 상단 바 */
.reader .prog{position:absolute; left:0; top:0; height:3px; background:var(--ch); width:0; z-index:5; transition:width .16s var(--ease-out)}
.reader .tick{position:absolute; top:0; width:1px; height:3px; background:var(--paper); z-index:6}
.reader .bar{height:52px; display:flex; align-items:center; gap:14px; padding:0 8px; border-bottom:1px solid var(--line)}
.reader .bar .ttl{flex:1; text-align:center; font-size:12px; font-weight:700; letter-spacing:.12em; color:var(--ink-2)}
.reader .bar .ic{width:48px; height:48px; display:grid; place-items:center; font-family:var(--serif); font-size:17px; border-radius:10px}
.reader .bar .ic:focus-visible, .reader .bar .pg:focus-visible{outline:2px solid var(--indigo); outline-offset:-2px}
.reader .bar .pg{font-size:12px; font-weight:700; color:var(--ink-2); font-variant-numeric:tabular-nums; letter-spacing:.06em; min-height:36px; padding:0 8px; border-radius:8px}
.reader .bar .pg.back{color:var(--indigo)}
.reader .bar svg{width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round}
/* 펼친 책 */
.reader .book{position:relative; height:768px; touch-action:pan-y; user-select:none; -webkit-user-select:none}
/* 판면: 헤드 16 + 열 672(21행) + 간격 8 + 각주 72 = 768. 마주 보는 두 면의 판면 상단이 같은 높이 */
.reader .rail{position:absolute; left:var(--rail-l); top:16px; width:calc(var(--colw)*2 + var(--gap)); height:var(--colh); overflow:hidden}
.reader .rail.bump-l{animation:bumpL .16s ease-out}
.reader .rail.bump-r{animation:bumpR .16s ease-out}
@keyframes bumpL{50%{transform:translateX(24px)}}
@keyframes bumpR{50%{transform:translateX(-24px)}}
.reader .track{display:flex; height:var(--colh); transition:transform .16s var(--ease-out); will-change:transform}
.reader .spread{flex:none; width:calc(var(--colw)*2 + var(--gap)); height:var(--colh); overflow:hidden; column-width:var(--colw); column-gap:var(--gap); column-fill:auto}
.reader .spacer{break-before:column; height:1px}
.reader .gutter{position:absolute; left:50%; top:0; bottom:0; width:var(--gap); transform:translateX(-50%); pointer-events:none}
.reader .gutter::before{content:""; position:absolute; left:50%; top:0; bottom:0; width:1px; background:linear-gradient(transparent, var(--line) 10%, var(--line) 90%, transparent)}
/* 32px 격자: 판심 40 + 제목 16+40 + 부제 8+24 = 128 = 4행, 소제목 32+32+32 = 3행. 펼친 면 좌우의 글줄이 홈통에서 맞는다 */
.reader .panshim{display:flex; align-items:center; gap:10px; height:40px; border-bottom:1px solid var(--line); margin:0;
  font-size:11.5px; font-weight:700; letter-spacing:.06em; color:var(--ink-2); white-space:nowrap}
.reader .panshim .l{color:var(--ink)}
.reader .panshim .c{flex:1; display:flex; justify-content:center}
.reader h1.epttl{font-family:var(--display); font-weight:400; font-size:30px; line-height:40px; margin:16px 0 0; text-wrap:balance}
.reader .epsub{font-size:13px; line-height:24px; color:var(--ink-2); margin:8px 0 0}
.reader .act > h2{display:flex; align-items:center; justify-content:center; gap:8px; margin:32px 0; height:32px; line-height:32px; font-family:var(--serif); font-size:19px; font-weight:700; letter-spacing:.02em; break-after:avoid}
.reader .prose p{font-family:var(--serif); font-size:var(--fs); line-height:var(--lh); letter-spacing:-.01em; margin:0; text-indent:1em; word-break:keep-all; text-wrap:wrap; orphans:2; widows:2}
.reader .prose p.dlg{margin:0; text-indent:calc(1em - .43em)}
/* 따옴표를 들여쓰기 칸에 걸고 첫 글자는 본문과 정렬 */
.reader .endmark{break-before:avoid}
/* 진하게 + 탭. 인라인이라 세로 padding은 행송을 바꾸지 않고 히트 영역만 키운다 */
.reader .dot{font-style:normal; font-weight:700; text-decoration:underline dotted var(--ch); text-decoration-thickness:1.5px; text-underline-offset:5px; cursor:pointer; padding:10px 4px; margin:0 -4px}
.reader .who{font-weight:700; text-decoration:underline dotted var(--indigo); text-decoration-thickness:1.5px; text-underline-offset:5px; cursor:pointer; padding:10px 4px; margin:0 -4px}
.reader .dot:focus-visible, .reader .who:focus-visible, .reader .pcard:focus-visible, .reader .fn .w:focus-visible, .reader .opt:focus-visible{outline:2px solid var(--indigo); outline-offset:2px; border-radius:2px}
/* 면 전체 도판 */
/* 여는 말 — 이야기 앞의 액자. "이 이야기의 사람들은 진짜인가"를 처음에 밝힌다.
   본문과 섞이면 안 되므로 왼쪽 계선과 작은 글씨로 갈라 둔다 */
/* 제목은 어절로 끊는다 — 본문은 양끝 맞춤 때문에 word-break:normal 을 쓰지만(DECISIONS 50),
   그게 제목까지 내려와 「무 / 엇을」처럼 낱말 가운데가 갈렸다 */
.reader .epttl, .reader .epsub{word-break:keep-all; text-wrap:balance}

/* 낱말 곳간 — 인물 카드가 없는 편의 수확. 오늘 배운 낱말이 곧 수확이다 */
.reader .wordbag{display:grid; gap:7px; margin-top:10px}
.reader .wordbag span{display:block; font-family:var(--serif); font-size:13px; line-height:1.65; color:var(--ink-2)}
.reader .wordbag b{display:inline-block; min-width:74px; font-weight:700; color:var(--ink)}
/* 수확 면의 낱말 곳간은 두 단이다 — 한 칸(500px)을 카드 줄(또는 카드가 없는 까닭)과 나눠 쓰기 때문에
   한 단으로 늘어놓으면 아홉 낱말째부터 「홈으로」 단추 밑으로 기어든다 (실제로 2편에서 겹쳤다) */
.reader .wordbag.tight{grid-template-columns:1fr 1fr; gap:6px 18px}
.reader .wordbag.tight span{font-size:12.5px; line-height:1.6}
.reader .wordbag.tight b{display:inline; min-width:0; margin-right:5px}

.reader .yeoneun{margin:14px 0 18px; padding:11px 0 11px 15px; border-left:2px solid var(--frame)}
.reader .yeoneun .label{display:block; color:var(--frame); margin-bottom:5px}
.reader .yeoneun p{margin:0; font-family:var(--sans); font-size:13.5px; line-height:1.85; color:var(--ink-2)}
.reader .yeoneun b{color:var(--ink); font-weight:700}

.reader figure.plate{break-before:column; break-after:column; break-inside:avoid; height:var(--colh); margin:0; position:relative; background:var(--ground)}
.reader figure.plate img{width:100%; height:100%; object-fit:cover; object-position:50% 30%}
.reader figure.plate figcaption{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0)}
/* 그림이 아직 없는 편 — 남의 편 그림을 보여 주느니 자리를 비워 둔다.
   캡션(삽화 지시문의 첫 문장)을 그 자리에 드러내면 검수자가 무엇이 들어올지 안다 */
.reader figure.plate.nodraw{display:grid; place-items:center; padding:0 64px; text-align:center;
  background:var(--ground); box-shadow:inset 0 0 0 1px var(--line)}
.reader figure.plate.nodraw img{display:none}
.reader figure.plate.nodraw figcaption{position:static; width:auto; height:auto; clip:auto; overflow:visible;
  font-family:var(--serif); font-size:15px; line-height:1.9; color:var(--ink-2)}
.reader figure.plate.nodraw figcaption::before{content:"그림 자리"; display:block; font-family:var(--sans);
  font-size:11px; font-weight:800; letter-spacing:.16em; color:var(--frame); margin-bottom:10px}
/* 캡션은 면 아래 각주 자리에 찍는다 */
.reader .endmark{display:flex; align-items:center; justify-content:center; gap:8px; margin-top:28px; font-size:11.5px; font-weight:700; letter-spacing:.16em; color:var(--ink-2)}
/* 마지막 면: 오늘 만난 사람들 */
.reader .people{break-before:column; break-inside:avoid; height:var(--colh); display:flex; flex-direction:column; justify-content:center; gap:18px}
.reader .people .label{color:var(--ink-2); text-align:center}
.reader .people h3{font-family:var(--display); font-weight:400; font-size:26px; margin:0; text-align:center}
.reader .people .row{display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-top:6px}
.reader .pcard{position:relative; background:var(--paper); border:1px solid var(--line); border-radius:10px; overflow:hidden; cursor:pointer; text-align:left; padding:0}
.reader .pcard .band{height:6px; background:var(--ch)}
.reader .pcard img{width:100%; aspect-ratio:2/2.5; object-fit:cover; object-position:top}
.reader .pcard .nm{position:absolute; right:6px; top:16px; writing-mode:vertical-rl; font-family:var(--display); font-size:15px; letter-spacing:.1em; background:rgba(251,248,241,.84); padding:6px 3px}
.reader .pcard .ln{padding:8px 9px 10px; font-size:12.5px; line-height:1.45; color:var(--ink-2)}
.reader .people .note{text-align:center; font-size:12px; line-height:1.7; color:var(--ink-2)}
/* 학습 면 */
/* 학습 블록은 wrapper 의 padding 으로 머리 공간을 확보한다 — 열 첫머리에서 margin 은 잘리고, 음수 top 의 도장은 앞 열로 넘어간다 */
.reader .blk{break-inside:avoid; padding-top:20px; margin-top:14px}
.reader .hooju, .reader .ifme, .reader .truth{margin-top:0}
.reader .hooju{padding-top:14px; border-top:2px solid var(--ink)}
.reader .hooju .h{font-family:var(--serif); font-size:15.5px; font-weight:700; margin:8px 0 6px}
.reader .hooju p{font-family:var(--serif); font-size:15.5px; line-height:1.85; margin:0}
/* 낫표는 글자 덩이를 감싼다 — 전에는 64px 글리프 하나가 첫 줄 왼쪽 위에 떠 있었다 */
.reader .ifme{position:relative; padding:15px 18px}
.reader .ifme::before, .reader .ifme::after{content:""; position:absolute; width:17px; height:25px;
  border:1.5px solid color-mix(in srgb,var(--ch) 45%,transparent)}
.reader .ifme::before{left:0; top:0; border-right:0; border-bottom:0}
.reader .ifme::after{right:0; bottom:0; border-left:0; border-top:0}
.reader .ifme .q{font-family:var(--serif); font-size:19px; font-weight:600; line-height:1.6}
.reader .ifme p{font-size:12.5px; line-height:1.8; color:var(--ink-2); margin:10px 0 0}
.reader .truth{position:relative; padding:20px 22px; background:color-mix(in srgb,var(--ch) 8%,var(--paper)); border:1px solid var(--frame); outline:1px solid var(--frame); outline-offset:3px}
.reader .truth .h{font-family:var(--serif); font-size:16px; font-weight:700; margin:4px 0 10px}
.reader .truth p{font-size:14px; line-height:1.75; margin:0; orphans:2; widows:2}
/* 학습 펼침면: 왼쪽 = 후주 위·여백의 질문 아래(면 발치), 오른쪽 = 판정 문서가 면을 채운다. 내용이 넘치면 .flow 로 풀어 흐르게 */
.reader .lpage, .reader .rpage{break-before:column; break-inside:avoid; height:var(--colh); padding-top:20px; display:flex; flex-direction:column}
.reader .lpage{justify-content:space-between; gap:24px}
.reader .rpage .blk{flex:1; display:flex; flex-direction:column}
.reader .rpage .truth{flex:1}
.reader .lpage .blk, .reader .rpage .blk{margin-top:0; padding-top:0}
.reader .lpage.flow, .reader .rpage.flow{height:auto; display:block; break-before:auto}
.reader .lpage.flow .blk, .reader .rpage.flow .blk{margin-top:14px; padding-top:20px}
/* 근거 문장 표시 (CSS Highlight API) */
.reader ::highlight(ev){background-color:color-mix(in srgb,var(--seal) 16%,transparent); text-decoration:underline; text-decoration-color:var(--seal); text-decoration-thickness:2px}
.reader .stamp{display:grid; place-items:center; background:var(--seal); color:var(--paper); border-radius:4px; font-family:var(--display); line-height:1.05; text-align:center}
.reader .truth .stamp{position:absolute; right:14px; top:-13px; width:52px; height:52px; font-size:15px; transform:rotate(-6deg)}
/* 가상 면: 읽기 확인 5 + 다음 이야기 1 (다단 흐름 밖, 답해도 재조판 없음) */
.reader .vpage{flex:none; width:calc(var(--colw)*2 + var(--gap)); height:var(--colh); margin-left:var(--gap); display:grid; grid-template-columns:var(--colw) var(--colw); column-gap:var(--gap)}
.reader .qp{padding-top:24px}
.reader .qp .label{display:block; color:var(--ink-2); margin-bottom:26px}
.reader .qp .kind{font-size:11.5px; font-weight:700; letter-spacing:.16em; color:var(--ch); margin-bottom:8px}
.reader .qp .q{display:flex; gap:10px; font-family:var(--serif); font-size:18px; font-weight:700; line-height:1.65; margin:0 0 18px}
.reader .qp .q .no{font-family:var(--serif); color:var(--ch)}
.reader .opt{display:flex; align-items:center; gap:12px; width:100%; min-height:52px; padding:10px 4px; text-align:left; border-bottom:1px solid var(--line); font-size:15px; font-weight:500; line-height:1.5}
.reader .opt .rd{flex:none; width:18px; height:18px; border-radius:50%; border:1.5px solid var(--ink-2)}
.reader .opt .tx{flex:1}
.reader .opt .mark{flex:none; width:24px; height:24px}
.reader .opt[data-s="ok"] .rd{border-color:var(--ok); background:var(--ok); box-shadow:inset 0 0 0 3px var(--paper)}
.reader .opt[data-s="done"]{color:var(--ink-2)}
.reader .mark svg{width:24px; height:24px; fill:none; stroke:var(--seal); stroke-width:2.5; stroke-linecap:round}
@keyframes stamp{from{transform:scale(1.5); opacity:0} to{transform:scale(1); opacity:1}}
.reader .stamped{animation:stamp .3s var(--ease-out) both}
.reader .qp.r{border-left:0}
.reader .dots{display:flex; gap:6px; margin:0 0 22px}
.reader .dots i{width:100%; height:3px; background:var(--line)}
.reader .dots i.ok{background:var(--ok)}
.reader .dots i.cur{background:var(--indigo)}
.reader .qp .wait{font-family:var(--serif); font-size:15px; line-height:1.8; color:var(--ink-2); margin:0 0 14px}
.reader .qp .fb:not(:empty) ~ .wait, .reader .qp .fb.yes ~ .lockmsg{display:none}
.reader .fb{font-size:14px; font-weight:700; line-height:1.6; min-height:24px}
.reader .fb.no{color:var(--seal)}
.reader .fb.yes{color:var(--ok)}
.reader .fb .why{display:block; font-weight:400; color:var(--ink-2); margin-top:4px}
/* 정답 근거: 이야기의 그 문장을 그대로 보여 준다 */
.reader .fb .ev{display:block; margin-top:14px; padding-top:12px; border-top:1px solid var(--line); font-weight:400; color:var(--ink)}
.reader .fb .ev .src{display:block; font-size:11.5px; font-weight:800; letter-spacing:.14em; color:var(--ink-2); margin-bottom:6px}
.reader .fb .ev .para{font-family:var(--serif); font-size:15.5px; line-height:1.85; font-weight:400; color:var(--ink); word-break:keep-all; text-wrap:wrap}
.reader ::highlight(evq){background-color:color-mix(in srgb,var(--seal) 16%,transparent); text-decoration:underline; text-decoration-color:var(--seal); text-decoration-thickness:2px}
.reader .fb .ev .more{display:block; margin-top:12px; padding-top:10px; border-top:1px dashed var(--line)}
.reader .fb .ev .more p{font-size:13.5px; line-height:1.8; color:var(--ink-2); margin:0; font-weight:400}
/* 다음 문제 — 설명 끝에 앉는 단추. 그 장의 색(--ch)을 입어 책 안에 있게 하고,
   폭은 글자만큼만 잡는다. 남색 꽉 찬 단추는 웹 폼처럼 보였고, 글 한 줄은 묻혔다 (Matto) */
.reader .next{display:flex; width:fit-content; margin:20px 0 0 auto;   /* 판 오른쪽에 붙는다 */
  align-items:center; gap:9px;
  padding:11px 20px; border:0; border-radius:10px; background:var(--ch); color:var(--paper);
  font-size:13.5px; font-weight:700; letter-spacing:.01em}
.reader .next b{font-weight:700; opacity:.62; font-variant-numeric:tabular-nums}
.reader .next::after{content:"›"; font-size:17px; line-height:1; opacity:.85}
.reader .goto{display:inline-block; margin-top:12px; padding:9px 14px; border:1px solid var(--indigo); color:var(--indigo); border-radius:10px; font-size:13px; font-weight:700}
.reader .again{display:inline-block; margin-top:14px; padding:10px 14px; border:1px solid var(--indigo); color:var(--indigo); border-radius:10px; font-size:13px; font-weight:700}
.reader .lockmsg{margin-top:26px; font-size:12.5px; color:var(--ink-2); opacity:0; transition:opacity .15s}
.reader .lockmsg.show{opacity:1}
.reader .qp.r .line{margin-top:20px; height:1px; background:var(--line)}
.reader .qp.r .line.gap{margin-top:36px}
/* 마지막 면 (시안 B): 시간의 강이 양면 위를 흐르고, 왼쪽 = 카드·별자리, 오른쪽 = 지도·들춘 다음 책장 */
.reader .vpage.bait{display:block; position:relative}
.reader .bait .river-band{position:absolute; left:0; top:0; width:calc(var(--colw)*2 + var(--gap)); height:150px}
.reader .bait .riv{width:calc(var(--colw)*2 + var(--gap)); height:150px; display:block}
.reader .bait .river{fill:none; stroke:var(--frame); stroke-width:2}
.reader .bait .chap{font-family:var(--sans); font-size:11.5px; font-weight:800; letter-spacing:.14em; fill:var(--ink-2)}
.reader .bait .done{fill:var(--ch)}
.reader .bait .todo{fill:none; stroke:var(--frame); stroke-width:1.5}
.reader .bait .new{fill:var(--seal); stroke:var(--paper); stroke-width:3; filter:drop-shadow(0 0 5px rgba(181,56,43,.55)); transform-box:fill-box; transform-origin:center}
.reader .bait .tx{font-family:var(--sans); font-size:12px; font-weight:700; fill:var(--ink); text-anchor:middle}
.reader .bait .tx.dim{fill:var(--ink-2); font-weight:500}
.reader .bait .tx.big{font-size:13px; font-weight:800}
/* 강에 걸린 오늘 그림 — 세로 비율을 못 박는다.
   높이를 안 주면 세로로 긴 그림(2편의 thumb 는 896×1152)이 그대로 늘어나 172px 에서 시작하는
   아래 두 칸을 덮었다 — 「낱말 곳간」 글씨 위에 그림이 얹혔다.
   66px 이면 그림이 가장 낮게 걸리는 자리(top 94px)에서도 94+66=160 < 172 이라 어느 편에서도 안 겹친다 */
.reader .bait .thumb{position:absolute; width:116px; height:66px; object-fit:cover; border:3px solid var(--paper); box-shadow:var(--sh-float); transform:rotate(-3deg)}
.reader .bait .col{position:absolute; top:172px; width:var(--colw); height:500px}
.reader .bait .col.l{left:0}
.reader .bait .col.r{left:calc(var(--colw) + var(--gap))}
.reader .bait .col .label{display:block; color:var(--ink-2)}
.reader .bait .label b{color:var(--seal); margin-left:4px}
/* 칸 수를 --n 으로 받는다 — 3을 박아 두면 카드 넷째부터 두 줄이 되어 낱말 곳간을 밀어낸다 */
.reader .bait .cards{display:grid; grid-template-columns:repeat(var(--n,3),1fr); gap:14px; margin-top:10px}
.reader .bait .card{position:relative; background:var(--paper); border:1px solid var(--line); border-radius:10px; overflow:hidden; padding:0; text-align:left; cursor:pointer}
.reader .bait .thumb{cursor:pointer}
.reader .bait .card .band{height:6px; background:var(--ch)}
.reader .bait .card img{width:100%; aspect-ratio:2/2.4; object-fit:cover; object-position:top}
.reader .bait .card .nm{position:absolute; right:6px; top:16px; writing-mode:vertical-rl; font-family:var(--display); font-size:15px; letter-spacing:.1em; background:rgba(251,248,241,.84); padding:6px 3px}
/* 수확 왼쪽 칸 — 카드 줄과 별자리를 나란히 놓고, 그 아래를 낱말 곳간에 내준다.
   전에는 세로로 쌓아서 「카드가 있으면 낱말 곳간이 통째로 사라지는」 양자택일이었다 —
   아이는 낱말도 분명히 얻었는데 화면에서 사라졌다 */
.reader .bait .haul{display:grid; grid-template-columns:1fr; gap:14px; align-items:start}
.reader .bait .haul.starred{grid-template-columns:1fr 150px}
.reader .bait .haul .cap{font-size:11.5px; margin-top:4px}
.reader .bait .haul + .label{margin-top:18px}
/* 카드가 없는 편 — 「없음」·「0장」으로 끝내면 아이가 제 잘못이라 느낀다. 왜 없는지를 말한다 */
.reader .bait .nocard{margin-top:6px; font-family:var(--serif); font-size:13px; line-height:1.7; color:var(--ink-2)}
.reader .bait .nocard b{color:var(--ink); font-weight:700}
.reader .bait .nocard + .label{margin-top:16px}
.reader .bait .stars{width:150px; height:94px; display:block}
.reader .bait .edge{stroke:var(--ch); stroke-width:1.5; stroke-dasharray:4 3}
.reader .bait .node{fill:var(--paper); stroke:var(--ch); stroke-width:2}
.reader .bait .cap{font-size:12.5px; line-height:1.6; color:var(--ink-2); margin-top:6px}
.reader .bait .home{position:absolute; left:0; bottom:0; padding:12px 28px; background:var(--seal); color:var(--paper); border-radius:10px; font-size:14px; font-weight:700; letter-spacing:.04em}
.reader .bait .map{display:block; width:var(--colw); height:250px; margin-top:10px; border:1px solid var(--line)}
.reader .bait .map .ctx{fill:#E3DAC6}
.reader .bait .map .land{fill:var(--paper); stroke:var(--frame); stroke-width:1.2}
.reader .bait .map .terr{fill:color-mix(in srgb,var(--ch) 42%,transparent); stroke:var(--ch); stroke-width:2.5}
.reader .bait .map .tname{font-family:var(--display); font-size:46px; fill:var(--ink); text-anchor:middle; paint-order:stroke; stroke:var(--paper); stroke-width:6px}
.reader .bait .map .pin{fill:var(--seal)}
.reader .bait .map .pname{font-family:var(--sans); font-size:24px; font-weight:700; fill:var(--ink); paint-order:stroke; stroke:var(--paper); stroke-width:5px}
.reader .bait .peek{position:absolute; left:0; bottom:-4px; width:var(--colw); height:168px; overflow:hidden}
.reader .bait .peek .page{position:absolute; left:14px; top:24px; width:452px; height:210px; background:var(--paper); border:1px solid var(--line); box-shadow:0 -6px 18px rgba(51,41,31,.18); padding:16px 22px; transform:rotate(-1.2deg)}
.reader .bait .peek .no{font-family:var(--display); font-size:22px; color:var(--ch)}
.reader .bait .peek p{font-family:var(--serif); font-size:14.5px; line-height:1.8; margin:8px 0 0; padding-right:60px}
.reader .bait .peek .stamp{position:absolute; right:18px; top:12px; width:58px; height:58px; font-size:14px; transform:rotate(9deg)}
.reader .bait .peek .fade{position:absolute; left:0; right:0; bottom:0; height:60px; background:linear-gradient(transparent, var(--ground))}
.reader .bait .blur{filter:blur(4.5px); user-select:none}
/* 도착하면 한 번: 강이 그려지고 → 3편이 찍히고 → 그림이 걸리고 → 카드가 오르고 → 영토가 칠해진다 */
@keyframes draw{from{stroke-dashoffset:1} to{stroke-dashoffset:0}}
@keyframes pop{from{transform:scale(0); opacity:0} 70%{transform:scale(1.25)} to{transform:scale(1); opacity:1}}
@keyframes drop{from{opacity:0; transform:rotate(-3deg) translateY(-18px)} to{opacity:1; transform:rotate(-3deg) translateY(0)}}
@keyframes rise{from{opacity:0; transform:translateY(14px)} to{opacity:1; transform:none}}
@keyframes ink{from{fill-opacity:0; stroke-dashoffset:1} to{fill-opacity:1; stroke-dashoffset:0}}
.reader .bait.play .river{stroke-dasharray:1; animation:draw 1.1s var(--ease-out) both}
.reader .bait.play .new{animation:pop .4s var(--ease-out) 1.0s both}
.reader .bait.play .tx.big{animation:rise .3s var(--ease-out) 1.2s both}
.reader .bait.play .thumb{animation:drop .4s var(--ease-out) 1.25s both}
.reader .bait.play .card{animation:rise .35s var(--ease-out) calc(1.4s + var(--i) * .12s) both}
.reader .bait.play .terr{stroke-dasharray:1; animation:ink 1s var(--ease-out) 1.8s both}
.reader .bait.play .peek .page{animation:rise .5s var(--ease-out) 2.4s both}
/* 면 아래 각주 — 그 면에 나온 낱말만, 책의 각주 크기 */
.reader .fn{position:absolute; bottom:0; width:var(--colw); height:72px; padding-top:9px; font-size:12.5px; line-height:1.6; color:var(--ink-2); overflow:hidden; z-index:4}
.reader .fn::before{content:""; position:absolute; left:0; top:0; width:72px; height:1px; background:var(--frame)}
.reader .fn.l{left:var(--rail-l)}
.reader .fn.r{left:calc(var(--rail-l) + var(--colw) + var(--gap))}
.reader .fn .cap{display:block}
.reader .fn .cap b{color:var(--ink); margin-right:6px}
.reader .fn .w{display:inline; padding:8px 0; margin:-8px 0; text-align:left; font:inherit; color:inherit; cursor:pointer; margin-right:14px}
.reader .fn .w b{color:var(--ink); font-weight:700; margin-right:4px}
.reader .fn .w:hover b{text-decoration:underline; text-underline-offset:3px}
/* 툴팁 — 아침신문 방식: 낱말 바로 위 말풍선, 자리 없으면 아래 */
.reader .tip{position:absolute; z-index:30; max-width:320px; background:var(--ink); color:var(--paper); padding:11px 14px; border-radius:8px;
  font-size:13px; line-height:1.55; box-shadow:0 12px 30px rgba(51,41,31,.3); animation:tipPop .13s ease-out}
.reader .tip .tw{display:block; font-family:var(--display); font-size:17px; color:#E8DFCB; margin-bottom:3px}
.reader .tip::after{content:""; position:absolute; left:var(--arrow,50%); bottom:-8px; transform:translateX(-50%); border:8px solid transparent; border-top-color:var(--ink); border-bottom:0}
.reader .tip.below::after{bottom:auto; top:-8px; border-top:0; border-bottom-color:var(--ink)}
.reader .tip.person{display:grid; grid-template-columns:64px 1fr; gap:12px; align-items:start}
.reader .tip.person img{width:64px; aspect-ratio:2/3; object-fit:cover; object-position:top; border-radius:4px}
.reader .tip .rel{display:block; margin-top:6px; padding-top:6px; border-top:1px solid rgba(251,248,241,.22); font-size:11.5px; color:#E8DFCB}
.reader .tip .rel b{color:var(--paper)}
@keyframes tipPop{from{opacity:0; transform:translateY(4px)} to{opacity:1; transform:none}}
/* 글자 크기 팝오버 ('가' 아래) */
.reader .pop{position:absolute; right:10px; top:54px; z-index:40; background:var(--paper); border:1px solid var(--line); border-radius:10px; padding:12px 14px 14px; box-shadow:var(--sh-float)}
.reader .pop .label{display:block; color:var(--ink-2); margin-bottom:8px}
.reader .pop .opts{display:flex; gap:6px}
.reader .pop .opts button{min-width:64px; height:48px; border:1px solid var(--line); border-radius:8px; font-family:var(--serif)}
.reader .pop .opts button[aria-pressed="true"]{border-color:var(--ink); background:var(--ground); font-weight:700}
/* 토스트 · 첫 사용 힌트 · 수확 시트 */
.reader .toast{position:absolute; left:50%; top:62px; transform:translateX(-50%); z-index:40; display:flex; align-items:center; gap:14px; background:var(--ink); color:var(--paper); padding:10px 16px; border-radius:8px; font-size:13px; box-shadow:var(--sh-float); animation:tipPop .15s ease-out}
.reader .toast button{color:#E8DFCB; font-weight:700; text-decoration:underline; text-underline-offset:3px}
.reader .hintov{position:absolute; left:0; top:52px; width:1180px; height:768px; z-index:35; display:grid; grid-template-columns:1fr 1fr; place-items:center; background:rgba(51,41,31,.18); transition:opacity .15s; pointer-events:none}
.reader .hintov.out{opacity:0}
.reader .hintov div{display:grid; justify-items:center; gap:4px; padding:22px 28px 20px; background:var(--paper); border-radius:10px; box-shadow:var(--sh-float); color:var(--ink); font-size:14px; font-weight:700}
.reader .hintov div span{font-family:var(--display); font-size:56px; line-height:1; color:var(--ch)}
.reader .sheet{position:absolute; inset:0; z-index:45; background:rgba(34,30,23,.5); display:grid; place-items:center; animation:tipPop .2s ease-out}
.reader .sheet .panel{width:560px; background:var(--paper); border-radius:12px; padding:28px 30px 24px; box-shadow:0 30px 60px rgba(30,20,10,.35)}
.reader .sheet .label{display:block; text-align:center; color:var(--ink-2); margin-bottom:6px}
.reader .sheet h3{font-family:var(--display); font-weight:400; font-size:24px; margin:0 0 16px; text-align:center}
.reader .hrow{display:flex; align-items:center; gap:12px; padding:11px 2px; border-bottom:1px solid var(--line); font-size:14px; opacity:0; animation:tipPop .25s var(--ease-out) forwards}
.reader .hrow .ic{flex:none; width:34px; height:34px; border-radius:50%; background:var(--ground); display:grid; place-items:center; font-size:11px; font-weight:800; color:var(--ch)}
.reader .hrow img{flex:none; width:34px; height:34px; border-radius:50%; object-fit:cover; object-position:top center}
.reader .hrow .go{margin-left:auto; font-size:12px; font-weight:700; color:var(--indigo); white-space:nowrap}
.reader .sheet .close{display:block; margin:18px auto 0; padding:12px 28px; background:var(--seal); color:var(--paper); border-radius:10px; font-weight:700}
/* 수확 미리보기 타일 */
.reader .sheet .panel.wide{width:760px; padding:24px 26px 22px}
.reader .tiles{display:grid; grid-template-columns:1fr 1fr; gap:12px}
.reader .htile{display:flex; flex-direction:column; gap:8px; padding:12px 14px 12px; background:var(--ground); border-radius:10px; opacity:0; animation:tipPop .25s var(--ease-out) forwards}
.reader .htile .k{font-size:11px; font-weight:800; letter-spacing:.14em; color:var(--ink-2)}
.reader .htile .cap{font-size:12.5px; line-height:1.5; color:var(--ink)}
.reader .htile .mini{width:100%; height:120px; display:block}
.reader .mini .river{fill:none; stroke:var(--frame); stroke-width:2}
.reader .mini .done{fill:var(--ch)}
.reader .mini .todo{fill:none; stroke:var(--line); stroke-width:1.5}
.reader .mini .new{fill:var(--seal); stroke:var(--paper); stroke-width:2; filter:drop-shadow(0 0 4px rgba(181,56,43,.6))}
.reader .mini .tx{font-family:var(--sans); font-size:12px; font-weight:700; fill:var(--ink); text-anchor:middle}
.reader .mini .edge{stroke:var(--ch); stroke-width:1.5; stroke-dasharray:4 3}
.reader .mini .node{fill:var(--paper); stroke:var(--ch); stroke-width:2}
.reader .mini.map .ctx{fill:#E3DAC6}
.reader .mini.map .land{fill:var(--paper); stroke:var(--frame); stroke-width:1.2}
.reader .mini.map .terr{fill:color-mix(in srgb,var(--ch) 40%,transparent); stroke:var(--ch); stroke-width:2}
.reader .mini.map .tname{font-family:var(--display); font-size:46px; fill:var(--ink); text-anchor:middle; paint-order:stroke; stroke:var(--paper); stroke-width:6px}
.reader .mini.map .pin{fill:var(--seal)}
.reader .mini.map .pname{font-family:var(--sans); font-size:26px; font-weight:700; fill:var(--ink); paint-order:stroke; stroke:var(--paper); stroke-width:5px}
.reader .mini.cards{display:flex; justify-content:center; gap:12px}
.reader .mini.cards figure{margin:0; text-align:center; font-size:11.5px; font-weight:700}
.reader .mini.cards img{width:64px; height:88px; object-fit:cover; object-position:top; border-radius:4px; border:1px solid var(--line); margin-bottom:4px}

/* ══ 폰 세로 — 1단 면 넘김 (DECISIONS 27·35: 배율을 줄이지 않는다, 세로 스크롤로 바꾸지 않는다) ══
   판면 넷(--colw/--gap/--colh/--rail-l)만 바꾸면 엔진이 readGeom 으로 되읽어 COLS=1 이 된다.
   여기서 폭·높이를 또 적지 말 것 — 두 곳에 적힌 숫자는 반드시 어긋난다. */
body.portrait .reader{
  --colw:calc(var(--sw, 420px) - 48px);
  --gap:48px;
  --colh:calc(var(--sh, 760px) - 148px);      /* 상단 바 52 + 판면 위 16 + 사이 8 + 각주 72 */
  --rail-l:24px;
  width:100%; height:100%; border-radius:0;
}
body.portrait .reader .book{height:calc(100% - 52px)}
body.portrait .reader .rail{width:var(--colw)}
body.portrait .reader .spread{width:var(--colw)}
body.portrait .reader .gutter{display:none}            /* 1단에는 홈통이 없다 */
body.portrait .reader .fn.r{display:none}              /* 오른쪽 면이 없으니 오른쪽 각주도 없다 */
/* 판심은 한 줄에 안 들어간다. 32px 격자는 마주 보는 두 면을 맞추려던 것이라 1단에서는 뜻이 없다 */
body.portrait .reader .panshim{white-space:normal; height:auto; min-height:40px; padding-bottom:4px}
body.portrait .reader h1.epttl{font-size:26px; line-height:36px}
body.portrait .reader .hintov{width:100%; height:calc(100% - 52px)}
body.portrait .reader .bar{gap:8px; padding:0 4px}
body.portrait .reader .bar .ttl{font-size:11px; letter-spacing:.06em}

/* 문제 면 — 질문 아래에 채점이 쌓이고 면 안에서 세로로 구른다.
   .book 이 touch-action:pan-y 이고 쓸기 판정이 |dx|>|dy| 라 스크롤이 면 넘김으로 새지 않는다 */
body.portrait .reader .vpage{width:var(--colw); grid-template-columns:1fr}
body.portrait .reader .vpage.quiz{grid-auto-rows:min-content; overflow-y:auto; overscroll-behavior:contain}
body.portrait .reader .qp{padding-top:14px}
body.portrait .reader .qp .label{margin-bottom:14px}

/* 수확 면 — 절대 배치를 흐름으로 푼다 */
body.portrait .reader .vpage.bait{overflow-y:auto; overscroll-behavior:contain; padding-bottom:16px}
body.portrait .reader .bait .river-band{position:relative; width:100%}
body.portrait .reader .bait .riv{width:100%; height:auto}
body.portrait .reader .bait .tx.big, body.portrait .reader .bait .thumb{display:none}   /* 제목은 상단 바가, 그림은 본문이 이미 보여 줬다 */
body.portrait .reader .bait .col{position:static; width:auto; height:auto; margin-top:14px}
body.portrait .reader .bait .haul.starred{grid-template-columns:1fr}
body.portrait .reader .bait .stars{width:100%; max-width:200px}
body.portrait .reader .bait .map{width:100%; height:auto; aspect-ratio:480/250}
body.portrait .reader .bait .peek{position:relative; width:100%; margin-top:16px}
body.portrait .reader .bait .home{position:static; display:inline-block; margin-top:16px}
