/* Reader — the reading view (route #/book/<id>). Owned by the reader feature.
   Structure:  .reader > .reader__topbar, .reader__sidebar, .reader__stage (> .reader__scroller
   > .reader__pages > .page …), .reader__bottombar.  The two bars overlay the stage so that
   hiding them never moves the page. */

/* ---------- Host & opening states ---------- */
.reader-host { position: absolute; inset: 0; background: var(--reader-bg); }
.reader-host__overlay {
  position: absolute; inset: 0; z-index: 5; display: grid; place-items: center;
  overflow: auto; background: var(--reader-bg);
}
.reader-host__overlay:empty { display: none; }
.reader-state { width: 100%; }
.reader-state--loading {
  display: grid; justify-items: center; gap: var(--s-4); padding: var(--s-6);
  color: var(--ink-3); font-size: var(--text-sm); text-align: center;
  animation: fade-in var(--dur-3) ease-out;
}
.reader-state__book { font-family: var(--font-display); font-style: italic; color: var(--ink-2); }
.reader-state .empty-state svg { color: var(--ink-3); }
.reader-state__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2); margin-top: var(--s-3); }

/* ---------- Shell ---------- */
.reader {
  --topbar-h: 56px;
  --bottombar-h: var(--reader-bottombar-h);   /* tokens.css: toasts and the import tray float above it */
  --sidebar-w: 0px;
  --search-w: 0px;
  --bar-top: calc(var(--topbar-h) + env(safe-area-inset-top, 0px));
  --bar-bottom: calc(var(--bottombar-h) + env(safe-area-inset-bottom, 0px));

  /* Page theme. Pages are original pixels + CSS (see src/reader/themes.js). */
  --page-paper: #FFFFFF;
  --page-backing: #FFFFFF;
  --canvas-filter: none;
  --canvas-opacity: 1;
  --picture-filter: none;
  --page-select: rgba(31, 90, 71, .26);
  --hit-bg: rgba(255, 210, 63, .5);
  --hit-current-bg: #FFD23F;
  --hit-ring: rgba(42, 33, 0, .75);
  --hit-blend: multiply;
  --link-hover: rgba(31, 90, 71, .12);

  position: absolute; inset: 0; overflow: hidden;
  background: var(--reader-bg);
}
.reader[data-page-theme="sepia"] {
  --page-paper: #F4ECD8;
  --page-backing: #CDA84D;
  --canvas-opacity: .78;
  --page-select: rgba(88, 62, 14, .26);
}
.reader[data-page-theme="dark"] {
  --page-paper: #131A17;
  --page-backing: #466055;
  --canvas-filter: invert(1) hue-rotate(180deg);
  --canvas-opacity: .73;
  --picture-filter: brightness(.88);
  --page-select: rgba(132, 212, 180, .34);
  --hit-bg: rgba(255, 210, 63, .30);
  --hit-current-bg: rgba(255, 210, 63, .55);
  --hit-ring: #FFD23F;
  --hit-blend: normal;
  --link-hover: rgba(132, 212, 180, .16);
}
.reader[data-page-theme="dark"][data-dark-style="recolor"] { --canvas-filter: grayscale(1) invert(1); }

.reader__stage { position: absolute; inset: 0 var(--search-w) 0 var(--sidebar-w); }
.reader__scroller {
  position: absolute; inset: 0;
  overflow: auto; overscroll-behavior: contain; overflow-anchor: none;
  scrollbar-gutter: stable;
  touch-action: pan-x pan-y;      /* pinch is ours (gestures.js) */
  -webkit-overflow-scrolling: touch;
}
.reader__scroller:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.reader__scroller--quiet:focus-visible { outline: none; }
/* Pages sit on whole device pixels; the viewer sets the rounding step to one device pixel. */
.reader__pages { position: relative; --scale-round-x: 1px; --scale-round-y: 1px; }

/* ---------- Pages ---------- */
.page {
  position: absolute;
  background: var(--page-paper);
  box-shadow: 0 0 0 1px var(--line), var(--shadow-1), 0 14px 28px -20px var(--line-strong);
}
.page--offstage { visibility: hidden; pointer-events: none; }
.page--enter { animation: page-in var(--dur-2) var(--ease); }
@keyframes page-in { from { opacity: 0; transform: translateY(6px); } }

.page__paper { position: absolute; inset: 0; overflow: hidden; background: var(--page-paper); }
.page--rendered .page__paper { background: var(--page-backing); }
/* The page theme is a filter over the original pixels. It sits on the box that holds the
   bitmaps, so the whole-page bitmap and the sharp detail on top of it blend as one. */
.page__ink { position: absolute; inset: 0; filter: var(--canvas-filter); opacity: var(--canvas-opacity); }
.page__canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.page__detail { position: absolute; }
/* Pictures restored from the original pixels in dark themes. */
.page__patch { position: absolute; filter: var(--picture-filter); }
/* Pages shown as they are in the dark theme: one big picture left alone (page--plain: a scan
   with "Recolor", a full-page photograph) and pages that are dark to begin with (page--dark). */
.page--plain .page__paper, .page--dark .page__paper { background: var(--page-paper); }
.page--plain .page__ink, .page--dark .page__ink { filter: var(--picture-filter); opacity: 1; }
/* A scan on grey or tan paper, re-inked by "Invert": the paper is lifted to white before the theme filter (page-view.js). */
.reader[data-page-theme="dark"] .page--lift .page__ink { filter: brightness(var(--paper-lift, 1)) var(--canvas-filter); }
.page__error {
  position: absolute; inset: 0; display: grid; place-items: center; margin: 0; padding: var(--s-6);
  color: var(--ink-3); font-size: var(--text-sm); text-align: center; background: var(--surface);
}

/* Overlay layers: laid out upright, rotated with the page. */
.page__layer { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; }
.page__layer[data-rotation="90"], .textLayer[data-main-rotation="90"] { transform: rotate(90deg) translateY(-100%); }
.page__layer[data-rotation="180"], .textLayer[data-main-rotation="180"] { transform: rotate(180deg) translate(-100%, -100%); }
.page__layer[data-rotation="270"], .textLayer[data-main-rotation="270"] { transform: rotate(270deg) translateX(-100%); }

.page__hits .hit {
  position: absolute; border-radius: 2px;
  background: var(--hit-bg); mix-blend-mode: var(--hit-blend);
}
.page__hits .hit--current { background: var(--hit-current-bg); box-shadow: 0 0 0 1.5px var(--hit-ring); }

.page__link { position: absolute; pointer-events: auto; border-radius: 2px; }
.page__link:hover { background: var(--link-hover); }
.page__link:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* pdf.js text layer (rules mirror pdf.js's own viewer CSS, which is not shipped). */
.textLayer {
  position: absolute; left: 0; top: 0;
  overflow: clip; line-height: 1; text-align: initial;
  -webkit-text-size-adjust: none; text-size-adjust: none; forced-color-adjust: none;
  transform-origin: 0 0; caret-color: CanvasText; z-index: 0;
  --min-font-size: 1;
  --text-scale-factor: calc(var(--total-scale-factor) * var(--min-font-size));
  --min-font-size-inv: calc(1 / var(--min-font-size));
}
.textLayer :is(span, br) { color: transparent; position: absolute; white-space: pre; cursor: text; transform-origin: 0% 0%; }
.textLayer > :not(.markedContent),
.textLayer .markedContent span:not(.markedContent) {
  z-index: 1;
  --font-height: 0; --scale-x: 1; --rotate: 0deg;
  font-size: calc(var(--text-scale-factor) * var(--font-height));
  transform: rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv));
}
.textLayer .markedContent { display: contents; }
.textLayer ::selection { background: var(--page-select); color: transparent; }
.textLayer br::selection { background: transparent; }
.textLayer .endOfContent { display: block; position: absolute; inset: 100% 0 0; z-index: 0; cursor: default; user-select: none; -webkit-user-select: none; }
.textLayer.selecting .endOfContent { top: 0; }
/* pdf.js measures text with a canvas it parks in <body>. */
.hiddenCanvasElement { position: absolute; top: 0; left: 0; width: 0; height: 0; display: none; }

/* ---------- Bars ---------- */
.reader__bar {
  position: absolute; z-index: var(--z-chrome);
  display: flex; align-items: center;
  background: var(--surface); color: var(--ink);
  transition: transform var(--dur-2) var(--ease), opacity var(--dur-2) var(--ease), visibility 0s;
}
.reader__topbar {
  top: 0; left: 0; right: 0; height: var(--bar-top); gap: var(--s-1);
  padding: env(safe-area-inset-top, 0px) max(var(--s-2), env(safe-area-inset-right, 0px)) 0 max(var(--s-2), env(safe-area-inset-left, 0px));
  border-bottom: 1px solid var(--line);
}
.reader__bottombar {
  bottom: 0; left: var(--sidebar-w); right: var(--search-w); height: var(--bar-bottom); gap: var(--s-4);
  padding: 0 max(var(--s-4), env(safe-area-inset-right, 0px)) env(safe-area-inset-bottom, 0px) max(var(--s-3), env(safe-area-inset-left, 0px));
  border-top: 1px solid var(--line);
}
.reader--chrome-hidden .reader__bar { opacity: 0; visibility: hidden; transition-delay: 0s, 0s, var(--dur-2); }
.reader--chrome-hidden .reader__topbar { transform: translateY(-100%); }
.reader--chrome-hidden .reader__bottombar { transform: translateY(100%); }

.reader__title { flex: 1; min-width: 0; padding: 0 var(--s-2); }
.reader__title-main {
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-family: var(--font-display); font-size: 1rem; font-weight: 560; letter-spacing: -0.01em; line-height: 1.25;
}
.reader__title-sub { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--ink-3); font-size: var(--text-xs); line-height: 1.3; }

.reader__tools { display: flex; align-items: center; gap: 2px; flex: none; }
.reader__slot { display: contents; }
.reader__zoom {
  display: flex; align-items: center; height: 34px; margin: 0 var(--s-1); padding: 0 1px;
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
}
.reader__zoom-value {
  min-width: 52px; height: 30px; padding: 0 4px; border: 0; border-radius: var(--r-sm); background: none;
  color: var(--ink); font-size: var(--text-sm); font-weight: 600; text-align: center;
}
.reader__zoom-value:hover { background: var(--hover); }

/* Page number + scrubber */
.reader__page { flex: none; font-size: var(--text-sm); color: var(--ink-2); white-space: nowrap; }
.reader__page-btn {
  display: inline-flex; align-items: baseline; gap: .3em; min-height: 32px; padding: 0 var(--s-2);
  border: 0; border-radius: var(--r-sm); background: none; color: inherit; white-space: pre;
}
.reader__page-btn:hover { background: var(--hover); color: var(--ink); }
.reader__page-current { color: var(--ink); font-weight: 650; border-bottom: 1px dashed var(--line-strong); }
.reader__page-form { display: inline-flex; align-items: center; gap: .3em; min-height: 32px; padding: 0 var(--s-2); white-space: pre; }
.reader__page-input {
  width: 5.5ch; height: 28px; padding: 0 6px; text-align: center;
  border: 1px solid var(--focus); border-radius: var(--r-sm); background: var(--raised); color: var(--ink); font-weight: 650;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus) 22%, transparent);
}
.reader__percent { flex: none; min-width: 4ch; color: var(--ink-3); font-size: var(--text-sm); text-align: right; }

.scrubber { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; height: 32px; }
.scrubber--single { visibility: hidden; }
.scrubber__range {
  --fill: 0;
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 32px; margin: 0; background: transparent; cursor: pointer; touch-action: none;
}
.scrubber__range::-webkit-slider-runnable-track {
  height: 5px; border-radius: 3px;
  /* The highlighter stroke fills the track up to the thumb's centre. */
  background: linear-gradient(to right, var(--accent) calc(9px + var(--fill) * (100% - 18px)), var(--line-strong) 0);
}
.scrubber__range::-moz-range-track { height: 5px; border-radius: 3px; background: var(--line-strong); }
.scrubber__range::-moz-range-progress { height: 5px; border-radius: 3px; background: var(--accent); }
.scrubber__range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; margin-top: -6.5px; border-radius: 50%;
  background: var(--raised); border: 1.5px solid var(--ink); box-shadow: var(--shadow-1);
  transition: transform var(--dur-1);
}
.scrubber__range::-moz-range-thumb {
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--raised); border: 1.5px solid var(--ink); box-shadow: var(--shadow-1);
}
.scrubber__range:active::-webkit-slider-thumb { transform: scale(1.15); }
.scrubber__range:focus-visible { outline: none; }
.scrubber__range:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--focus); outline-offset: 2px; }
.scrubber__range:focus-visible::-moz-range-thumb { outline: 2px solid var(--focus); outline-offset: 2px; }
.scrubber__bubble {
  position: absolute; bottom: calc(100% + 6px); left: var(--x, 0); transform: translateX(var(--shift, -50%));
  display: grid; gap: 1px; max-width: min(280px, 80vw); padding: 6px 10px;
  border-radius: var(--r-sm); background: var(--ink); color: var(--bg);
  font-size: var(--text-sm); line-height: 1.3; white-space: nowrap; pointer-events: none;
  box-shadow: var(--shadow-2);
}
.scrubber__bubble span { overflow: hidden; text-overflow: ellipsis; opacity: .78; font-size: var(--text-xs); }

/* ---------- "Back to page N" (the way back after a jump) ---------- */
.reader__return {
  position: absolute; left: var(--sidebar-w); right: var(--search-w); bottom: calc(var(--bar-bottom) + var(--s-3));
  z-index: var(--z-chrome); display: flex; justify-content: center; padding: 0 var(--s-3);
  pointer-events: none; transition: bottom var(--dur-2) var(--ease);
}
.reader__return[hidden] { display: none; }
.reader--chrome-hidden .reader__return { bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px)); }
.return {
  display: inline-flex; align-items: center; max-width: 100%; padding: 3px;
  border-radius: var(--r-pill); background: var(--ink); color: var(--bg); box-shadow: var(--shadow-3);
  pointer-events: auto; animation: toast-in var(--dur-2) var(--ease);
}
.return__go {
  display: inline-flex; align-items: center; gap: var(--s-2); min-height: 2rem; padding: 0 var(--s-2) 0 var(--s-3);
  border: 0; border-radius: var(--r-pill); background: none; color: inherit;
  font-size: var(--text-sm); font-weight: 650; white-space: nowrap;
}
.return__stay {
  display: grid; place-items: center; width: 2rem; height: 2rem; padding: 0;
  border: 0; border-radius: 50%; background: none; color: inherit; opacity: .8;
}
.return__go:hover, .return__stay:hover { background: color-mix(in srgb, var(--bg) 18%, transparent); opacity: 1; }
.return__go:focus-visible, .return__stay:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
@media (pointer: coarse) {
  .return__go { min-height: 2.5rem; }
  .return__stay { width: 2.5rem; height: 2.5rem; }
}
/* Toasts stay clear of it. */
#app[data-route="reader"]:has(.reader__return:not([hidden])):not(:has(.reader--chrome-hidden)) ~ .toasts { padding-bottom: calc(var(--reader-bottombar-h) + 64px + env(safe-area-inset-bottom)); }
#app[data-route="reader"]:has(.reader__return:not([hidden])):has(.reader--chrome-hidden) ~ .toasts { padding-bottom: calc(68px + env(safe-area-inset-bottom)); }

/* ---------- Sidebar ---------- */
.reader--sidebar-open { --sidebar-w: 320px; }
.reader__sidebar {
  position: absolute; top: var(--bar-top); bottom: 0; left: 0; width: 320px;
  z-index: calc(var(--z-chrome) - 1);
  display: flex; flex-direction: column;
  background: var(--surface); border-right: 1px solid var(--line);
}
.reader__scrim { display: none; }
.sidebar__grip { display: none; }
.sidebar__head { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2) var(--s-2) 0 var(--s-3); }
.sidebar__tabs { flex: 1; display: flex; gap: 2px; }
.sidebar__tab {
  position: relative; display: grid; place-items: center; width: 44px; height: 40px;
  border: 0; border-radius: var(--r-md); background: none; color: var(--ink-3);
  transition: background var(--dur-1), color var(--dur-1);
}
.sidebar__tab:hover { background: var(--hover); color: var(--ink); }
.sidebar__tab[aria-selected="true"] { color: var(--ink); }
/* The highlighter stroke marks the tab that is open. */
.sidebar__tab[aria-selected="true"]::after {
  content: ""; position: absolute; left: 11px; right: 11px; bottom: 3px; height: 5px; border-radius: 3px;
  background: var(--accent);
}
.sidebar__badge {
  position: absolute; top: 3px; right: 2px; min-width: 1rem; height: 1rem; padding: 0 4px;
  border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink-2);
  font-size: 0.625rem; font-weight: 700; line-height: 1rem; text-align: center;
}
.sidebar__title {
  padding: var(--s-3) var(--s-4) var(--s-2);
  font-family: var(--font-display); font-size: var(--text-lg); font-weight: 560; letter-spacing: -0.01em;
}
.sidebar__body { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding-bottom: var(--s-4); }
.sidebar__body:focus-visible { outline: none; }
.sidebar__loading { display: grid; place-items: center; padding: var(--s-10); }
.sidebar__empty {
  display: grid; justify-items: center; gap: var(--s-2); padding: var(--s-8) var(--s-5);
  color: var(--ink-2); font-size: var(--text-sm); text-align: center;
}
.sidebar__empty > svg { color: var(--ink-3); margin-bottom: var(--s-1); }
.sidebar__empty-title { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 560; color: var(--ink); }
.sidebar__empty-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-2); margin-top: var(--s-3); }

/* Contents */
.toc { margin: 0; padding: 0; }
.sidebar__body > .toc { padding: 0 var(--s-2); }
.toc__row { display: flex; align-items: stretch; padding-left: calc(var(--depth, 0) * 14px); }
.toc__toggle, .toc__toggle-space { flex: none; width: 26px; }
.toc__toggle {
  display: grid; place-items: center; padding: 0; border: 0; border-radius: var(--r-sm); background: none; color: var(--ink-3);
}
.toc__toggle:hover { background: var(--hover); color: var(--ink); }
.toc__toggle svg { transition: transform var(--dur-1) var(--ease); }
.toc__item--collapsed > .toc__row .toc__toggle svg { transform: rotate(-90deg); }
.toc__item--collapsed > .toc { display: none; }
.toc__link {
  flex: 1; min-width: 0; display: flex; align-items: baseline; gap: var(--s-3);
  min-height: 36px; padding: 8px var(--s-2) 8px 4px;
  border: 0; border-radius: var(--r-sm); background: none; color: var(--ink-2);
  font-size: var(--text-md); line-height: 1.35; text-align: left;
}
.toc__item[style*="--depth: 0"] > .toc__row .toc__link { color: var(--ink); }
.toc__link:hover { background: var(--hover); color: var(--ink); }
.toc__link--bold { font-weight: 650; }
.toc__link--italic { font-style: italic; }
.toc__link[aria-current="true"] { color: var(--ink); font-weight: 650; }
.toc__title { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.toc__page { flex: none; color: var(--ink-3); font-size: var(--text-sm); font-weight: 400; }

/* Pages */
.thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: var(--s-4) var(--s-3); padding: var(--s-1) var(--s-4) var(--s-4); }
.thumb { display: grid; gap: 6px; justify-items: center; align-content: start; padding: 0; border: 0; background: none; color: var(--ink-2); }
.thumb__paper {
  position: relative; display: block; width: 100%; overflow: hidden; border-radius: 2px;
  background: var(--page-paper);
  box-shadow: 0 0 0 1px var(--line), var(--shadow-1);
  transition: box-shadow var(--dur-1);
}
.thumb__paper--ready { background: var(--page-backing); }
.thumb__canvas { position: absolute; inset: 0; width: 100%; height: 100%; filter: var(--canvas-filter); opacity: var(--canvas-opacity); }
.thumb:hover .thumb__paper { box-shadow: 0 0 0 1px var(--line-strong), var(--shadow-2); }
.thumb[aria-current="page"] .thumb__paper { box-shadow: 0 0 0 2px var(--ink), var(--shadow-2); }
.thumb[aria-current="page"] { color: var(--ink); font-weight: 650; }
.thumb:focus-visible { outline: none; }
.thumb:focus-visible .thumb__paper { outline: 2px solid var(--focus); outline-offset: 3px; }
.thumb__label { font-size: var(--text-xs); }

/* ---------- Search ---------- */
.reader__search {
  position: absolute; top: calc(var(--bar-top) + 10px); right: 26px; z-index: var(--z-chrome);
  display: flex; flex-direction: column; width: min(400px, calc(100% - 52px)); max-height: min(72%, 580px);
  border-radius: var(--r-lg); background: var(--raised); color: var(--ink);
  box-shadow: var(--shadow-3), 0 0 0 1px var(--line);
  animation: pop-in var(--dur-2) var(--ease);
}
.search__bar { display: flex; align-items: center; gap: var(--s-1); padding: var(--s-2); }
.search__field { flex: 1; min-width: 0; }
.search__input { min-height: 36px; }
.search__input::-webkit-search-cancel-button { display: none; }
.search__count { flex: none; padding: 0 var(--s-1); color: var(--ink-2); font-size: var(--text-sm); white-space: nowrap; }
.search__count:empty { display: none; }
.search__nav { display: flex; flex: none; }
.search__progress { height: 3px; margin: 0 var(--s-3); }
.search__status { padding: var(--s-2) var(--s-4) var(--s-4); color: var(--ink-2); font-size: var(--text-sm); line-height: 1.5; }
.search__results { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; margin: 0; padding: 0 var(--s-1) var(--s-1); border-top: 1px solid var(--line); }
.reader__search:not(.reader__search--has-results) .search__results { display: none; }
.reader:not(.reader--search-docked) .reader__search--collapsed .search__results { display: none; }
/* Where there is room (search.js decides: a wide window, wider still beside a docked sidebar)
   the panel is a docked column beside the page, so results never cover the text. */
.reader--search-docked.reader--search-open { --search-w: 360px; }
.reader--search-docked .reader__search {
  top: var(--bar-top); right: 0; bottom: 0; width: 360px; max-height: none;
  border-radius: 0; border-left: 1px solid var(--line); background: var(--surface); box-shadow: none;
  animation: none;
}
.reader--search-docked .search__bar { padding: var(--s-3) var(--s-2) var(--s-2) var(--s-3); }
.reader--search-docked .search__nav [aria-expanded] { display: none; }
.search__result {
  display: flex; align-items: baseline; gap: var(--s-3); width: 100%; padding: 9px var(--s-3);
  border: 0; border-radius: var(--r-sm); background: none; color: var(--ink-2);
  font-size: var(--text-sm); line-height: 1.45; text-align: left;
}
.search__results li:first-child .search__result { margin-top: var(--s-1); }
.search__result:hover { background: var(--hover); }
.search__result[aria-current="true"] { background: var(--pressed); color: var(--ink); }
.search__snippet {
  flex: 1; min-width: 0; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical;
  font-family: var(--font-display);
}
.search__snippet mark {
  color: var(--ink); font-weight: 600; border-radius: 2px;
  background: linear-gradient(var(--mark), var(--mark)) no-repeat 0 88% / 100% 46%;
}
.search__page { flex: none; color: var(--ink-3); font-family: var(--font-ui); font-size: var(--text-xs); }

/* ---------- Page theme popover ---------- */
.display-pop { display: grid; gap: var(--s-5); width: 304px; max-width: calc(100vw - 16px); padding: var(--s-4); }
.display-pop__section { display: grid; gap: var(--s-2); }
.display-pop__hint { color: var(--ink-2); font-size: var(--text-sm); line-height: 1.45; }
.display-pop .seg { display: flex; }
.display-pop .seg > button { flex: 1; }
.display-pop__zoom { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1); }
.display-pop__zoom-value { min-width: 48px; font-size: var(--text-sm); font-weight: 600; text-align: center; }
.display-pop__zoom .chip { margin-left: var(--s-1); }
.display-pop__zoom .chip + .chip { margin-left: 0; }

/* Four across — or, when the text is set too large for a quarter of the row (3.75rem), two by
   two; never three and one. The clamp() picks the quarter or the half as the column width. */
.swatches {
  --quarter: calc((100% - 3 * var(--s-2)) / 4 - 0.5px);
  --half: calc((100% - var(--s-2)) / 2 - 0.5px);
  display: grid; gap: var(--s-2);
  grid-template-columns: repeat(auto-fit, minmax(clamp(var(--quarter), (3.75rem - var(--quarter)) * 999, var(--half)), 1fr));
}
.swatch { display: grid; gap: 6px; padding: 0; border: 0; background: none; color: var(--ink-2); font-size: var(--text-xs); font-weight: 600; }
.swatch__page {
  display: grid; place-items: center; height: 52px; border-radius: var(--r-sm);
  font-family: var(--font-display); font-size: 1.125rem; font-weight: 560;
  box-shadow: 0 0 0 1px var(--line-strong);
  transition: box-shadow var(--dur-1);
}
.swatch[data-look="original"] .swatch__page, .swatch .swatch__page--auto [data-look="original"] { background: #FFFFFF; color: #14251F; }
.swatch[data-look="sepia"] .swatch__page { background: #F4ECD8; color: #2D2511; }
.swatch[data-look="dark"] .swatch__page, .swatch .swatch__page--auto [data-look="dark"] { background: #131A17; color: #CDD4D1; }
/* "Match app": both papers side by side. */
.swatch .swatch__page--auto { grid-template-columns: 1fr 1fr; place-items: stretch; overflow: hidden; }
.swatch__page--auto span { display: grid; place-items: center; }
.swatch:hover .swatch__page { box-shadow: 0 0 0 1px var(--ink-3); }
.swatch[aria-checked="true"] { color: var(--ink); }
.swatch[aria-checked="true"] .swatch__page { box-shadow: 0 0 0 2px var(--ink); }
.swatch:focus-visible { outline: none; }
.swatch:focus-visible .swatch__page { outline: 2px solid var(--focus); outline-offset: 3px; }

/* ---------- Dialog contents ---------- */
.shortcuts { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--s-5) var(--s-8); padding-top: var(--s-2); }
.shortcuts__group { display: grid; gap: var(--s-2); align-content: start; }
.shortcuts__list { margin: 0; }
.shortcuts__row { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 34px; border-bottom: 1px solid var(--line); }
.shortcuts__row:last-child { border-bottom: 0; }
.shortcuts__row dt { color: var(--ink-2); font-size: var(--text-sm); white-space: nowrap; }
.shortcuts__row dd { display: flex; align-items: center; gap: 6px; margin: 0; white-space: nowrap; }
.shortcuts__combo { display: inline-flex; gap: 3px; }
.shortcuts__or { color: var(--ink-3); font-size: var(--text-xs); }

.book-info { display: grid; gap: var(--s-1); }
.book-info__title { font-size: var(--text-xl); }
.book-info__author { color: var(--ink-2); }
.book-info__list { margin: var(--s-4) 0 0; }
.book-info__row { display: grid; grid-template-columns: 88px minmax(0, 1fr); gap: var(--s-3); padding: 9px 0; border-top: 1px solid var(--line); font-size: var(--text-sm); }
.book-info__row dt { color: var(--ink-3); }
.book-info__row dd { margin: 0; overflow-wrap: anywhere; }
.book-info__note { margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid var(--line); color: var(--ink-3); font-size: var(--text-xs); }

/* ---------- Sidebar as a sheet (tablets in portrait, phones) ---------- */
@media (max-width: 860px) {
  .reader--sidebar-open { --sidebar-w: 0px; }
  .reader__sidebar {
    top: auto; left: 0; right: 0; bottom: 0; width: auto; height: min(76dvh, 680px);
    z-index: calc(var(--z-chrome) + 2);
    border-right: 0; border-radius: var(--r-lg) var(--r-lg) 0 0;
    padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
    box-shadow: var(--shadow-3);
    animation: sheet-up var(--dur-3) var(--ease);
  }
  .reader__scrim { display: block; position: absolute; inset: 0; z-index: calc(var(--z-chrome) + 1); background: var(--scrim); animation: fade-in var(--dur-2) ease-out; }
  .sidebar__grip { display: block; width: 36px; height: 4px; margin: 8px auto 0; border-radius: 2px; background: var(--line-strong); }
  .sidebar__head { padding-top: var(--s-1); }
  .thumbs { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
}
@keyframes sheet-up { from { transform: translateY(32px); opacity: 0; } }

/* ---------- Phones ---------- */
@media (max-width: 720px) {
  .reader { --topbar-h: 52px; }
  .reader__topbar { gap: 0; padding-left: max(4px, env(safe-area-inset-left, 0px)); padding-right: max(4px, env(safe-area-inset-right, 0px)); }
  .reader__title { padding: 0 var(--s-1); }
  .reader__title-main { font-size: var(--text-md); }
  .reader__tools { gap: 0; }
  .reader__zoom { display: none; }

  .reader__bottombar {
    display: grid; grid-template-columns: 1fr auto; grid-template-rows: minmax(30px, auto) minmax(28px, auto); align-content: center; gap: 0 var(--s-3);
    padding-left: max(var(--s-3), env(safe-area-inset-left, 0px)); padding-right: max(var(--s-3), env(safe-area-inset-right, 0px));
  }
  .scrubber { grid-column: 1 / -1; grid-row: 1; height: 30px; margin: 0 var(--s-1); }
  .reader__page { grid-row: 2; justify-self: start; }
  .reader__percent { grid-row: 2; padding-right: var(--s-1); }
  .reader__page-btn, .reader__page-form { min-height: 28px; padding: 0 var(--s-1); }

  .reader__search { top: calc(var(--bar-top) + 8px); left: 8px; right: 8px; width: auto; max-height: min(64%, 480px); }
  .display-pop { width: min(328px, calc(100vw - 16px)); }
}

@media (pointer: coarse) {
  .scrubber__range::-webkit-slider-thumb { width: 22px; height: 22px; margin-top: -8.5px; }
  .scrubber__range::-webkit-slider-runnable-track { background: linear-gradient(to right, var(--accent) calc(11px + var(--fill) * (100% - 22px)), var(--line-strong) 0); }
  .scrubber__range::-moz-range-thumb { width: 19px; height: 19px; }
  /* Touch targets of 40px and more, like the shared controls ("Touch" in base.css). */
  .reader__zoom { height: 44px; }
  .reader__zoom-value { height: 40px; }
  .toc__toggle, .toc__toggle-space { width: 40px; }
  .toc__link { min-height: 44px; padding-block: 11px; }
  .reader__page-btn { position: relative; }
  .reader__page-btn::before { content: ""; position: absolute; inset: -6px 0; }
  /* The larger zoom buttons still share one row with the two fit chips. */
  .display-pop__zoom-value { min-width: 40px; }
  .display-pop__zoom .chip { padding: 0 10px; }
}
