*{box-sizing:border-box;margin:0;padding:0}
:focus-visible{outline:2px solid var(--ac);outline-offset:2px;border-radius:4px}

/* ══ BRAND TOKENS ══════════════════════ */
:root{
  --bg0:#0a0a0d;--bg1:#111116;--bg2:#18181f;--bg3:#202028;--bg4:#2c2c38;
  --fg0:#f4f2ee;--fg1:#c8c4bc;--fg2:#8a8680;--fg3:#4e4a44;--bdr:#28283a;
  --ac:#8B6FE8;--ac2:#b09cf5;--adim:#241d52;
  --gold:#E8A830;--goldbg:#2a1f06;--goldbdr:#3d2e08;
  --gr:#4caf7d;--gbg:#0e2318;--gbdr:#1a3a24;--red:#e05c5c;
  --sans:'Inter',system-ui,sans-serif;
  --serif:'Lora',Georgia,serif;
  --brand-grad:linear-gradient(135deg,#7B5FDB,#A07EF5);
}
body.app-sepia{--bg0:#e8dfc8;--bg1:#f0e8d8;--bg2:#e8dfc8;--bg3:#ddd4be;--bg4:#ccc2ac;--fg0:#2a1e10;--fg1:#4a3828;--fg2:#8a7050;--fg3:#b09070;--bdr:#ccc2ac;--goldbg:#f5e8c8;--goldbdr:#d4a840;--gbg:#d8ecd8;--gbdr:#4caf7d}
body.app-light{--bg0:#e8e8f0;--bg1:#ffffff;--bg2:#f3f3f8;--bg3:#e8e8f0;--bg4:#d8d8e8;--fg0:#0e0e18;--fg1:#333344;--fg2:#666678;--fg3:#99999e;--bdr:#e0e0ee;--goldbg:#fff8e8;--goldbdr:#e8a830;--gbg:#eafaf0;--gbdr:#4caf7d}

html,body{height:100%;background:var(--bg0,#0a0a0d);font-family:var(--sans);font-size:14px;overflow:hidden}
#shell{display:flex;height:100vh;width:100%;margin:0 auto;flex-direction:column;background:var(--bg1);position:relative;overflow:hidden;transition:background .3s;
  padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px)}
/* Phone-sized layout: shell fills screen, max 480px on small screens for centering on portrait phones */
@media(max-width:519px){#shell{max-width:100%}}
/* Tablet / large phones / desktop: shell stretches but capped so the chrome doesn't get absurdly wide.
   The reader content (rb2) gets its own narrower reading column inside this. */
@media(min-width:520px){#shell{max-width:900px;box-shadow:0 0 0 1px rgba(255,255,255,.06),0 24px 80px rgba(0,0,0,.6);height:100vh}}
@media(min-width:1024px){#shell{max-width:1100px}}
/* Follow Safari's visible viewport, including expanded browser controls.
   Shell padding reserves the notch and home-indicator space on every screen. */
@supports(height:100dvh){#shell{height:100dvh}}
/* On tablets/desktop, give EPUB content a comfortable reading column so lines aren't 80+ chars wide */
@media(min-width:520px){.rb2 .epub-content{max-width:680px;margin-left:auto;margin-right:auto}}

/* ── SPLASH ── */
#splash{position:absolute;inset:0;background:var(--bg0);z-index:1000;display:flex;flex-direction:column;align-items:center;justify-content:center}
#splash.hide{animation:splashOut .5s ease forwards;pointer-events:none}
@keyframes splashOut{to{opacity:0;transform:scale(1.03)}}
.splash-logo{margin-bottom:24px;animation:lIn .7s ease .2s both}
@keyframes lIn{from{opacity:0;transform:translateY(20px) scale(.9)}to{opacity:1;transform:none}}
.splash-name{font-size:32px;font-weight:700;letter-spacing:-.5px;animation:lIn .7s ease .4s both}
.splash-name .hs{background:var(--brand-grad);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.splash-name .bk{color:var(--fg0)}
.splash-tagline{font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--fg3);margin-top:8px;animation:lIn .7s ease .6s both}
.splash-dots{display:flex;gap:8px;margin-top:40px;animation:lIn .7s ease .8s both}
.splash-dot{width:6px;height:6px;border-radius:50%;background:var(--bg4);animation:dp 1.2s ease infinite}
.splash-dot:nth-child(2){animation-delay:.2s}.splash-dot:nth-child(3){animation-delay:.4s}
@keyframes dp{0%,100%{background:var(--bg4)}50%{background:var(--ac)}}
.splash-v{position:absolute;bottom:30px;font-size:11px;color:var(--fg3)}

/* ── SCREENS ── */
.scr{display:none;flex-direction:column;height:100%;min-height:0;min-width:0;overflow:hidden}
.scr.on{display:flex;animation:fi .22s ease}
@keyframes fi{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
@keyframes hl-pop{from{opacity:0;transform:translateY(-4px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}

/* ── TOPBAR ── */
.tb{display:flex;align-items:center;gap:10px;padding:16px 16px 12px;flex-shrink:0;background:var(--bg1);transition:background .3s}
.tb-brand{display:flex;align-items:center;gap:10px;flex:1}
.tb-logo{width:32px;height:32px;flex-shrink:0}
.tb-name{font-size:18px;font-weight:700;letter-spacing:-.3px;line-height:1}
.tb-name .bk{color:var(--fg0);transition:color .3s}
.tb-name .hs{background:var(--brand-grad);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.tb-sub{font-size:11px;color:var(--fg2);margin-top:2px;transition:color .3s}
.ib{width:36px;height:36px;border-radius:9px;border:none;background:var(--bg3);display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s;-webkit-tap-highlight-color:transparent}
.ib:hover{background:var(--bg4)}.ib:active{transform:scale(.94)}
.ib svg{width:18px;height:18px;stroke:var(--fg1);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;display:block;transition:stroke .3s;pointer-events:none}

/* ── SCROLL ── */
.sc{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;padding:0 16px 28px;background:var(--bg1);transition:background .3s;-webkit-overflow-scrolling:touch}
.sc::-webkit-scrollbar{width:3px}
.sc::-webkit-scrollbar-thumb{background:var(--bg4);border-radius:2px}

/* ── BOTTOM NAV ── */
.bn{display:flex;background:var(--bg1);border-top:1px solid var(--bdr);padding:6px 0 10px;flex-shrink:0;transition:background .3s,border-color .3s}
.ni{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 2px;cursor:pointer;color:var(--fg3);font-size:10px;font-weight:500;transition:color .15s;-webkit-tap-highlight-color:transparent;user-select:none}
.ni svg{width:21px;height:21px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.ni.on{color:var(--ac2)}

/* ── SEC LABEL ── */
.sec{font-size:10px;font-weight:700;letter-spacing:.1em;color:var(--fg2);text-transform:uppercase;margin:20px 0 10px;transition:color .3s}
.sec:first-child{margin-top:6px}

/* ── QUOTE CARD ── */
.qcard{border-radius:16px;padding:18px 18px 42px;margin-bottom:16px;border:1px solid;position:relative;overflow:hidden}
.qcard-hex{position:absolute;right:-10px;top:-10px;opacity:.06;font-size:80px;line-height:1;pointer-events:none;user-select:none}
.qcard-tag{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;opacity:.8;margin-bottom:12px;display:flex;align-items:center;gap:6px}
.qcard-tag svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.qcard-text{font-family:var(--serif);font-size:14px;line-height:1.78;font-style:italic;color:var(--fg0);transition:color .3s}
.qcard-author{font-size:11px;font-weight:600;margin-top:12px;letter-spacing:.05em;opacity:.75}
.qcard-refresh{position:absolute;bottom:14px;right:14px;width:28px;height:28px;border-radius:50%;border:none;background:rgba(255,255,255,.07);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s}
.qcard-refresh:hover{background:rgba(255,255,255,.14)}
.qcard-refresh svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;opacity:.7;pointer-events:none}

/* ── QUOTE CARD: PLAIN VARIANT (popup modal) ──
   Strips the decorative styling (hex glyph, gradient background,
   per-quote tint) so the popup is calm and focused on readability.
   The dynamic background + borderColor set inline by renderQuote()
   are overridden with !important — that's the only place inline styles
   are imposed on the qcard, and we explicitly want them ignored here. */
.qcard-plain{background:var(--bg2)!important;border-color:var(--bdr)!important;padding:22px 20px!important;box-shadow:none}
.qcard-plain .qcard-hex{display:none}
.qcard-plain .qcard-refresh{position:static;width:auto;height:auto;background:transparent;padding:6px;margin-top:14px;opacity:.6;display:inline-flex}
.qcard-plain .qcard-refresh:hover{background:transparent;opacity:1}
.qcard-plain .qcard-tag{opacity:.65}
.qcard-plain .qcard-author{margin-top:10px}

/* ── STREAK ── */
.sk{display:flex;align-items:center;gap:12px;background:var(--goldbg);border:1px solid var(--goldbdr);border-radius:13px;padding:13px 15px;margin-bottom:14px;transition:background .3s}
.sk-ico{font-size:22px;flex-shrink:0}
.skt{font-size:13px;font-weight:600;color:var(--gold)}
.sks{font-size:11px;color:var(--fg2);margin-top:2px;transition:color .3s}

/* ── STATS ── */
.sts{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:2px}
.st{background:var(--bg2);border:1px solid var(--bdr);border-radius:13px;padding:14px 10px;transition:background .3s,border-color .3s}
.stv{font-size:22px;font-weight:700;color:var(--fg0);transition:color .3s}
.stl{font-size:10px;color:var(--fg2);margin-top:3px;text-transform:uppercase;letter-spacing:.05em;transition:color .3s}
.sti svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-bottom:6px;pointer-events:none}

/* ── HERO ── */
.hr{background:var(--bg2);border:1px solid var(--bdr);border-radius:18px;padding:16px;display:flex;gap:14px;margin-bottom:20px;cursor:pointer;transition:border-color .15s,background .3s;-webkit-tap-highlight-color:transparent}
.hr:hover{border-color:var(--bg4)}
.hc{width:64px;height:96px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:32px;flex-shrink:0;user-select:none}
.hb{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:space-between}
.htg{font-size:10px;color:var(--ac2);font-weight:700;text-transform:uppercase;letter-spacing:.07em;margin-bottom:4px}
.htt{font-size:15px;font-weight:600;color:var(--fg0);line-height:1.3;transition:color .3s}
.hau{font-size:12px;color:var(--fg2);margin-top:2px;transition:color .3s}
.hpw{height:4px;background:var(--bg4);border-radius:2px;margin-top:12px;transition:background .3s}
.hpf{height:100%;border-radius:2px;background:var(--brand-grad)}
.hpc{font-size:11px;color:var(--fg2);margin-top:5px;transition:color .3s}
/* Continue-Reading dual-button row: Read (purple) + Listen (gold).
   The container keeps the old margin-top of the single button so the
   surrounding hero card layout doesn't shift. Each button takes 50%
   width via flex; the small gap matches Material spacing. */
.rbt-row{display:flex;gap:8px;margin-top:10px;width:100%}
.rbt{display:flex;align-items:center;justify-content:center;gap:6px;border-radius:9px;padding:9px 10px;font-size:12px;font-weight:600;border:none;cursor:pointer;font-family:var(--sans);flex:1;min-width:0;transition:background .15s, transform .12s, box-shadow .15s;-webkit-tap-highlight-color:transparent}
.rbt:active{transform:scale(.97)}
.rbt svg{width:13px;height:13px;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
/* Read button — keeps the original purple identity */
.rbt-read{background:var(--adim);color:var(--ac2)}
.rbt-read:hover{background:#2e2562}
.rbt-read svg{stroke:var(--ac2)}
/* Listen button — gold accent to mark TTS as a peer feature of reading.
   Reuses the page's existing --gold tokens so it doesn't introduce
   new colors. Solid background so the button reads as "tap-me" even
   on devices where the user hasn't bought premium yet (the tap then
   surfaces the premium upsell, same as the panel's Play button). */
.rbt-listen{background:linear-gradient(135deg,#f5c84a,#e8a830);color:#1a1408;box-shadow:0 2px 8px rgba(232,168,48,.25)}
.rbt-listen:hover{filter:brightness(1.06)}

/* ── BOOK GRID ── */
.bg{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(min-width:600px){.bg{grid-template-columns:repeat(4,1fr);gap:16px}}
@media(min-width:900px){.bg{grid-template-columns:repeat(5,1fr)}}
.bk{cursor:pointer;border-radius:13px;overflow:hidden;background:var(--bg2);border:1px solid var(--bdr);transition:border-color .15s,transform .15s,background .3s;-webkit-tap-highlight-color:transparent}
.bk:hover{border-color:var(--bg4);transform:translateY(-2px)}.bk:active{transform:scale(.97)}
.bkc{aspect-ratio:2/3;display:flex;align-items:center;justify-content:center;font-size:36px;position:relative;user-select:none}
.bkp{position:absolute;bottom:0;left:0;right:0;height:3px;background:rgba(0,0,0,.12)}
.bkpf{height:100%}
.bki{padding:9px 10px 11px}
.bkt{font-size:12px;font-weight:600;color:var(--fg0);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:color .3s}
.bka{font-size:10px;color:var(--fg2);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:color .3s}
.bkf{display:flex;align-items:center;justify-content:space-between;margin-top:6px}
.bge{background:#1e1a3f;color:#b09cf5;padding:2px 6px;border-radius:4px;font-size:9px;font-weight:700;text-transform:uppercase}
.bgp{background:#2a1510;color:#e07850;padding:2px 6px;border-radius:4px;font-size:9px;font-weight:700;text-transform:uppercase}
.bgt{background:#0e2018;color:#4caf7d;padding:2px 6px;border-radius:4px;font-size:9px;font-weight:700;text-transform:uppercase}
.bkpc{font-size:10px;color:var(--ac2);font-weight:600}

/* ── FAB ── */
.fab{position:absolute;bottom:calc(78px + env(safe-area-inset-bottom,0px));right:16px;width:52px;height:52px;border-radius:50%;background:var(--brand-grad);border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:20;box-shadow:0 4px 20px rgba(123,95,219,.45);transition:transform .15s,box-shadow .15s;-webkit-tap-highlight-color:transparent}
.fab:hover{transform:scale(1.06);box-shadow:0 6px 28px rgba(123,95,219,.6)}.fab:active{transform:scale(.96)}
.fab svg{width:24px;height:24px;stroke:#fff;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}

/* ── IMPORT ── */
.io{display:flex;align-items:center;gap:14px;padding:15px 16px;background:var(--bg2);border:1px solid var(--bdr);border-radius:13px;cursor:pointer;margin-bottom:10px;transition:border-color .15s,background .3s;-webkit-tap-highlight-color:transparent}
.io:hover{border-color:var(--ac)}
.ii{width:44px;height:44px;border-radius:11px;background:var(--adim);color:var(--ac2);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.ii svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.il{font-size:14px;font-weight:600;color:var(--fg0);transition:color .3s}
.is{font-size:11px;color:var(--fg2);margin-top:2px;transition:color .3s}
.cv{width:16px;height:16px;stroke:var(--fg3);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;margin-left:auto;flex-shrink:0;pointer-events:none}
.okm{background:var(--gbg);border:1px solid var(--gbdr);border-radius:13px;padding:14px 16px;display:none;margin-top:12px;transition:background .3s}
.okm.on{display:block}
.okt{font-size:14px;font-weight:600;color:var(--gr);display:flex;align-items:center;gap:8px}
.okt svg{width:17px;height:17px;stroke:var(--gr);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.oks{font-size:12px;color:var(--fg2);margin-top:3px}

/* ── READER ── */
#s-reader{position:relative;overflow:hidden}
#bl-overlay{position:absolute;inset:0;background:rgba(255,130,10,.13);pointer-events:none;z-index:50;opacity:1;transition:opacity .35s}
#bl-overlay.off{opacity:0}
.rt2{display:flex;align-items:center;gap:8px;padding:14px 14px 10px;flex-shrink:0;transition:background .3s}
.rtm{font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:color .3s}
.rts{font-size:10px;margin-top:1px;transition:color .3s}
.rb2{flex:1;padding:18px 14px;font-family:var(--serif);line-height:1.7;font-size:var(--reader-font-size,16px);transition:background .3s,color .3s;-webkit-overflow-scrolling:touch;word-break:break-word;overflow-y:auto}
@media(min-width:520px){.rb2{padding:24px 26px;line-height:1.95;font-size:var(--reader-font-size,15px)}}
/* Scroll mode = free scrolling (current default). Page mode = scroll-snap
   to chapter headings + section breaks so each scroll lands on a clean
   reading boundary. Both modes use overflow-y:auto so the user can still
   drag freely; page-mode just makes the scroll position snap once they
   release. This is the lowest-risk way to give the toggle real meaning
   without rebuilding the paginator. */
.rb2.scroll-mode{overflow-y:auto;scroll-snap-type:none}
.rb2.page-mode{overflow-y:auto;scroll-snap-type:y proximity;scroll-padding-top:8px}
.rb2.page-mode .epub-content > h1,
.rb2.page-mode .epub-content > h2,
.rb2.page-mode .epub-content > h3,
.rb2.page-mode .epub-content > section,
.rb2.page-mode .epub-content > .chapter-break,
.rb2.page-mode .pdf-page-wrapper{scroll-snap-align:start}
.rb2::-webkit-scrollbar{width:3px}
.rb2::-webkit-scrollbar-thumb{background:rgba(255,255,255,.1)}
.rb2 h3{font-size:17px;font-weight:500;margin-bottom:20px;font-family:var(--serif);transition:color .3s}
.rb2 p{margin-bottom:14px;transition:color .3s}
@media(min-width:520px){.rb2 p{margin-bottom:18px}}
/* ── Faithful EPUB rendering ──
   The book's own CSS controls typography inside .epub-content. We only set
   sensible defaults at this scope; the book's stylesheet (scoped in the
   parser) overrides them where it cares to. Theme color overrides are
   applied via JS (applyReaderTheme in app.js) so they win regardless of
   the book's CSS specificity. */
.rb2 .epub-content{font-size:var(--reader-font-size,16px);line-height:1.7;letter-spacing:.01em;transition:color .3s,background .3s}
@media(min-width:520px){.rb2 .epub-content{font-size:var(--reader-font-size,15px);line-height:1.65}}
.rb2 .epub-content img,.rb2 .epub-content svg,.rb2 .epub-content picture{max-width:100%;height:auto;transition:filter .3s}
.rb2 .epub-content figure{margin:1em 0;text-align:center}
.rb2 .epub-content table{max-width:100%;border-collapse:collapse}
.rb2 .epub-content pre{white-space:pre-wrap;overflow-x:auto}

/* Highlights inside the book's content keep their own color */
.rb2 .epub-content [class*="highlight"]{background-color:rgba(232,168,48,.26) !important}

/* ── PDF page host ── */
.rb2 .pdf-page-host{overflow:auto;width:100%;height:100%;min-height:60vh;display:flex;justify-content:center;align-items:center;padding:4px 0;touch-action:pinch-zoom}
.rb2 .pdf-page-host canvas{width:100%;max-width:100%;height:auto;display:block;background:#fff;will-change:transform;user-select:none;-webkit-user-select:none;image-rendering:auto;image-rendering:-webkit-optimize-contrast;border-radius:2px;box-shadow:0 1px 3px rgba(0,0,0,.18)}
/* PDF page wrapper: no CSS transform — that approach caused a Huawei
   WebView quirk where creating/destroying the GPU compositing layer
   for transform:scale produced a visible zoom-in/zoom-out flicker on
   every page turn. We size the wrapper directly via inline width (set
   in _applyPdfZoomToVisible) so font-slider zoom changes actual flow
   layout instead of going through the GPU compositor. */
.rb2 .pdf-page-wrapper{display:block;width:100%}
/* Invisible text layer over the canvas — selection makes it visible via ::selection */
.rb2 .pdf-text-layer{position:absolute;left:0;top:0;color:transparent;cursor:text;user-select:text;-webkit-user-select:text}
.rb2 .pdf-text-layer span{color:transparent;position:absolute;white-space:pre;cursor:text;user-select:text;-webkit-user-select:text}
.rb2 .pdf-text-layer ::selection{background:rgba(106,76,233,.35);color:transparent}
.rb2 .pdf-text-layer ::-moz-selection{background:rgba(106,76,233,.35);color:transparent}
.ha{background:linear-gradient(180deg,rgba(255,213,79,.0) 30%,rgba(255,213,79,.45) 30%);border-radius:2px;padding:1px 1px;box-decoration-break:clone;-webkit-box-decoration-break:clone}
.hv{background:linear-gradient(180deg,rgba(149,117,255,.0) 30%,rgba(149,117,255,.45) 30%);border-radius:2px;padding:1px 1px;box-decoration-break:clone;-webkit-box-decoration-break:clone}
.rf2{padding:10px 16px 14px;flex-shrink:0;transition:background .3s}

/* ── IMMERSIVE READER MODE ──
   When the reader screen has .immersive, the top toolbar and bottom
   footer hide off-screen, leaving only the book content. Adding the
   .immersive-show class (set on center tap) slides them back in.
   Transitions are transform+opacity — the elements still take up DOM
   layout space, but visually they're collapsed. To get TRUE full-screen
   we use position:absolute on the bars and let .rb2 fill the parent.
   The CSS uses position:absolute on the chrome so .rb2 can be a single
   full-height scrollable surface. */
#s-reader.immersive {
  position: relative;
}
#s-reader.immersive .rt2,
#s-reader.immersive .rf2 {
  position: absolute;
  left: 0; right: 0;
  z-index: 50;
  background: var(--bg1);
  border-color: var(--bdr);
  transition: transform .25s ease-out, opacity .2s ease-out;
  will-change: transform, opacity;
}
#s-reader.immersive .rt2 { top: 0; }
#s-reader.immersive .rf2 { bottom: 0; border-top: 1px solid var(--bdr); }
/* Hidden by default in immersive mode (slid off-screen, faded) */
#s-reader.immersive:not(.immersive-show) .rt2 {
  transform: translateY(-100%);
  opacity: 0;
  pointer-events: none;
}
#s-reader.immersive:not(.immersive-show) .rf2 {
  transform: translateY(100%);
  opacity: 0;
  pointer-events: none;
}
/* When shown, slide back in */
#s-reader.immersive.immersive-show .rt2,
#s-reader.immersive.immersive-show .rf2 {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
}
/* In immersive mode, the body scrolls under the full screen height —
   not constrained between chrome bars. */
#s-reader.immersive .rb2 {
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
  padding-top: 24px;
  padding-bottom: 24px;
}
/* Status bar safe area (Capacitor with notch / camera cutout) */
@supports (padding: env(safe-area-inset-top)) {
  #s-reader.immersive .rb2 {
    padding-top: 24px;
    padding-bottom: 24px;
  }
  #s-reader.immersive .rt2 {
    padding-top: 14px;
  }
  #s-reader.immersive .rf2 {
    padding-bottom: 14px;
  }
}

/* Settings panel positioning in immersive: anchor to bottom, above rf2 */
#s-reader.immersive .cp {
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  z-index: 51;
  background: var(--bg1);
  border-top: 1px solid var(--bdr);
  max-height: 60vh;
  overflow-y: auto;
}
/* When chrome bars are showing, push the cpanel up so it doesn't
   overlap the bottom footer (rf2). The transform value matches the
   space rf2 takes when visible. */
#s-reader.immersive.immersive-show .cp {
  bottom: 120px;
}
@supports (padding: env(safe-area-inset-bottom)) {
  #s-reader.immersive.immersive-show .cp {
    bottom: calc(120px + env(safe-area-inset-bottom, 0px));
  }
}

/* Hide the settings with the reader chrome, retaining its open state. */
#s-reader.immersive:not(.immersive-show) .cp {
  visibility: hidden;
  pointer-events: none;
}
#s-reader.immersive:not(.immersive-show) .rt2,
#s-reader.immersive:not(.immersive-show) .rf2 {
  visibility: hidden;
}
.reader-pagebar{display:flex;gap:10px;margin-top:10px}
.pagebar-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;
  min-height:48px;padding:0 16px;border-radius:10px;
  background:var(--bg2);border:1px solid var(--bdr);color:var(--fg1);
  font-family:var(--sans);font-size:14px;font-weight:600;cursor:pointer;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:background .15s,opacity .15s,transform .08s}
.pagebar-btn:hover{background:var(--bg3)}
.pagebar-btn:active{transform:scale(.97);opacity:.85}
.pagebar-btn:disabled{opacity:.35;cursor:not-allowed}
.pagebar-btn svg{width:18px;height:18px;stroke:currentColor;stroke-width:2.4;fill:none;flex-shrink:0}
.reader-page-nav{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:8px}
.reader-nav-btn{flex:1;background:var(--bg2);border:1px solid var(--bdr);border-radius:8px;padding:10px;color:var(--fg1);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s,opacity .15s;-webkit-tap-highlight-color:transparent}
.reader-nav-btn:hover{background:var(--bg3)}
.reader-nav-btn:active{opacity:.6}
.reader-nav-btn svg{width:18px;height:18px;stroke:currentColor;stroke-width:2;fill:none}
.ps{width:100%;height:6px;border-radius:3px;cursor:pointer;position:relative;margin-bottom:10px;transition:background .3s}
.psf{height:100%;border-radius:3px;background:var(--brand-grad);pointer-events:none}
.fr{display:flex;justify-content:space-between}
.fi{font-size:11px;transition:color .3s}
.cp{flex-shrink:0;padding:16px 18px;border-top:1px solid;transition:background .3s,border-color .3s}
.cr{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.cr:last-child{margin-bottom:0}
.cl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;width:76px;flex-shrink:0;transition:color .3s}
.thbtn{padding:6px 14px;border-radius:8px;border:1px solid;background:transparent;cursor:pointer;font-size:12px;font-family:var(--sans);transition:all .15s;-webkit-tap-highlight-color:transparent}
.thbtn.on{background:var(--adim);border-color:var(--ac)!important;color:var(--ac2)!important}
.rsl{flex:1;accent-color:var(--ac);cursor:pointer}
.rv{font-size:11px;min-width:32px;text-align:right;transition:color .3s}

/* ── TOGGLE ── */
.tg{width:40px;height:23px;border-radius:12px;position:relative;cursor:pointer;transition:background .2s;flex-shrink:0;-webkit-tap-highlight-color:transparent}
.tk{width:17px;height:17px;background:#fff;border-radius:50%;position:absolute;top:3px;left:3px;transition:transform .2s;pointer-events:none}
.tg.on .tk{transform:translateX(17px)}
.tg-lbl{font-size:11px;margin-left:6px;transition:color .3s}

/* ── BOOKMARKS ── */
.bmi{display:flex;align-items:center;gap:12px;padding:14px 15px;background:var(--bg2);border:1px solid var(--bdr);border-radius:13px;margin-bottom:9px;cursor:pointer;transition:border-color .15s,background .3s;-webkit-tap-highlight-color:transparent}
.bmi:hover{border-color:var(--bg4)}
.bmd{width:10px;height:10px;border-radius:50%;background:var(--brand-grad);flex-shrink:0}
.bmt{font-size:13px;font-weight:600;color:var(--fg0);transition:color .3s}
.bmm{font-size:11px;color:var(--fg2);margin-top:2px;transition:color .3s}

/* ── HIGHLIGHTS ── */
.hi{padding:14px 16px;background:var(--bg2);border-radius:13px;margin-bottom:9px;border:1px solid var(--bdr);border-left:3px solid var(--ac);transition:background .3s,border-color .3s}
.hi.pk{border-left-color:var(--gold)}
.hq{font-family:var(--serif);font-size:13px;color:var(--fg0);line-height:1.7;margin-bottom:7px;font-style:italic;transition:color .3s}
.hm{display:flex;align-items:center;justify-content:space-between}
.hs{font-size:11px;color:var(--fg2);transition:color .3s}
.hch{font-size:10px;font-weight:700;padding:2px 8px;border-radius:4px;background:var(--adim);color:var(--ac2)}
.hch.pk{background:var(--goldbg);color:var(--gold)}

/* ── SEARCH ── */
.sw{position:relative;margin-bottom:14px}
.sw svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:18px;height:18px;stroke:var(--fg2);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none;transition:stroke .3s}
#si{width:100%;background:var(--bg2);border:1px solid var(--bdr);border-radius:13px;padding:12px 14px 12px 42px;color:var(--fg0);font-family:var(--sans);font-size:14px;outline:none;transition:border-color .15s,background .3s,color .3s}
#si:focus{border-color:var(--ac)}
#si::placeholder{color:var(--fg3)}
.ri{padding:13px 15px;border-bottom:1px solid var(--bdr);cursor:pointer;transition:background .15s}
.ri:hover{background:var(--bg3)}
.rb3{font-size:10px;font-weight:700;color:var(--ac2);text-transform:uppercase;letter-spacing:.06em;margin-bottom:4px}
.rt3{font-size:13px;color:var(--fg1);line-height:1.5;transition:color .3s}
.rt3 .hit{background:rgba(232,168,48,.28);font-style:normal;border-radius:2px;padding:0 2px;color:#c08020}
.es{text-align:center;padding:40px 20px}
.es-ico{font-size:36px;display:block;margin-bottom:12px}
.es p{font-size:13px;line-height:1.6;color:var(--fg2);transition:color .3s}

/* ── SETTINGS ── */
.sg{background:var(--bg2);border:1px solid var(--bdr);border-radius:13px;overflow:hidden;margin-bottom:16px;transition:background .3s,border-color .3s}
.sr{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;border-bottom:1px solid var(--bdr);gap:12px;transition:border-color .3s}
.sr:last-child{border-bottom:none}
.srl{font-size:14px;font-weight:500;color:var(--fg0);transition:color .3s}
.srs{font-size:11px;color:var(--fg2);margin-top:2px;transition:color .3s}
.srv{font-size:12px;color:var(--fg2);transition:color .3s}
.syb{display:flex;align-items:center;gap:10px;background:var(--gbg);border:1px solid var(--gbdr);border-radius:13px;padding:13px 15px;margin-bottom:16px;transition:background .3s,border-color .3s}
.syd{width:8px;height:8px;border-radius:50%;background:var(--gr);flex-shrink:0}
.syd.go{background:var(--gold);animation:pl .8s infinite}
@keyframes pl{0%,100%{opacity:1}50%{opacity:.25}}
.syl{font-size:13px;font-weight:600;color:var(--gr)}
.sys{font-size:11px;color:var(--fg2);margin-top:1px;transition:color .3s}
.syb2{font-size:12px;padding:6px 13px;background:var(--gbg);color:var(--gr);border:1px solid var(--gbdr);border-radius:8px;cursor:pointer;font-family:var(--sans);font-weight:600;white-space:nowrap;transition:filter .15s}
.syb2:hover{filter:brightness(1.15)}

/* Affiliate account */
.affiliate-menu{width:100%;border:0;background:transparent;color:inherit;font-family:var(--sans);cursor:pointer}
.affiliate-menu-icon{width:36px;height:36px;display:grid;place-items:center;flex:none;border-radius:8px;background:var(--adim);color:var(--ac2)}
.affiliate-menu-icon svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.8}
.affiliate-menu-arrow{font-size:26px;line-height:1;color:var(--fg2)}
.affiliate-screen{padding-top:4px;max-width:760px;width:100%;margin:0 auto}
.affiliate-loading,.affiliate-empty{padding:28px 16px;text-align:center;color:var(--fg2);font-size:13px}
.affiliate-message{margin:0 0 12px;padding:11px 13px;border:1px solid var(--bdr);border-radius:8px;background:var(--bg2);color:var(--fg1);font-size:12px}
.affiliate-message.error{border-color:rgba(239,83,80,.45);color:var(--red)}
.affiliate-message.success{border-color:var(--gbdr);color:var(--gr)}
.affiliate-identity{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:16px 0 14px}
.affiliate-name{font-size:20px;font-weight:700;color:var(--fg0)}
.affiliate-email{font-size:12px;color:var(--fg2);margin-top:3px;overflow-wrap:anywhere}
.affiliate-code-wrap{text-align:right;flex:none}
.affiliate-code-wrap span{display:block;color:var(--gr);font-size:10px;text-transform:uppercase;margin-bottom:4px}
.affiliate-code-wrap strong{font-size:12px;color:var(--ac2);font-family:monospace}
.affiliate-metrics{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--bdr);border-radius:8px;background:var(--bg2);overflow:hidden;margin-bottom:16px}
.affiliate-metrics div{min-width:0;padding:14px 8px;text-align:center;border-right:1px solid var(--bdr);border-bottom:1px solid var(--bdr)}
.affiliate-metrics div:nth-child(3n){border-right:0}.affiliate-metrics div:nth-last-child(-n+2){border-bottom:0}
.affiliate-metrics strong{display:block;font-size:15px;color:var(--fg0);overflow-wrap:anywhere}.affiliate-metrics span{display:block;margin-top:3px;font-size:10px;color:var(--fg2)}
.affiliate-panel{margin-bottom:14px;padding:16px;border:1px solid var(--bdr);border-radius:8px;background:var(--bg2)}
.affiliate-panel h2{font-size:15px;line-height:1.25;color:var(--fg0);margin:0 0 10px;letter-spacing:0}.affiliate-panel p{font-size:11px;line-height:1.45;color:var(--fg2);margin:3px 0}
.affiliate-panel-head{display:flex;justify-content:space-between;gap:12px;margin-bottom:12px}
.affiliate-select,.affiliate-link,.affiliate-form input,.affiliate-form select,.affiliate-form textarea{width:100%;box-sizing:border-box;border:1px solid var(--bdr);border-radius:7px;background:var(--bg1);color:var(--fg0);font:13px var(--sans);padding:10px 11px;outline:none}
.affiliate-select{margin-bottom:8px}.affiliate-link{font-family:monospace;font-size:11px}
.affiliate-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px}.affiliate-actions button,.affiliate-primary{min-height:40px;border:1px solid var(--bdr);border-radius:7px;background:var(--bg3);color:var(--fg0);font:600 13px var(--sans);cursor:pointer}.affiliate-actions .primary,.affiliate-primary{background:var(--ac);border-color:var(--ac);color:#fff}
.affiliate-form{display:grid;gap:12px}.affiliate-form label{display:grid;gap:6px;color:var(--fg1);font-size:11px}.affiliate-form textarea{min-height:76px;resize:vertical}.affiliate-primary{padding:9px 14px}.affiliate-primary:disabled{opacity:.55}
.affiliate-withdrawal{display:flex;align-items:center;justify-content:space-between;gap:16px}.affiliate-withdrawal .affiliate-primary{flex:none}
.affiliate-activity{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 0;border-bottom:1px solid var(--bdr)}.affiliate-activity:last-child{border-bottom:0}.affiliate-activity-title{font-size:12px;color:var(--fg0)}.affiliate-activity-detail{font-size:10px;color:var(--fg2);margin-top:3px}.affiliate-activity-right{text-align:right;font-size:12px;color:var(--fg0)}.affiliate-status{display:block;margin-top:3px;font-size:9px;text-transform:uppercase;color:var(--fg2)}
@media(max-width:420px){.affiliate-metrics{grid-template-columns:repeat(2,1fr)}.affiliate-metrics div:nth-child(3n){border-right:1px solid var(--bdr)}.affiliate-metrics div:nth-child(2n){border-right:0}.affiliate-metrics div:nth-last-child(-n+2){border-bottom:1px solid var(--bdr)}.affiliate-metrics div:last-child{border-bottom:0}.affiliate-withdrawal{align-items:stretch;flex-direction:column}}
.crypto-badge{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;color:var(--gr);background:var(--gbg);border:1px solid var(--gbdr);border-radius:6px;padding:3px 8px}
.crypto-badge svg{width:12px;height:12px;stroke:var(--gr);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
select{background:var(--bg3);color:var(--fg0);border:1px solid var(--bg4);border-radius:8px;padding:6px 10px;font-family:var(--sans);font-size:13px;outline:none;cursor:pointer;transition:background .3s,color .3s}

/* ── ABOUT ── */
.about-card{background:var(--bg2);border:1px solid var(--bdr);border-radius:16px;padding:20px;text-align:center;margin-bottom:16px;transition:background .3s}
.about-name{font-size:20px;font-weight:700;letter-spacing:-.3px}
.about-name .hs{background:var(--brand-grad);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.about-tag{font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--fg3);margin-top:4px;transition:color .3s}
.about-ver{font-size:11px;color:var(--fg2);margin-top:8px;transition:color .3s}

/* ── TOAST ── */
.toast{position:fixed;bottom:calc(90px + env(safe-area-inset-bottom,0px));left:50%;transform:translateX(-50%);background:var(--bg4);border:1px solid var(--bdr);border-radius:20px;padding:8px 18px;font-size:12px;color:var(--fg0);white-space:nowrap;z-index:999;opacity:0;transition:opacity .25s;pointer-events:none;font-weight:500;max-width:90vw;overflow:hidden;text-overflow:ellipsis}
.toast.show{opacity:1}

/* ── IMPORT PROGRESS PILL (floating, tappable) ──
   Compact button-style indicator pinned just above the bottom nav.
   Tapping it navigates to the Stats page, where the full per-import
   progress UI lives. Only visible while at least one import is active. */
#import-prog{position:fixed;left:50%;bottom:calc(96px + env(safe-area-inset-bottom,0px));transform:translate(-50%,12px);width:auto;max-width:90vw;background:var(--bg4);border:1px solid var(--bdr);border-radius:24px;padding:8px 16px 8px 12px;display:none;align-items:center;gap:10px;z-index:998;opacity:0;transition:opacity .25s,transform .25s;box-shadow:0 6px 20px rgba(0,0,0,.45);cursor:pointer;font-family:var(--sans);color:var(--fg0)}
#import-prog.show{display:flex;opacity:1;transform:translate(-50%,0)}
#import-prog:active{transform:translate(-50%,1px)}
.ip-spinner{width:16px;height:16px;border-radius:50%;border:2px solid rgba(123,95,219,.25);border-top-color:#a07ef5;animation:ip-spin .9s linear infinite;flex:0 0 auto}
@keyframes ip-spin{to{transform:rotate(360deg)}}
.ip-text{min-width:0;text-align:left}
.ip-title{font-size:12px;font-weight:600;color:var(--fg0);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px}
.ip-step{font-size:10px;color:var(--fg2);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px}
/* Success state — green spinner ring (no rotation animation when done) */
#import-prog.success .ip-spinner{border-color:rgba(76,175,125,.25);border-top-color:#4caf7d;animation:none}
/* Error state — red */
#import-prog.error .ip-spinner{border-color:rgba(227,90,79,.25);border-top-color:#e35a4f;animation:none}

/* ── STATS PAGE IMPORTS LIST ──
   Each in-flight or recently-finished import gets a row here. Active
   imports show a progress bar with the current step text; finished ones
   show a check or × with the final message. */
#stats-imports-list{display:flex;flex-direction:column;gap:8px}
.imp-row{background:var(--bg2);border:1px solid var(--bdr);border-radius:11px;padding:11px 13px}
.imp-row-top{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.imp-row-icon{width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;flex:0 0 auto}
.imp-row.active   .imp-row-icon{border:2px solid rgba(123,95,219,.25);border-top-color:#a07ef5;animation:ip-spin .9s linear infinite}
.imp-row.success  .imp-row-icon{background:rgba(76,175,125,.18);color:#4caf7d}
.imp-row.error    .imp-row-icon{background:rgba(227,90,79,.18);color:#e35a4f}
.imp-row-title{font-size:13px;font-weight:600;color:var(--fg0);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.imp-row-pct{font-size:11px;color:var(--fg2);font-variant-numeric:tabular-nums}
.imp-row-step{font-size:11px;color:var(--fg2);margin-bottom:7px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.imp-row-bar-bg{height:4px;border-radius:2px;background:rgba(255,255,255,.08);overflow:hidden;position:relative}
.imp-row-bar-fill{height:100%;background:linear-gradient(90deg,#7B5FDB,#A07EF5);width:0%;transition:width .25s ease-out;border-radius:2px}
.imp-row.indeterminate .imp-row-bar-fill{width:40%;background:linear-gradient(90deg,transparent,#7B5FDB 30%,#A07EF5 70%,transparent);background-size:200% 100%;animation:imp-slide 1.4s linear infinite;transition:none}
@keyframes imp-slide{0%{transform:translateX(-100%)}100%{transform:translateX(250%)}}
.imp-row.success .imp-row-bar-fill{background:#4caf7d;width:100%;animation:none;transition:none}
.imp-row.error   .imp-row-bar-fill{background:#e35a4f;width:100%;animation:none;transition:none}
.imp-row.error   .imp-row-bar-bg{background:rgba(227,90,79,.12)}
/* Cancel button for active imports. Sits inside .imp-row-top after the percentage. */
.imp-row-cancel{background:transparent;border:none;color:var(--fg2);width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:16px;line-height:1;cursor:pointer;padding:0;margin-left:4px;flex:0 0 auto;transition:background .15s ease,color .15s ease}
.imp-row-cancel:hover,.imp-row-cancel:focus-visible{background:rgba(227,90,79,.18);color:#e35a4f;outline:none}
.imp-row-cancel:active{background:rgba(227,90,79,.28)}

/* ── OFFLINE BANNER ── */
#offline-banner{display:none;position:fixed;top:0;left:50%;transform:translateX(-50%);width:100%;max-width:1100px;background:var(--goldbg);border-bottom:1px solid var(--goldbdr);padding:8px 16px;font-size:12px;color:var(--gold);font-weight:600;text-align:center;z-index:500}
#offline-banner.show{display:block}

/* ── ERROR SCREEN ── */
#error-screen{position:absolute;inset:0;background:var(--bg0);z-index:2000;display:none;flex-direction:column;align-items:center;justify-content:center;padding:32px;text-align:center}
#error-screen.show{display:flex}
.err-ico{font-size:40px;margin-bottom:16px}
.err-title{font-size:18px;font-weight:600;color:var(--fg0);margin-bottom:8px}
.err-msg{font-size:13px;color:var(--fg2);line-height:1.6;margin-bottom:24px}
.err-btn{background:var(--ac);color:#fff;border:none;border-radius:10px;padding:10px 24px;font-size:14px;font-weight:600;cursor:pointer;font-family:var(--sans)}

/* ── COVER COLORS ── */
.ca{background:#1c1836}.cb{background:#162418}.cc{background:#181228}.cd{background:#251a0a}.ce{background:#161620}.cf{background:#102018}

@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}}

/* ═══════════════════════════════════════
   NEW FEATURES CSS
═══════════════════════════════════════ */

/* ── CATEGORY / FILTER CHIPS ── */
.filter-row{display:flex;gap:8px;overflow-x:auto;padding:4px 0 12px;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.filter-row::-webkit-scrollbar{display:none}
.chip{padding:6px 14px;border-radius:20px;border:1px solid var(--bdr);background:var(--bg2);color:var(--fg2);font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap;transition:all .15s;flex-shrink:0;-webkit-tap-highlight-color:transparent}
.chip:hover{border-color:var(--ac);color:var(--ac2)}
.chip.on{background:var(--adim);border-color:var(--ac);color:var(--ac2)}

/* ── SORT BAR ── */
.sort-bar{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.sort-lbl{font-size:11px;color:var(--fg2)}
.sort-sel{font-size:11px;background:var(--bg2);color:var(--fg1);border:1px solid var(--bdr);border-radius:7px;padding:4px 8px;font-family:var(--sans);cursor:pointer;outline:none}

/* ── READING TIMER BADGE ── */
.timer-badge{display:inline-flex;align-items:center;gap:5px;background:var(--adim);color:var(--ac2);border-radius:8px;padding:4px 10px;font-size:11px;font-weight:600;margin-left:auto}
.timer-badge svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.timer-dot{width:6px;height:6px;border-radius:50%;background:var(--red);flex-shrink:0;animation:timerPulse 1s ease infinite}
@keyframes timerPulse{0%,100%{opacity:1}50%{opacity:.3}}

/* ── NOTES / ANNOTATIONS ── */
#s-notes .note-card{background:var(--bg2);border:1px solid var(--bdr);border-left:3px solid var(--gold);border-radius:13px;padding:14px 16px;margin-bottom:10px}
.note-text{font-size:13px;color:var(--fg0);line-height:1.65;margin-bottom:8px;white-space:pre-wrap;word-break:break-word}
.note-meta{font-size:11px;color:var(--fg2);display:flex;justify-content:space-between;align-items:center}
.note-input-wrap{padding:12px 0}
.note-input{width:100%;background:var(--bg2);border:1px solid var(--bdr);border-radius:12px;padding:12px 14px;color:var(--fg0);font-family:var(--serif);font-size:14px;line-height:1.6;resize:none;outline:none;min-height:80px;transition:border-color .15s}
.note-input:focus{border-color:var(--ac)}
.note-input::placeholder{color:var(--fg3)}
.note-save-btn{margin-top:8px;padding:8px 18px;background:var(--adim);color:var(--ac2);border:none;border-radius:9px;font-family:var(--sans);font-size:13px;font-weight:600;cursor:pointer;transition:background .15s}
.note-save-btn:hover{background:#2e2562}

/* ── READING STATS SCREEN ── */
#s-stats .stat-big{font-size:42px;font-weight:700;color:var(--fg0);line-height:1}
#s-stats .stat-unit{font-size:13px;color:var(--fg2);margin-top:4px}
#s-stats .prog-bar-wrap{margin:8px 0}
#s-stats .prog-bar-bg{height:8px;background:var(--bg4);border-radius:4px;overflow:hidden}
#s-stats .prog-bar-fill{height:100%;border-radius:4px;background:var(--brand-grad);transition:width .6s ease}
#s-stats .week-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin:12px 0}
#s-stats .day-bar{display:flex;flex-direction:column;align-items:center;gap:4px}
#s-stats .day-fill{width:100%;border-radius:3px;background:var(--adim);min-height:4px;transition:height .4s ease}
#s-stats .day-fill.active{background:var(--brand-grad)}
#s-stats .day-lbl{font-size:9px;color:var(--fg3)}
.streak-fire{font-size:28px;margin-right:8px}

/* ── TABLE OF CONTENTS ── */
#toc-panel{position:absolute;top:0;right:0;bottom:0;width:76%;max-width:280px;background:var(--bg2);border-left:1px solid var(--bdr);z-index:100;transform:translateX(100%);transition:transform .3s ease;overflow-y:auto;padding:16px}
#toc-panel.open{transform:translateX(0)}
.toc-item{padding:10px 0;border-bottom:1px solid var(--bdr);cursor:pointer;font-size:13px;color:var(--fg1);display:flex;align-items:center;gap:8px;transition:color .15s}
.toc-item:hover{color:var(--ac2)}
.toc-item.active{color:var(--ac2);font-weight:600}
.toc-ch{font-size:10px;color:var(--fg3);min-width:28px}
.toc-overlay{position:absolute;inset:0;background:rgba(0,0,0,.4);z-index:99;display:none}
#toc-panel.open ~ .toc-overlay{display:block}

/* ── BOOK CARD LIST VIEW ── */
.bg.list-view{grid-template-columns:1fr !important}
.bg.list-view .bk{display:flex;flex-direction:row;border-radius:13px}
.bg.list-view .bkc{aspect-ratio:unset;width:56px;height:80px;flex-shrink:0;border-radius:10px 0 0 10px}
.bg.list-view .bki{flex:1;padding:12px 14px;display:flex;flex-direction:column;justify-content:space-between}
.bg.list-view .bkt{font-size:14px;white-space:normal;-webkit-line-clamp:2;display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden}

/* ── VIEW TOGGLE ── */
.view-toggle{display:flex;gap:4px}
.view-btn{width:30px;height:30px;border-radius:7px;border:1px solid var(--bdr);background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--fg3);transition:all .15s}
.view-btn.on{background:var(--adim);border-color:var(--ac);color:var(--ac2)}
.view-btn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}

/* ── READER FONT FAMILY ── */
.font-btn{padding:5px 10px;border-radius:7px;border:1px solid var(--bdr);background:transparent;cursor:pointer;font-size:12px;color:var(--fg2);transition:all .15s}
.font-btn.on{background:var(--adim);border-color:var(--ac);color:var(--ac2)}

/* ── PAGE NAV ARROWS ── */
.page-nav{display:flex;align-items:center;gap:8px;justify-content:center;padding:8px 0}
.page-btn{width:36px;height:36px;border-radius:50%;border:1px solid var(--bdr);background:var(--bg2);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--fg2);transition:all .15s}
.page-btn:hover{border-color:var(--ac);color:var(--ac2)}
.page-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}

/* ── BOTTOM SHEET (notes/TOC) ── */
.sheet{position:absolute;bottom:0;left:0;right:0;background:var(--bg2);border-top:1px solid var(--bdr);border-radius:18px 18px 0 0;padding:16px;z-index:200;transform:translateY(100%);transition:transform .3s ease;max-height:60vh;overflow-y:auto}
.sheet.open{transform:translateY(0)}
.sheet-handle{width:36px;height:4px;background:var(--bg4);border-radius:2px;margin:0 auto 16px}
.sheet-title{font-size:14px;font-weight:600;color:var(--fg0);margin-bottom:14px}

/* ── SEARCH RESULTS IMPROVED ── */
.search-tabs{display:flex;gap:6px;margin-bottom:14px}
.stab{padding:5px 12px;border-radius:8px;border:1px solid var(--bdr);background:transparent;font-size:11px;font-weight:600;color:var(--fg2);cursor:pointer;transition:all .15s}
.stab.on{background:var(--adim);border-color:var(--ac);color:var(--ac2)}

/* ── EMPTY LIBRARY ── */
.empty-lib{text-align:center;padding:40px 20px}
.empty-lib-ico{font-size:56px;margin-bottom:16px;display:block}
.empty-lib h3{font-size:17px;font-weight:600;color:var(--fg0);margin-bottom:8px}
.empty-lib p{font-size:13px;color:var(--fg2);line-height:1.65;margin-bottom:20px}
.empty-lib-btn{display:inline-flex;align-items:center;gap:7px;background:var(--brand-grad);color:#fff;border:none;border-radius:12px;padding:12px 24px;font-family:var(--sans);font-size:14px;font-weight:600;cursor:pointer}

/* ── FAV STAR ── */
.fav-overlay{position:absolute;top:6px;right:6px;font-size:14px;line-height:1;pointer-events:none}

/* ══════════════════════════════════
   READER ONBOARDING OVERLAY

   First-time tutorial overlay. Splits the reader into three vertical
   tap zones (30 / 40 / 30 percent) matching the actual tap behavior
   in _initImmersiveTapZones. A centered card explains the controls
   and offers a dismiss button. Theme-aware via CSS variables so it
   looks correct in dark, sepia, and light modes.
══════════════════════════════════ */
.reader-onboarding{
  position:fixed;inset:0;z-index:700;
  background:rgba(0,0,0,.55);
  display:flex;align-items:center;justify-content:center;
  padding:20px;
  -webkit-tap-highlight-color:transparent;
  animation:ronb-fade-in .25s ease-out;
}
@keyframes ronb-fade-in{from{opacity:0}to{opacity:1}}

/* Three-zone illustration. Uses flex with proportional flex-grow so
   the visual matches the actual tap math (0.30 / 0.40 / 0.30). */
.ronb-zones{
  position:absolute;inset:0;
  display:flex;flex-direction:row;
  pointer-events:none;
}
.ronb-zone{
  display:flex;flex-direction:column;
  align-items:center;justify-content:center;
  border-right:1px dashed rgba(255,255,255,.18);
  color:rgba(255,255,255,.92);
  text-align:center;padding:8px;
}
.ronb-zone:last-child{border-right:none}
.ronb-zone-left{flex:30;background:rgba(255,255,255,.04)}
.ronb-zone-mid{flex:40;background:rgba(255,255,255,.08)}
.ronb-zone-right{flex:30;background:rgba(255,255,255,.04)}
.ronb-zone-label{
  font-family:var(--sans);font-size:15px;font-weight:700;
  letter-spacing:.02em;text-shadow:0 1px 3px rgba(0,0,0,.5);
  margin-bottom:6px;
}
.ronb-zone-hint{
  font-family:var(--sans);font-size:11px;font-weight:500;
  opacity:.7;text-shadow:0 1px 2px rgba(0,0,0,.4);
}

/* Explanation card on top of the zones */
.ronb-card{
  position:relative;z-index:1;
  background:var(--bg1);
  border:1px solid var(--bdr);
  border-radius:16px;
  padding:24px 22px;
  max-width:340px;width:100%;
  box-shadow:0 10px 40px rgba(0,0,0,.4);
  font-family:var(--sans);
}
.ronb-title{
  font-size:18px;font-weight:700;color:var(--fg0);
  margin-bottom:12px;
}
.ronb-body{
  font-size:14px;line-height:1.6;color:var(--fg1);
  margin-bottom:18px;
}
.ronb-list{
  list-style:none;padding:0;margin:12px 0;
}
.ronb-list li{
  padding:6px 0;font-size:13px;color:var(--fg1);
  border-bottom:1px solid var(--bdr);
}
.ronb-list li:last-child{border-bottom:none}
.ronb-list strong{color:var(--ac2);font-weight:700}
.ronb-ok{
  display:block;width:100%;
  background:var(--brand-grad);color:#fff;
  border:none;border-radius:10px;
  padding:12px 24px;
  font-family:var(--sans);font-size:14px;font-weight:600;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:transform .08s,opacity .15s;
}
.ronb-ok:hover{opacity:.92}
.ronb-ok:active{transform:scale(.98)}

/* Compact tweaks for small phones — collapse the zone hint, smaller card padding */
@media (max-width:380px){
  .ronb-card{padding:20px 18px;max-width:300px}
  .ronb-title{font-size:16px}
  .ronb-body{font-size:13px}
  .ronb-zone-hint{display:none}
}
/* ── TTS Phase 3: sentence highlighting ──
   The chunks tts.js feeds to the engine are wrapped in <span class="tts-chunk"
   data-tts-idx="N"> when the chapter renders. As each chunk speaks, tts.js
   toggles .tts-current onto the matching span so the user can read along
   with the spoken text. The styling is subtle on purpose — strong enough
   to track at a glance, light enough not to fight the book's typography. */
.tts-chunk { transition: background-color .2s ease; }
.tts-chunk.tts-current {
  background: rgba(139,111,232,.18);
  border-radius: 3px;
  box-shadow: 0 0 0 2px rgba(139,111,232,.18);
}
::highlight(bookhive-tts-current){color:inherit;background-color:rgba(245,200,74,.42);text-decoration:underline rgba(245,200,74,.9) 2px}
.tts-range-overlay{position:absolute;inset:0;z-index:8;overflow:hidden;pointer-events:none}
.tts-range-overlay i{position:absolute;display:block;border-radius:3px;background:rgba(245,200,74,.38);box-shadow:inset 0 -2px 0 rgba(245,200,74,.9);mix-blend-mode:multiply}
[data-theme="dark"] .tts-range-overlay i,.dark .tts-range-overlay i{mix-blend-mode:screen;background:rgba(245,200,74,.28)}
.tts-readalong{position:absolute;z-index:58;left:50%;bottom:76px;transform:translate(-50%,12px);display:flex;align-items:flex-start;gap:10px;width:min(680px,calc(100% - 28px));box-sizing:border-box;padding:11px 13px;border:1px solid var(--bdr);border-radius:8px;background:rgba(18,18,24,.94);color:#f7f5ff;box-shadow:0 8px 28px rgba(0,0,0,.35);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s ease,transform .18s ease;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
.tts-readalong.on{opacity:1;visibility:visible;transform:translate(-50%,0)}
.tts-readalong span{flex:none;padding-top:2px;color:#f5c84a;font-size:10px;font-weight:700;text-transform:uppercase;white-space:nowrap}
.tts-readalong strong{min-width:0;display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:3;font-size:13px;line-height:1.45;font-weight:500;letter-spacing:0}
@media(max-width:520px){.tts-readalong{bottom:68px;gap:7px;padding:9px 10px}.tts-readalong strong{font-size:12px;-webkit-line-clamp:2}}

/* Safari does not expose the Chromium install prompt. Give iPhone/iPad users
   the native Share -> Add to Home Screen path, then stay out of the way. */
.ios-install-guide{position:fixed;z-index:1200;top:calc(10px + env(safe-area-inset-top,0px));left:12px;right:12px;display:flex;align-items:center;gap:12px;padding:12px 12px 12px 15px;border:1px solid rgba(139,111,232,.55);border-radius:14px;background:rgba(24,22,32,.96);color:#f7f5ff;box-shadow:0 8px 30px rgba(0,0,0,.38);font-family:var(--sans);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.ios-install-guide[hidden]{display:none}
.ios-install-copy{display:flex;min-width:0;flex:1;flex-direction:column;gap:3px}
.ios-install-copy strong{font-size:13px;line-height:1.3}
.ios-install-copy span{font-size:12px;line-height:1.4;color:rgba(247,245,255,.76)}
.ios-install-copy em{color:#c9bbff;font-style:normal;font-weight:700}
.ios-install-guide button{width:34px;height:34px;flex:0 0 34px;border:0;border-radius:50%;background:rgba(255,255,255,.09);color:#fff;font-size:24px;line-height:1;cursor:pointer}
.tts-page-input {
  width: 68px;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--bdr);
  border-radius: 7px;
  background: var(--bg2);
  color: var(--fg0);
  font: 12px var(--sans);
}
.tts-page-total {
  flex: 1;
  color: var(--fg2);
  font: 11px var(--sans);
}
.tts-page-apply {
  min-height: 30px;
  padding: 5px 12px;
  border: 1px solid var(--ac);
  border-radius: 7px;
  background: transparent;
  color: var(--ac);
  font: 600 12px var(--sans);
  cursor: pointer;
}
.tts-page-apply:disabled {
  cursor: default;
  opacity: .45;
}

/* Keep the iOS app frame anchored; only the content panels scroll. */
html.ios-web,html.ios-web body{width:100%;height:100%;overflow:hidden;overscroll-behavior:none}
html.ios-web body{position:fixed;inset:0;background:var(--bg1)}
html.ios-web #shell{height:var(--web-viewport-height,100dvh);min-height:0}
html.ios-web .sc{overscroll-behavior:none}
/* Avoid Safari's automatic input zoom without disabling pinch zoom. */
html.ios-web input,html.ios-web textarea,html.ios-web select{font-size:16px}

/* The measured Home Screen window includes the safe area. Reserve it once
   in #shell's border-box padding; do not subtract it from this height again. */
html.ios-standalone #shell{position:fixed;inset:0;height:auto;max-height:none}
html.ios-standalone #shell > .scr{flex:1;height:auto}
html.ios-standalone.ios-keyboard #shell{bottom:auto;height:var(--web-viewport-height,100vh)}
html.ios-standalone .bn{padding-bottom:4px}
