/* ==========================================================================
   Tích hợp đa văn hóa Đông Tây — digital edition
   Design system: warm paper light / deep ink dark, terracotta accent.
   ========================================================================== */

:root {
  /* ---- palette (light) ---- */
  --paper:      #fdfcfa;
  --paper-2:    #f7f4ee;
  --paper-3:    #efebe2;
  --ink:        #171614;
  --ink-2:      #4a453e;
  --ink-3:      #7d766c;
  --ink-4:      #a8a094;
  --line:       #e4dfd4;
  --line-2:     #d3ccbe;
  --accent:     #9a3d16;
  --accent-2:   #c1663a;
  --accent-bg:  #f6ebe2;
  --gold:       #8a6d2f;
  --shadow-sm:  0 1px 2px rgba(30, 25, 18, .06);
  --shadow:     0 4px 16px -4px rgba(30, 25, 18, .12), 0 1px 3px rgba(30,25,18,.05);
  --shadow-lg:  0 24px 60px -12px rgba(30, 25, 18, .3), 0 8px 20px -8px rgba(30,25,18,.16);

  /* ---- type ---- */
  --serif: 'Lora', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  --sans:  'Be Vietnam Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono:  ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;

  /* ---- reader settings (JS-controlled) ---- */
  --fs: 18px;
  --lh: 1.78;
  --measure: 40rem;
  --body-font: var(--serif);

  /* ---- metrics ---- */
  --topbar-h: 3.25rem;
  --cmp-w: min(34rem, 46vw);
  --rail: 19.5rem;
  --r-sm: 6px;
  --r: 10px;
  --r-lg: 16px;
}

:root[data-theme='dark'] {
  --paper:     #100f0e;
  --paper-2:   #191816;
  --paper-3:   #22201d;
  --ink:       #ece8e1;
  --ink-2:     #b8b1a7;
  --ink-3:     #8e8780;
  --ink-4:     #6a645d;
  --line:      #2b2825;
  --line-2:    #3b3733;
  --accent:    #e79a68;
  --accent-2:  #c97c4e;
  --accent-bg: #2a1f17;
  --gold:      #c9a961;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow:    0 4px 16px -4px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.3);
  --shadow-lg: 0 24px 60px -12px rgba(0,0,0,.7), 0 8px 20px -8px rgba(0,0,0,.4);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme='auto'] {
    --paper:     #100f0e;
    --paper-2:   #191816;
    --paper-3:   #22201d;
    --ink:       #ece8e1;
    --ink-2:     #b8b1a7;
    --ink-3:     #8e8780;
    --ink-4:     #6a645d;
    --line:      #2b2825;
    --line-2:    #3b3733;
    --accent:    #e79a68;
    --accent-2:  #c97c4e;
    --accent-bg: #2a1f17;
    --gold:      #c9a961;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
    --shadow:    0 4px 16px -4px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.3);
    --shadow-lg: 0 24px 60px -12px rgba(0,0,0,.7), 0 8px 20px -8px rgba(0,0,0,.4);
  }
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'kern' 1, 'liga' 1;
}
::selection { background: var(--accent-bg); color: var(--ink); }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 1px; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
img { max-width: 100%; height: auto; }
h1, h2, h3, h4 { font-weight: 600; letter-spacing: -.011em; text-wrap: balance; }

/* ==========================================================================
   Top bar
   ========================================================================== */
.topbar {
  position: sticky; top: 0; z-index: 60;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: .375rem;
  padding: 0 .75rem;
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  backdrop-filter: blur(14px) saturate(1.6);
  -webkit-backdrop-filter: blur(14px) saturate(1.6);
  border-bottom: 1px solid var(--line);
}
.topbar .brand {
  display: flex; align-items: center; gap: .5rem;
  font-family: var(--sans); font-size: .875rem; font-weight: 600;
  color: var(--ink); letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.topbar .brand:hover { text-decoration: none; color: var(--accent); }
.brand-mark {
  flex: none; width: 1.5rem; height: 1.5rem; border-radius: 5px;
  display: grid; place-items: center;
  background: linear-gradient(150deg, var(--accent) 0%, var(--accent-2) 100%);
  color: #fff; font-size: .72rem; font-weight: 700; letter-spacing: 0;
}
.topbar .spacer { flex: 1 1 auto; }
.tools { display: flex; align-items: center; gap: .125rem; }

.iconbtn {
  height: 2.125rem; min-width: 2.125rem; padding: 0 .5rem;
  display: inline-flex; align-items: center; justify-content: center; gap: .375rem;
  border-radius: var(--r-sm); color: var(--ink-2);
  font-size: .8125rem; font-weight: 500;
  transition: background .14s, color .14s;
}
.iconbtn:hover { background: var(--paper-3); color: var(--ink); }
.iconbtn[aria-expanded='true'] { background: var(--paper-3); color: var(--ink); }
.iconbtn svg { width: 1.0625rem; height: 1.0625rem; flex: none; }

.searchtrigger {
  display: flex; align-items: center; gap: .5rem;
  height: 2.125rem; padding: 0 .625rem 0 .5rem;
  min-width: 12rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper-2); color: var(--ink-3);
  font-size: .8125rem; text-align: left;
  transition: border-color .14s, background .14s;
}
.searchtrigger:hover { border-color: var(--line-2); background: var(--paper); }
.searchtrigger svg { width: 1rem; height: 1rem; flex: none; }
.searchtrigger .lbl { flex: 1 1 auto; }
.kbd {
  font-family: var(--sans); font-size: .6875rem; font-weight: 500;
  padding: .0625rem .3125rem; border-radius: 4px;
  border: 1px solid var(--line-2); background: var(--paper);
  color: var(--ink-3); line-height: 1.4;
}

/* reading progress */
.progress {
  position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: transparent; overflow: hidden;
}
.progress i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--accent-2), var(--accent));
  transition: width .1s linear;
}

/* ==========================================================================
   Shell
   ========================================================================== */
.shell { display: flex; align-items: flex-start; }

.rail {
  flex: 0 0 var(--rail); width: var(--rail);
  position: sticky; top: var(--topbar-h);
  height: calc(100vh - var(--topbar-h));
  display: flex; flex-direction: column;
  border-right: 1px solid var(--line);
  background: var(--paper-2);
}
.rail-head { padding: .75rem .75rem .5rem; border-bottom: 1px solid var(--line); }
.filter {
  width: 100%; height: 2rem; padding: 0 .625rem;
  font-family: var(--sans); font-size: .8125rem;
  color: var(--ink); background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.filter::placeholder { color: var(--ink-4); }
.filter:focus { outline: none; border-color: var(--accent-2); }
.rail-scroll { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: .5rem .5rem 3rem; }
.rail-scroll::-webkit-scrollbar { width: 9px; }
.rail-scroll::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 9px; border: 3px solid var(--paper-2); }
.rail-scroll::-webkit-scrollbar-track { background: transparent; }

/* ---- TOC tree ---- */
#toc { font-size: .8125rem; }
#toc .grp { margin-bottom: .125rem; }
#toc .vol-btn {
  width: 100%; display: flex; align-items: center; gap: .5rem;
  padding: .4375rem .5rem; border-radius: var(--r-sm);
  text-align: left; color: var(--ink);
  font-size: .75rem; font-weight: 600; letter-spacing: .02em;
}
#toc .vol-btn:hover { background: var(--paper-3); }
#toc .vol-btn .chev {
  flex: none; width: .875rem; height: .875rem; color: var(--ink-4);
  transition: transform .16s ease;
}
#toc .grp[data-open='false'] .chev { transform: rotate(-90deg); }
#toc .grp[data-open='false'] .vol-body { display: none; }
#toc .vol-n {
  flex: none; font-size: .625rem; font-weight: 700; letter-spacing: .06em;
  color: var(--accent); background: var(--accent-bg);
  padding: .125rem .3125rem; border-radius: 4px;
}
#toc .vol-t { flex: 1 1 auto; min-width: 0; font-weight: 600; }
#toc .vol-body { padding: .125rem 0 .375rem .375rem; margin-left: .5rem; border-left: 1px solid var(--line); }
#toc .part {
  padding: .5rem .5rem .25rem .625rem;
  font-size: .6875rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-4);
}
#toc a {
  display: flex; gap: .4375rem; padding: .3125rem .5rem .3125rem .625rem;
  border-radius: var(--r-sm); color: var(--ink-2); line-height: 1.45;
}
#toc a:hover { background: var(--paper-3); color: var(--ink); text-decoration: none; }
#toc a .n { flex: none; color: var(--ink-4); font-variant-numeric: tabular-nums; font-size: .75rem; }
#toc a.here { background: var(--accent-bg); color: var(--accent); font-weight: 600; }
#toc a.here .n { color: var(--accent-2); }
#toc .empty { padding: 1rem .75rem; color: var(--ink-4); font-size: .8125rem; }
#toc mark { background: transparent; color: var(--accent); font-weight: 700; }

/* ==========================================================================
   Reader
   ========================================================================== */
.reader { flex: 1 1 auto; min-width: 0; display: flex; justify-content: center;
  padding: 2.5rem clamp(1.25rem, 4vw, 3.5rem) 6rem; }
.col-main { flex: 1 1 var(--measure); max-width: var(--measure); min-width: 0; }

.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: .375rem;
  font-family: var(--sans); font-size: .75rem; color: var(--ink-3);
  margin-bottom: 1.25rem;
}
.crumbs a { color: var(--ink-3); }
.crumbs a:hover { color: var(--accent); }
.crumbs .sep { color: var(--ink-4); }
.crumbs .vol { color: var(--accent); font-weight: 600; }

.sec-head { margin-bottom: 2.5rem; }
.sec-head .eyebrow {
  font-family: var(--sans); font-size: .6875rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent);
  margin: 0 0 .625rem;
}
.sec-head h1.sr {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.sec-head .ch-label {
  font-family: var(--sans); font-size: .8125rem; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
  margin: 0 0 .3rem;
}
.sec-head h1 {
  font-family: var(--serif);
  font-size: clamp(1.65rem, 1.1rem + 2vw, 2.3rem);
  line-height: 1.2; margin: 0 0 .875rem; letter-spacing: -.02em;
}
.sec-head .meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: .375rem .875rem;
  font-family: var(--sans); font-size: .8125rem; color: var(--ink-3);
  padding-top: .875rem; border-top: 1px solid var(--line);
}
.sec-head .meta .dot { color: var(--ink-4); }
.sec-head .meta a { color: var(--ink-3); }
.sec-head .meta a:hover { color: var(--accent); }

/* ---- prose ---- */
.prose {
  container-type: inline-size;
  position: relative;
  font-family: var(--body-font);
  font-size: 1rem; line-height: var(--lh);
  color: var(--ink);
}
/* Set as the book sets it: the first line is indented and paragraphs run on
   without a blank line, so the indent alone marks the break. */
.prose p { margin: 0; text-indent: 2.1em; text-align: justify; hyphens: auto; }
/* every paragraph is indented in the print, including after a heading */
/* the scan yields long unbreakable runs (dot leaders, formulas); let them wrap
   rather than push the page sideways */
.prose { overflow-wrap: break-word; }
.prose :is(p, h2, h3, h4) { max-width: 100%; }
.prose h2 {
  font-family: var(--sans);
  font-size: 1.35em; font-weight: 700; line-height: 1.3;
  letter-spacing: .01em; color: var(--ink);
  margin: 2.4em 0 .85em;
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
}
.prose h2:first-child { margin-top: 0; }
/* The file button, pointed at when GitHub could not be reached at all. */
.btn.nudge {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* One title printed on several lines is one title: the chapter title of page
   92 runs "VỀ ĐẠO LÀM NGƯỜI / THEO TRIẾT CỔ ĐÔNG PHƯƠNG / NÓI RIÊNG THEO KINH
   DỊCH", set tight in the book. Each line arrives as its own heading, so the
   space between them has to close up. */
.prose h2 + h2, .prose h3 + h3, .prose h4 + h4 { margin-top: .12em; }
.prose :is(h2, h3).caps { text-transform: uppercase; }
/* part titles and some section heads are centred in the print; which ones is
   read off the scan rather than guessed */
.prose :is(h2, h3, p).mid { text-align: center; text-indent: 0; }
.prose p.mid { margin: 1.15em 0; }
/* A line the print sets in from both margins: a formula, or the explanation
   under a numbered item. Indented, not centred -- the print indents it. */
.prose :is(h2, h3, h4, p).disp {
  text-indent: 0;
  padding-left: 2.2em;
  text-align: left;
}
.prose h3 {
  font-family: var(--sans);
  font-size: .96em; font-weight: 700; line-height: 1.4;
  letter-spacing: .02em; color: var(--ink-2);
  margin: 1.9em 0 .7em;
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
}
.prose h3:first-child { margin-top: 0; }
/* the print's smallest heading step */
.prose h4 {
  font-family: var(--sans);
  font-size: .84375em; font-weight: 700; line-height: 1.45;
  letter-spacing: .02em; color: var(--ink);
  margin: 1.9em 0 .7em;
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
}
.prose h4:first-child { margin-top: 0; }
.prose :is(h4).caps { text-transform: uppercase; }
.prose :is(h4).mid { text-align: center; }
.prose > :last-child { margin-bottom: 0; }

/* ---- one card per printed page ---- */
.pages { display: flex; flex-direction: column; gap: 1.75rem; }
.pg {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: 0 1px 1px rgba(23,22,20,.04), 0 10px 28px -16px rgba(23,22,20,.16);
  padding: 2.1rem clamp(1.1rem, 5.5%, 3rem) 2.6rem;
  /* the printed page is about 1:1.45, so hold that shape unless the text needs
     more room; on a phone the constraint only adds emptiness */
  min-height: 42rem;
}
:root[data-theme="dark"] .pg,
:root[data-theme="auto"] .pg { box-shadow: 0 1px 1px rgba(0,0,0,.3), 0 10px 28px -16px rgba(0,0,0,.5); }
.pg-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  font-family: var(--sans); font-size: .625rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-4);
  padding-bottom: .5rem; margin-bottom: 1.75rem;
  border-bottom: 1px solid var(--line);
  cursor: pointer; user-select: none; transition: color .14s, border-color .14s;
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
}
/* the book alternates the folio between verso and recto */
.pg-head.flip { flex-direction: row-reverse; }
.pg-head .pg-n { font-variant-numeric: tabular-nums; letter-spacing: .06em; flex: none; }
.pg-head .pg-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pg-head:hover { color: var(--accent); border-color: var(--accent-2); }
.pg:target .pg-head, .pg-head:focus-visible { color: var(--accent); border-color: var(--accent); }
.pg .prose > :first-child { margin-top: 0; }
.pg .prose h2:first-child, .pg .prose h3:first-child { margin-top: 0; }
/* the print's smallest heading step */
.prose h4 {
  font-family: var(--sans);
  font-size: .84375em; font-weight: 700; line-height: 1.45;
  letter-spacing: .02em; color: var(--ink);
  margin: 1.9em 0 .7em;
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
}
.prose h4:first-child { margin-top: 0; }
.prose :is(h4).caps { text-transform: uppercase; }
.prose :is(h4).mid { text-align: center; }
/* a paragraph the page break cut in half carries on without an indent */
.prose p.cont { text-indent: 0; }
.prose p.blank-note {
  text-indent: 0; text-align: center; font-family: var(--sans);
  font-size: .75rem; color: var(--ink-4); font-style: italic;
  margin: 3rem 0;
}
@media (max-width: 700px) {
  .pg { min-height: 0; padding: 1.5rem 1.1rem 1.9rem; border-radius: 0;
        border-left: 0; border-right: 0; margin-inline: calc(-1 * var(--reader-pad, 1.1rem)); }
  .pages { gap: 1rem; }
}
@media print {
  .pg { break-after: page; box-shadow: none; border: 0; min-height: 0; padding: 0; }
  .pages { gap: 0; }
}

/* Page break drawn as the printed running head: folio, rule, section title.
   Clicking it opens the scan of that page. */
.folio {
  display: flex; align-items: baseline; gap: .75rem;
  margin: 1.9em 0 1.2em; cursor: pointer; user-select: none;
  font-family: var(--sans); font-size: .625rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-4);
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
  transition: color .14s;
}
.folio:first-child { margin-top: 0; }
.folio .f-n { font-variant-numeric: tabular-nums; letter-spacing: .06em; }
.folio .f-line { flex: 1 1 auto; height: 1px; background: var(--line); }
.folio .f-t { flex: 0 1 auto; min-width: 0; overflow: hidden;
              text-overflow: ellipsis; white-space: nowrap; }
.folio:hover { color: var(--accent); }
.folio:hover .f-line { background: var(--accent-2); }
.folio:target { color: var(--accent); }
.folio:target .f-line { background: var(--accent); }
@media print { .folio { break-before: page; } }

/* page markers: badge inline, moved into the gutter when there is room */
.pgmark {
  display: inline-block; vertical-align: .3em;
  font-family: var(--mono); font-size: .625rem; line-height: 1;
  color: var(--ink-4); padding: .1875rem .3125rem; margin: 0 .25rem;
  border: 1px solid var(--line); border-radius: 4px;
  background: var(--paper-2);
  cursor: pointer; user-select: none; white-space: nowrap;
  transition: color .14s, border-color .14s, background .14s;
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
}
.pgmark::before { content: attr(data-p); }
.pgmark:hover { color: var(--accent); border-color: var(--accent-2); background: var(--accent-bg); }
.pgmark:target { color: var(--accent); border-color: var(--accent); background: var(--accent-bg); }
@media (min-width: 1180px) {
  .pgmark {
    position: absolute; left: -3.75rem; width: 2.5rem;
    margin: 0; text-align: center; vertical-align: baseline;
    border-color: transparent; background: transparent; color: var(--ink-4);
  }
  .pgmark:hover { border-color: var(--line-2); background: var(--paper-2); }
}
a.pref { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- tables reconstructed from the scan's coordinates ---- */
.tbl-wrap { overflow-x: auto; margin: 1.4rem 0; -webkit-overflow-scrolling: touch; }
.tbl-wrap table {
  border-collapse: collapse; width: 100%;
  font-family: var(--sans); font-size: .78em; line-height: 1.45;
  font-variant-numeric: tabular-nums;
}
.tbl-wrap :is(th, td) {
  border: 1px solid var(--line);
  padding: .3em .5em; text-align: left; vertical-align: top;
  white-space: nowrap;
}
.tbl-wrap th { font-weight: 700; background: var(--paper-2); color: var(--ink); }
.tbl-wrap td { color: var(--ink-2); }
.tbl-wrap tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--paper-2) 45%, transparent); }
@media (max-width: 700px) { .tbl-wrap table { font-size: .72em; } }

/* ---- tables lifted from the scan ---- */
.tblwrap {
  margin: 1.75em 0; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--paper-2); overflow: hidden;
}
.tblwrap > pre {
  margin: 0; padding: .875rem 1rem; overflow-x: auto;
  font-family: var(--mono); font-size: .76em; line-height: 1.6;
  white-space: pre; color: var(--ink-2);
}
.tblwrap > pre::-webkit-scrollbar { height: 8px; }
.tblwrap > pre::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 8px; }

/* ---- figures ---- */
figure { margin: 2em 0; }
figure img {
  display: block; margin: 0 auto; border-radius: var(--r-sm);
  background: #fff; padding: .5rem; cursor: zoom-in;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .18s, transform .18s;
}
figure img:hover { box-shadow: var(--shadow); }
figcaption {
  margin-top: .75rem; text-align: center;
  font-family: var(--sans); font-size: .8125rem; line-height: 1.5; color: var(--ink-3);
}
figure.scanfig img { max-width: min(100%, 30rem); }
figure.scanfig figcaption { color: var(--ink-4); font-size: .75rem; }
/* Inverting a figure for dark mode suits line art: the first book's diagrams
   come out of the PDF as black strokes on white. It does not suit a
   photograph. Every page of Sứ Mệnh is one, carrying the print showing through
   from the reverse, and inverted the ink goes dim grey on black while the
   show-through becomes dark mottling -- a formula that reads plainly in light
   mode stopped being readable at all. So the rule follows the source, and
   <body data-book> says which book this is. */
:root[data-theme='dark'] figure img { filter: invert(.92) hue-rotate(180deg) saturate(.7); }
@media (prefers-color-scheme: dark) {
  :root[data-theme='auto'] figure img { filter: invert(.92) hue-rotate(180deg) saturate(.7); }
}
body[data-book='di-lac'] figure img,
figure.mathfig.photo img { filter: none; }

/* ---- pager ---- */
.pager { display: grid; grid-template-columns: 1fr 1fr; gap: .875rem; margin-top: 4rem; }
.pager a {
  display: flex; flex-direction: column; gap: .3125rem;
  padding: .875rem 1rem; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--paper-2); color: var(--ink);
  transition: border-color .16s, background .16s, transform .16s;
}
.pager a:hover { border-color: var(--accent-2); background: var(--paper); text-decoration: none; transform: translateY(-1px); }
.pager .dir {
  display: flex; align-items: center; gap: .3125rem;
  font-family: var(--sans); font-size: .6875rem; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--ink-4);
}
.pager .ttl { font-family: var(--sans); font-size: .84375rem; font-weight: 500; line-height: 1.4; }
.pager a.next { text-align: right; }
.pager a.next .dir { justify-content: flex-end; }
.pager svg { width: .8125rem; height: .8125rem; }
.pager .void { border: 1px dashed var(--line); border-radius: var(--r); opacity: .45; }

.foot {
  margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--line);
  font-family: var(--sans); font-size: .78125rem; line-height: 1.65; color: var(--ink-4);
}
.foot strong { color: var(--ink-3); font-weight: 600; }

/* ==========================================================================
   Home
   ========================================================================== */
.home { max-width: 62rem; margin: 0 auto; padding: clamp(2rem, 5vw, 4.5rem) clamp(1.25rem, 4vw, 2rem) 6rem; }

.hero { display: grid; grid-template-columns: 17rem 1fr; gap: clamp(2rem, 5vw, 3.5rem); align-items: center; }
.hero-cover { position: relative; }
.hero-cover img {
  display: block; width: 100%; height: auto;
  border-radius: var(--r); background: #fff;
  padding: 7px; box-shadow: var(--shadow-lg);
}
.hero-cover figcaption {
  margin-top: .75rem; font-family: var(--sans); font-size: .6875rem;
  letter-spacing: .04em; color: var(--ink-4); text-align: center;
}
.hero-body .eyebrow {
  font-size: .6875rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 .875rem;
}
.hero-body h1 {
  font-family: var(--serif);
  font-size: clamp(1.9rem, 1.1rem + 3vw, 3rem); line-height: 1.14;
  letter-spacing: -.028em; margin: 0 0 1rem;
}
.hero-body .author { font-family: var(--serif); font-size: 1.125rem; color: var(--ink-2); margin: 0 0 .375rem; }
.hero-body .imprint { font-size: .8125rem; color: var(--ink-4); margin: 0 0 1.75rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .625rem; }

.btn {
  display: inline-flex; align-items: center; gap: .4375rem;
  height: 2.5rem; padding: 0 1.125rem; border-radius: var(--r-sm);
  font-family: var(--sans); font-size: .875rem; font-weight: 500;
  transition: background .16s, border-color .16s, transform .16s;
}
.btn svg { width: 1rem; height: 1rem; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-2); text-decoration: none; transform: translateY(-1px); }
:root[data-theme='dark'] .btn-primary { color: #1a1210; }
@media (prefers-color-scheme: dark) { :root[data-theme='auto'] .btn-primary { color: #1a1210; } }
.btn-ghost { border: 1px solid var(--line-2); color: var(--ink); background: var(--paper-2); }
.btn-ghost:hover { border-color: var(--accent-2); color: var(--accent); text-decoration: none; }

.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: 1px;
  margin: 3.5rem 0 0; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
}
.stats div { background: var(--paper); padding: 1rem 1.125rem; }
.stats .v { font-family: var(--serif); font-size: 1.5rem; font-weight: 600; letter-spacing: -.02em; }
.stats .k { font-size: .75rem; color: var(--ink-4); margin-top: .1875rem; }

.resume {
  display: flex; align-items: center; gap: 1rem; margin-top: 1.75rem;
  padding: .9375rem 1.125rem; border-radius: var(--r);
  border: 1px solid var(--accent-2); background: var(--accent-bg);
}
.resume .ic { flex: none; color: var(--accent); }
.resume .tx { flex: 1 1 auto; min-width: 0; }
.resume .k { font-size: .6875rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.resume .v { font-family: var(--sans); font-size: .875rem; font-weight: 500; color: var(--ink); margin-top: .125rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sec-title {
  display: flex; align-items: baseline; gap: .75rem; margin: 4rem 0 1.25rem;
}
.sec-title h2 { font-size: .75rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin: 0; }
.sec-title .rule { flex: 1 1 auto; height: 1px; background: var(--line); }
.sec-title .cnt { font-size: .75rem; color: var(--ink-4); }

.vols { display: grid; gap: .875rem; }
.vol-card {
  display: grid; grid-template-columns: 3.25rem 1fr auto; gap: 1.125rem; align-items: center;
  padding: 1.125rem 1.25rem; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--paper-2); color: var(--ink);
  transition: border-color .16s, background .16s, transform .16s;
}
.vol-card:hover { border-color: var(--accent-2); background: var(--paper); text-decoration: none; transform: translateY(-1px); }
.vol-card .num {
  font-family: var(--serif); font-size: 1.75rem; font-weight: 600; line-height: 1;
  color: var(--accent); text-align: center; letter-spacing: -.02em;
}
.vol-card .t { display: block; font-family: var(--serif); font-size: 1.0625rem;
  line-height: 1.35; font-weight: 600; }
.vol-card .m { display: block; font-size: .78125rem; color: var(--ink-4); margin-top: .3125rem; }
.vol-card .go { color: var(--ink-4); }
.vol-card:hover .go { color: var(--accent); }

.list { display: grid; gap: .375rem; }
.list a {
  display: flex; align-items: baseline; gap: .75rem;
  padding: .625rem .875rem; border-radius: var(--r-sm); color: var(--ink);
  border: 1px solid transparent;
}
.list a:hover { background: var(--paper-2); border-color: var(--line); text-decoration: none; }
.list a .t { flex: 1 1 auto; font-size: .90625rem; line-height: 1.45; }
.list a .p { flex: none; font-size: .75rem; color: var(--ink-4); font-variant-numeric: tabular-nums; }

.note {
  margin-top: 1rem; padding: 1.125rem 1.25rem;
  border: 1px solid var(--line); border-left: 3px solid var(--gold);
  border-radius: var(--r); background: var(--paper-2);
  font-size: .84375rem; line-height: 1.7; color: var(--ink-2);
}
.note p { margin: 0 0 .625rem; }
.note p:last-child { margin: 0; }
.note strong { color: var(--ink); font-weight: 600; }

/* ==========================================================================
   Overlays: search, lightbox, settings, shortcuts
   ========================================================================== */
.scrim {
  position: fixed; inset: 0; z-index: 90;
  background: color-mix(in srgb, var(--ink) 45%, transparent);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: fade .14s ease;
}
@keyframes fade { from { opacity: 0 } }
@keyframes pop { from { opacity: 0; transform: translateY(-6px) scale(.99) } }

/* ---- search ---- */
.searchwrap { position: fixed; inset: 0; z-index: 91; display: flex; justify-content: center;
  padding: clamp(2rem, 8vh, 6rem) 1rem 1rem; pointer-events: none; }
.searchbox {
  pointer-events: auto;
  width: min(44rem, 100%); max-height: min(34rem, 100%);
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--line-2); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg); overflow: hidden;
  animation: pop .16s cubic-bezier(.2,.8,.3,1);
}
.searchbox .top { display: flex; align-items: center; gap: .625rem; padding: .8125rem .9375rem;
  border-bottom: 1px solid var(--line); }
.searchbox .top svg { width: 1.125rem; height: 1.125rem; color: var(--ink-4); flex: none; }
#q { flex: 1 1 auto; min-width: 0; border: 0; background: none; color: var(--ink);
  font-family: var(--sans); font-size: 1rem; }
#q::placeholder { color: var(--ink-4); }
#q::-webkit-search-cancel-button, .filter::-webkit-search-cancel-button { display: none; }
#q:focus { outline: none; }
.hint { padding: .5rem .9375rem; font-size: .75rem; color: var(--ink-4);
  border-bottom: 1px solid var(--line); background: var(--paper-2); }
.hits { flex: 1 1 auto; overflow-y: auto; padding: .375rem; overscroll-behavior: contain; }
.hit {
  display: block; padding: .625rem .75rem; border-radius: var(--r-sm); color: var(--ink);
  border: 1px solid transparent;
}
.hit:hover, .hit.sel { background: var(--paper-2); border-color: var(--line); text-decoration: none; }
.hit.sel { border-color: var(--accent-2); }
.hit .hv { font-size: .6875rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--accent); }
.hit .hh { font-size: .875rem; font-weight: 600; margin-top: .125rem; line-height: 1.4; }
.hit .hh .pg { font-weight: 400; color: var(--ink-4); font-size: .78125rem; }
.hit .hs { font-family: var(--body-font); font-size: .84375rem; line-height: 1.6; color: var(--ink-2); margin-top: .25rem; }
.hit mark { background: var(--accent-bg); color: var(--accent); font-weight: 600; border-radius: 3px; padding: 0 .1em; }
.searchbox .btm { display: flex; gap: 1rem; padding: .5rem .9375rem; border-top: 1px solid var(--line);
  background: var(--paper-2); font-size: .6875rem; color: var(--ink-4); }
.searchbox .btm span { display: flex; align-items: center; gap: .3125rem; }

/* ---- lightbox ---- */
.lightbox { position: fixed; inset: 0; z-index: 95; display: flex; flex-direction: column;
  background: color-mix(in srgb, var(--ink) 92%, #000); animation: fade .14s ease; }
.lb-bar { display: flex; align-items: center; gap: .5rem; padding: .625rem .875rem;
  color: #e8e4dd; font-size: .8125rem; }
.lb-bar .t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-bar button { width: 2.125rem; height: 2.125rem; border-radius: var(--r-sm); color: #e8e4dd;
  display: grid; place-items: center; }
.lb-bar button:hover { background: rgba(255,255,255,.14); }
.lb-bar svg { width: 1.0625rem; height: 1.0625rem; }
.lb-stage { flex: 1 1 auto; overflow: auto; display: grid; place-items: center; padding: 0 1rem 1.25rem; }
.lb-stage img { background: #fff; border-radius: 4px; box-shadow: var(--shadow-lg);
  transform-origin: center; transition: transform .18s ease; }
.lb-stage.zoom { place-items: start center; cursor: grab; }
.lb-stage.zoom img { transform: scale(2.1); transition: none; }

/* ---- popover panels (settings / shortcuts) ---- */
.pop {
  position: fixed; z-index: 92; top: calc(var(--topbar-h) + .375rem); right: .75rem;
  width: min(20rem, calc(100vw - 1.5rem));
  background: var(--paper); border: 1px solid var(--line-2); border-radius: var(--r);
  box-shadow: var(--shadow-lg); padding: .875rem;
  animation: pop .14s cubic-bezier(.2,.8,.3,1);
}
.pop h3 { font-size: .6875rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-4); margin: 0 0 .625rem; }
.pop .row { display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  padding: .5rem 0; }
.pop .row + .row { border-top: 1px solid var(--line); }
.pop .row .lb { font-size: .8125rem; color: var(--ink-2); }
.seg { display: flex; gap: 2px; padding: 2px; background: var(--paper-3); border-radius: var(--r-sm); }
.seg button {
  padding: .3125rem .5625rem; border-radius: 5px; font-size: .75rem; font-weight: 500;
  color: var(--ink-3); transition: background .14s, color .14s;
}
.seg button:hover { color: var(--ink); }
.seg button[aria-pressed='true'] { background: var(--paper); color: var(--ink); box-shadow: var(--shadow-sm); }
.stepper { display: flex; align-items: center; gap: .125rem; }
.stepper button { width: 1.75rem; height: 1.75rem; border-radius: 5px; color: var(--ink-2);
  display: grid; place-items: center; font-size: .9375rem; }
.stepper button:hover { background: var(--paper-3); color: var(--ink); }
.stepper .val { min-width: 2.5rem; text-align: center; font-size: .78125rem; color: var(--ink-3);
  font-variant-numeric: tabular-nums; }

.keys { display: grid; gap: .4375rem; }
.keys .k { display: flex; align-items: center; justify-content: space-between; gap: 1rem; font-size: .8125rem; }
.keys .k span { color: var(--ink-2); }

/* goto page */
.goto { display: flex; gap: .375rem; }
.goto input {
  flex: 1 1 auto; height: 2rem; padding: 0 .625rem; min-width: 0;
  font-family: var(--sans); font-size: .8125rem; color: var(--ink);
  background: var(--paper-2); border: 1px solid var(--line); border-radius: var(--r-sm);
}
.goto input:focus { outline: none; border-color: var(--accent-2); }
.goto button { height: 2rem; padding: 0 .75rem; border-radius: var(--r-sm);
  background: var(--accent); color: #fff; font-size: .8125rem; font-weight: 500; }
:root[data-theme='dark'] .goto button { color: #1a1210; }

/* ==========================================================================
   Mobile
   ========================================================================== */
.mobilebar { display: none; }

@media (max-width: 1023px) {
  :root { --rail: 18rem; }
  .rail {
    position: fixed; top: var(--topbar-h); bottom: 0; left: 0; z-index: 80;
    transform: translateX(-101%); transition: transform .22s cubic-bezier(.2,.8,.3,1);
    box-shadow: var(--shadow-lg);
  }
  .rail.open { transform: none; }
  .reader { padding: 1.75rem 1.25rem 5.5rem; }
  .prose p { text-align: left; hyphens: none; }
  .searchtrigger { min-width: 0; padding: 0; width: 2.125rem; justify-content: center; }
  .searchtrigger .lbl, .searchtrigger .kbd { display: none; }
  .hero { grid-template-columns: 1fr; gap: 2rem; }
  .hero-cover { max-width: 11rem; }
  .pager { grid-template-columns: 1fr; }
  .pager .void { display: none; }
  .mobilebar {
    display: flex; align-items: center; gap: .5rem;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    padding: .5rem .75rem; padding-bottom: max(.5rem, env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--paper) 88%, transparent);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-top: 1px solid var(--line);
  }
  .mobilebar a, .mobilebar button {
    height: 2.25rem; padding: 0 .75rem; border-radius: var(--r-sm);
    display: inline-flex; align-items: center; gap: .375rem;
    font-size: .8125rem; font-weight: 500; color: var(--ink-2);
    border: 1px solid var(--line); background: var(--paper-2);
  }
  .mobilebar a:hover { text-decoration: none; }
  .mobilebar .grow { flex: 1 1 auto; justify-content: center; }
  .mobilebar svg { width: .9375rem; height: .9375rem; }
  .mobilebar .off { opacity: .4; pointer-events: none; }
}
@media (min-width: 1024px) { #menubtn { display: none; } }

/* ==========================================================================
   Print
   ========================================================================== */
@media print {
  .topbar, .rail, .pager, .mobilebar, .scrim, .searchwrap, .lightbox, .pop { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .reader { padding: 0; display: block; }
  .col-main { max-width: none; }
  .prose h2 { break-after: avoid; }
  figure, .tblwrap { break-inside: avoid; }
  .pgmark { position: static; border: 0; color: #888; }
  .folio { color: #888; }
  a { color: #000; text-decoration: none; }
}


/* ---- library landing: the site holds more than one book ---- */
.lib { max-width: 44rem; margin: 0 auto; padding: 4rem clamp(1.1rem, 5vw, 2rem) 5rem; }
.lib-head { margin-bottom: 3rem; }
.lib-eyebrow {
  font-family: var(--sans); font-size: .6875rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--accent);
  margin: 0 0 .75rem;
}
.lib-head h1 {
  font-family: var(--serif); font-size: clamp(1.9rem, 6vw, 2.6rem);
  font-weight: 600; letter-spacing: -.02em; line-height: 1.1;
  margin: 0 0 .9rem; color: var(--ink);
}
.lib-lead {
  font-family: var(--serif); font-size: 1.0625rem; line-height: 1.65;
  color: var(--ink-2); margin: 0; max-width: 34rem;
}
.lib-card {
  display: block; text-decoration: none; color: inherit;
  background: var(--paper); border: 1px solid var(--line); border-radius: 8px;
  padding: 1.5rem 1.6rem; margin-bottom: 1rem;
  transition: border-color .16s, box-shadow .16s, transform .16s;
}
.lib-card:hover {
  border-color: var(--accent-2);
  box-shadow: 0 1px 2px rgba(23,22,20,.04), 0 12px 28px -18px rgba(23,22,20,.22);
  transform: translateY(-1px);
}
.lib-t {
  font-family: var(--serif); font-size: 1.3rem; font-weight: 600;
  line-height: 1.25; color: var(--ink); margin-bottom: .2rem;
}
.lib-s { font-family: var(--serif); font-size: .95rem; color: var(--ink-2); font-style: italic; }
.lib-meta {
  font-family: var(--sans); font-size: .8125rem; font-weight: 500;
  color: var(--accent); margin-top: .7rem;
}
.lib-imp { font-family: var(--sans); font-size: .75rem; color: var(--ink-4); margin-top: .15rem; }
.lib-note {
  font-family: var(--sans); font-size: .8125rem; line-height: 1.55;
  color: var(--ink-3); margin-top: .7rem; padding-top: .7rem;
  border-top: 1px solid var(--line);
}
.lib-foot {
  font-family: var(--sans); font-size: .8125rem; line-height: 1.6;
  color: var(--ink-4); margin-top: 2.5rem; padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.lib-foot a { color: var(--link); }


/* ---- panels: a page that prints several figures as a framed grid ---- */
.panels {
  display: grid;
  grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr));
  border: 1px solid var(--ink-4);
  margin: 1.6rem 0;
}
.panels .panel-cell {
  margin: 0;
  padding: 1rem .9rem;
  border: 1px solid var(--ink-4);
  margin: -0.5px;                 /* collapse the shared rules */
  display: flex; flex-direction: column; gap: .75rem;
}
.panels .panel-cell img {
  max-width: min(100%, 9rem); height: auto; margin: 0 auto;
  cursor: zoom-in;
}
.panels .panel-cell figcaption {
  margin: 0; text-align: left; font-family: var(--sans);
  font-size: .78em; line-height: 1.5; color: var(--ink-2);
}
@media (max-width: 640px) {
  .panels { grid-template-columns: 1fr; }
}


/* A heading the print sets on one line is kept on one line by shrinking it to
   the measure, never by breaking it — and never past its own size: `1em` here
   would mean the *parent's* size, which is larger than h3 and h4 and smaller
   than h2, so one shared rule got all three wrong.

   --n is the character count. 0.72 is the per-character advance budgeted for:
   measured in Chrome over all 849 such headings, the widest single string needs
   0.669 em (Vietnamese capitals with diacritics are wide, and each string's own
   average differs), so 0.72 leaves about 6% headroom, webfont or fallback.

   The floor is the same for all three so that the character budget the build
   applies is achievable at every level; an h2 with a higher floor could never
   reach one line at the lengths h3 and h4 manage.

   Two deliberate limits. The size has a floor, because on a narrow phone the
   fit for a long caption works out at 5.6px — one line, unreadable. And there
   is no `nowrap`: the computed size already makes the line fit, so if the
   estimate is ever short the text wraps, which keeps every word. Clipping it
   to one line with an ellipsis would drop words instead. */
.prose :is(h2, h3, h4).oneline { max-width: 100%; }
.prose h2.oneline { font-size: max(.62em, min(1.35em,   calc(100cqw / (var(--n) * 0.72)))); }
.prose h3.oneline { font-size: max(.62em, min(.96em,    calc(100cqw / (var(--n) * 0.72)))); }
.prose h4.oneline { font-size: max(.62em, min(.84375em, calc(100cqw / (var(--n) * 0.72)))); }

/* ---- a list the print sets in aligned columns ----
   No rules and no shading: on the page it is running text that happens to line
   up, and the alignment is what makes it readable. The narrow columns hold a
   label or a run of numbers and must not wrap; the last one carries the prose
   and takes the rest of the measure. */
.prose .cols-wrap { overflow-x: auto; margin: 1.15em 0; }
.prose table.cols {
  border-collapse: collapse;
  width: 100%;
  font-size: inherit;
}
.prose table.cols td {
  border: 0;
  padding: .12em 1.25em .12em 0;
  vertical-align: baseline;
  text-align: left;
  text-indent: 0;
}
.prose table.cols td.nw { white-space: nowrap; width: 1%; }
.prose table.cols td:last-child { padding-right: 0; }
@media (max-width: 560px) {
  .prose table.cols td { padding-right: .7em; }
}

/* Where the print leaves a blank line, leave one. Body paragraphs run on with
   only an indent, exactly as the book sets them, so the indent alone cannot
   show the groupings the print marks by skipping a line -- the planes of the
   body on page 6 of Sứ Mệnh, each followed by its numbered members. Measured
   against each page's own paragraph breaks, since the type size varies. */
.prose p.sp, .prose .cols-wrap.sp { margin-top: .85em; }
/* A sentence the print frames. tools/boxes.py measures the rectangle off the
   page image, so this appears only where the book actually drew one. The rule
   is hairline as it is on the page, and the text is centred inside it. */
.boxed {
  margin: 1.6em auto;
  padding: .9em 1.1em;
  border: 1px solid var(--ink-3);
  max-width: 90%;
  background: var(--paper);
}
.boxed > :first-child { margin-top: 0; }
.boxed > :last-child { margin-bottom: 0; }
.boxed.mid, .boxed.mid > p, .boxed.mid > h2, .boxed.mid > h3, .boxed.mid > h4 {
  text-align: center;
}
.boxed > p {
  text-indent: 0;
  line-height: 1.65;
  letter-spacing: .01em;
}
@media (max-width: 560px) {
  .boxed { max-width: 100%; padding: .75em .8em; }
}
@media print {
  .boxed { border-color: #000; background: none; }
}

/* A formula display, cut out of the page scan. Both engines read mathematics
   as word soup, and a structure of overlines, nested braces and subscripts
   cannot be put right by correcting words -- so what the book printed stands
   in its place. Centred, at its own size, never wider than the measure. */
.mathfig {
  margin: 1.4em 0;
  text-align: center;
}
.mathfig img {
  max-width: 100%;
  height: auto;
  background: #fff;
  border-radius: 2px;
}
/* A photographic crop keeps its white plate in dark mode -- see the note on
   `figure img` above -- with a little padding so the ink is not flush to the
   edge, and a hairline so the plate does not glare against a dark page. */
.mathfig img { padding: .35rem; }
:root[data-theme='dark'] .mathfig img { box-shadow: 0 0 0 1px rgba(0, 0, 0, .5); }
@media (prefers-color-scheme: dark) {
  :root[data-theme='auto'] .mathfig img { box-shadow: 0 0 0 1px rgba(0, 0, 0, .5); }
}
/* the fallback when a page has no scan to cut from */
.mathtext {
  font-family: var(--mono);
  font-size: .9em;
  text-indent: 0;
  white-space: pre-wrap;
}

.prose table.cols.tight td { padding-right: .55em; font-size: .9em; }
.prose table.cols.tight td:last-child { padding-right: 0; }

/* Where the print rules its table, rule it. The OCR layer records no rules, so
   the test is the shape: three or more columns, every cell filled, every cell
   short. `mid` follows the print too -- page 74 centres its cells, which is how
   the columns were found in the first place. */
/* The print sets a table's caption under it, so the caption goes under it. */
.prose table.cols caption {
  caption-side: bottom;
  padding-top: .7rem;
  font-family: var(--sans);
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--ink-3);
  text-align: center;
}
.prose .tbl-wrap table caption {
  caption-side: bottom;
  padding-top: .7rem;
  font-family: var(--sans);
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--ink-3);
  text-align: center;
}
.prose table.cols th {
  font-weight: 600;
  text-align: center;
  padding: .35em .8em .35em 0;
}
/* A head set over a borderless table -- LỤC NGHI over two columns of page
   525 -- is ruled under, as the print rules it. */
.prose table.cols:not(.ruled) th { border-bottom: 1px solid var(--ink-3); }
.prose table.cols.ruled th {
  border: 1px solid var(--ink-3);
  padding: .4em .8em;
}
.prose table.cols.ruled { width: auto; margin: 0 auto; }
.prose table.cols.ruled td {
  border: 1px solid var(--ink-3);
  padding: .34em .8em;
  width: auto;
}
/* A ruled cell wraps like any other. Holding every one of them on one line was
   right while the only ruled tables were short ones; a table read off the
   print's rules can hold a phrase in a cell -- page 256 sets six columns of
   Kinh, each a name over a code over an hour -- and nowrap made it four times
   the width of the page. Cells the renderer has marked short stay on one
   line. */
.prose table.cols.ruled td.nw { width: auto; white-space: nowrap; }
/* Each line of a cell on its own line. This has to cover th as well as td:
   in a header cell the spans stayed inline and ran together -- "KHÔNHẠ2NGOẠI"
   -- which made the column three times as wide as the print sets it and pushed
   page 703's table 420px past the reading column. */
.prose table.cols :is(td, th) .ln { display: block; white-space: nowrap; }

/* A table wider than the reading column is fitted to it rather than left to
   scroll sideways: first its cells give up some padding, then the table itself
   is scaled down. The print sets these tables in smaller type than its body for
   the same reason, so scaling keeps the proportions the print chose. Below the
   floor in app.js the scroll comes back -- a nine-column table of stacked words
   cannot be made both to fit and to be read. */
.prose .fit table.cols.ruled :is(td, th) { padding-left: .34em; padding-right: .34em; }
.prose .fit table.cols :is(td, th) { padding-right: .55em; }
.prose .fit table { zoom: var(--fit, 1); }
.prose .fit > pre { zoom: var(--fit, 1); }
/* Still too wide at the floor: let the lines inside a cell wrap after all. The
   print never breaks "Dũng Tuyền" across two lines, so this is a last resort --
   nine tables of Tập 1 need it, none of Sứ Mệnh. */
/* Specific enough to beat `.cols.ruled td.nw`, which is what holds a short
   cell on one line. */
.prose .fit-wrap table :is(td, th),
.prose .fit-wrap table.cols.ruled :is(td, th).nw,
.prose .fit-wrap table.cols :is(td, th) .ln { white-space: normal; }
/* A cell holding one long unbroken token keeps the table wide even at the
   floor -- one table of Sứ Mệnh was left 68px past the column that way. Only
   tables already scaled as small as they may go break inside a word. */
.prose .fit-wrap table :is(td, th) { overflow-wrap: anywhere; }
@media print {
  .prose .fit table, .prose .fit > pre { zoom: 1; }
}
.prose table.cols.ruled td:last-child { padding-right: .8em; }
.prose table.cols.mid td { text-align: center; }
/* Columns of equal width, as the print spaces them. Sized to their content the
   table dropped its slack into the last column, and page 484's HỢI stood apart
   from the eleven Chi before it. */
.prose table.cols.even { table-layout: fixed; }
.prose table.cols.even :is(td, th),
.prose table.cols.even :is(td, th).nw {
  width: auto;                  /* `td.nw { width: 1% }` collapsed every column */
  padding-left: .2em; padding-right: .2em;
}
.prose .cols-wrap:has(table.ruled) { text-align: center; }
.panels .panel-cell figcaption.mid { text-align: center; }

/* ---- proofreading mode ----
   The corrections a reader makes are theirs alone until they export the file,
   so nothing here suggests the text has changed for anyone else: a quiet
   underline where a word was corrected, and a mode that has to be turned on. */
#fixbtn { position: relative; }
#fixbtn[aria-pressed="true"] { color: var(--accent); background: var(--accent-bg); }
#fixbtn .fixcount {
  position: absolute; top: -2px; right: -2px; min-width: 15px; height: 15px;
  padding: 0 3px; border-radius: 8px; background: var(--accent); color: #fff;
  font-family: var(--sans); font-size: .5625rem; font-weight: 700;
  line-height: 15px; text-align: center;
}
body.fixmode .prose { cursor: text; }
body.fixmode .prose p:hover,
body.fixmode .prose :is(h2, h3, h4):hover,
body.fixmode .prose td:hover { background: var(--accent-bg); }
.prose mark.fixed {
  background: none; color: inherit;
  border-bottom: 1px dashed var(--accent);
}

.fixpop {
  position: absolute; z-index: 96; width: 22rem; max-width: calc(100vw - 1rem);
  padding: .875rem; border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--paper); box-shadow: var(--shadow-lg);
  font-family: var(--sans); font-size: .8125rem;
}
.fixpop h3 {
  font-size: .6875rem; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-4); margin: 0 0 .625rem;
}
.fixpop-ctx {
  font-family: var(--serif); font-size: .8125rem; color: var(--ink-2);
  background: var(--paper-3); border-radius: var(--r-sm); padding: .4rem .5rem;
  margin-bottom: .625rem;
}
.fixpop-lab { display: block; font-size: .6875rem; color: var(--ink-3); margin-bottom: .25rem; }
.fixpop-in {
  width: 100%; padding: .4375rem .5rem; border: 1px solid var(--line-2);
  border-radius: var(--r-sm); background: var(--paper); color: var(--ink);
  font-family: var(--serif); font-size: .9375rem;
}
.fixpop-in:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.fixpop-scope { margin: .5625rem 0 .75rem; display: grid; gap: .1875rem; }
.fixpop-scope label {
  display: flex; align-items: center; gap: .375rem;
  font-size: .75rem; color: var(--ink-2);
}
.fixpop-n { color: var(--ink-4); }
.fixpop-act { display: flex; gap: .375rem; }

.fixpanel { width: min(22rem, calc(100vw - 1.5rem)); }
.fixpanel .pop-note {
  font-size: .6875rem; line-height: 1.55; color: var(--ink-3); margin: 0 0 .75rem;
}
.fixpanel .pop-note code { font-family: var(--mono); font-size: .625rem; }
.fixlist { max-height: 42vh; overflow-y: auto; display: grid; gap: .3125rem; }
.fixempty { font-size: .75rem; color: var(--ink-4); margin: .1875rem 0; }
.fixrow {
  position: relative; padding: .375rem 2rem .375rem .5rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--paper-3);
}
.fixrow-main { font-family: var(--serif); font-size: .875rem; }
.fixwrong { text-decoration: line-through; color: var(--ink-4); }
.fixarrow { color: var(--ink-4); margin: 0 .3125rem; }
.fixright { color: var(--ink); font-weight: 500; }
.fixrow-meta { font-size: .625rem; color: var(--ink-4); margin-top: .0625rem; }
.fixdel { position: absolute; top: .25rem; right: .1875rem; width: 26px; height: 26px; }
.fixpanel-act { display: flex; flex-wrap: wrap; gap: .375rem; margin-top: .75rem; }
.fixcopy.ok { color: var(--accent); }
@media (max-width: 560px) {
  .fixpop { width: calc(100vw - 1rem); left: .5rem !important; }
}

/* ---- the printed page, beside the correction ----
   Docked rather than floating, because the point is to read the two side by
   side; on a narrow screen it takes the lower half instead. */
.cmp {
  position: fixed; z-index: 94; top: var(--topbar-h); right: 0; bottom: 0;
  width: var(--cmp-w);
  display: flex; flex-direction: column;
  background: var(--paper); border-left: 1px solid var(--line-2);
  box-shadow: var(--shadow-lg);
}
.cmp-bar {
  display: flex; align-items: center; gap: .125rem;
  padding: .375rem .5rem; border-bottom: 1px solid var(--line);
  font-family: var(--sans); font-size: .6875rem; font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
}
.cmp-sp { flex: 1; }
.cmp-bar .iconbtn { width: 28px; height: 28px; }
.cmp-slot:empty { display: none; }
/* The scan keeps its share of the column: the point of the mode is to see it.
   The shares are of the column, not the window, because below 1100px the
   column docks along the bottom at 46vh and shares in vh would overflow it.
   `flex: 1 0 45%` means the scan cannot be shrunk below 45% of the column; the
   correction box scrolls instead, and the list stays folded until asked for. */
.cmp-slot {
  flex: 0 1 auto; min-height: 0; overflow-y: auto;
  border-bottom: 1px solid var(--line);
}
.cmp-list { flex: 0 0 auto; border-bottom: 1px solid var(--line); }
.cmp-list summary {
  cursor: pointer; padding: .5rem .875rem;
  font-family: var(--sans); font-size: .625rem; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-4);
}
.cmp-list summary:hover { color: var(--accent); }
.cmp-list[open] { max-height: 34%; overflow-y: auto; }
.cmp-list .fixpanel h3 { display: none; }
.cmp-box {
  position: relative; flex: 1 0 45%; min-height: 0; overflow: auto;
  background: var(--paper-3); scroll-behavior: smooth;
}
/* In the column they are part of it: no shadow, no floating, full width. */
.fixpop.inpanel, .fixpanel.inpanel {
  position: static; width: auto; max-width: none;
  border: 0; border-radius: 0; box-shadow: none; background: none;
  animation: none;
}
.fixpanel.inpanel { padding: .75rem .875rem; }
.fixpop.inpanel { padding: .875rem; }
.cmp-box img { display: block; max-width: none; background: #fff; }
.cmp-mark {
  position: absolute; left: 0; right: 0; height: 0;
  border-top: 2px solid var(--accent); opacity: .55; pointer-events: none;
}
/* the reading column keeps clear of the panel so the two can be compared */
body.cmp-open .shell { padding-right: var(--cmp-w); }
/* Wide enough to read a printed page fitted to it. */
body.cmp-open .pop { right: calc(var(--cmp-w) + .75rem); }
/* Below this the reading column and a docked panel cannot both have room, so
   the scan takes the lower half of the screen instead of the right side. */
@media (max-width: 1100px) {
  .cmp { top: auto; left: 0; width: auto; height: 46vh; border-left: 0;
         border-top: 1px solid var(--line-2); }
  body.cmp-open .shell { padding-right: 0; padding-bottom: 46vh; }
  body.cmp-open .pop { right: .75rem; }
}

/* publishing a correction */
.fixstatus {
  margin: .625rem 0 0; padding: .4375rem .5rem; border-radius: var(--r-sm);
  background: var(--accent-bg); color: var(--ink-2);
  font-size: .6875rem; line-height: 1.5;
}
.fixstatus.bad { background: var(--paper-3); color: var(--accent); }
.fixtok { margin-top: .625rem; border-top: 1px solid var(--line); padding-top: .5rem; }
.fixtok summary {
  cursor: pointer; font-size: .625rem; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-4);
}
.fixtok p { font-size: .6875rem; line-height: 1.5; color: var(--ink-3); margin: .5rem 0; }
.fixtok-in {
  width: 100%; padding: .375rem .5rem; border: 1px solid var(--line-2);
  border-radius: var(--r-sm); background: var(--paper); color: var(--ink);
  font-family: var(--mono); font-size: .6875rem;
}
.fixtok-act { display: flex; gap: .375rem; margin-top: .375rem; }
/* A block being edited as text, and its small bar of Lưu / Bỏ. */
.prose .editing {
  outline: 2px dashed var(--accent);
  outline-offset: 4px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  cursor: text;
}
.prose .editing:focus-visible { outline: 2px dashed var(--accent); }
.editbar {
  display: flex; flex-wrap: wrap; gap: .375rem; align-items: center;
  margin: .5rem 0 .875rem; font-size: .75rem; color: var(--ink-3);
}
.editbar-hint { margin-right: auto; }
.fixpop-warn {
  margin: .375rem 0 0; padding: .375rem .5rem; border-radius: var(--r-sm);
  background: var(--accent-bg); color: var(--accent);
  font-size: .6875rem; line-height: 1.45;
}
.fixpop-scope label.off { color: var(--ink-4); }
