:root{
  /* retro-futurism chrome: gunmetal chassis + copper/teal duotone */
  --chassis:#15120f;--chassis2:#1c1712;--panel:#211b15;--panel2:#281f17;
  --copper:#c9834a;--copper-b:#e8ad6f;--teal:#4fd6c4;--teal-d:#2b7f78;
  --chrome:#ece2cf;--chrome-dim:#a89a83;--line:rgba(201,131,74,.32);
  --disp:'Zen Dots',ui-sans-serif,system-ui;--mono:'JetBrains Mono',ui-monospace,monospace;
  --serif:'Noto Serif SC',"Songti SC","STSong",serif;
  --safe-t:env(safe-area-inset-top,0px);--safe-b:env(safe-area-inset-bottom,0px);
  --safe-l:env(safe-area-inset-left,0px);--safe-r:env(safe-area-inset-right,0px);
  --read-fs:18px;
}
/* ---- reading-mode palettes (low-blue, long-read friendly) ----
   U15e: green white point lowered (~10-11% luminance cut) to ease
   OLED/LED night-reading glare; --read-ink/--read-ink-dim contrast against
   the new backgrounds verified >=4.6:1 (WCAG AA floor is 4.5:1). Night
   theme is already dark and untouched.
   U-toolbar-redo: retired the third ("皇木" imperial-wood) reading theme —
   it duplicated the page's own dark chrome (see body{} below) rather than
   giving readers a distinct option. Only two eye-care choices remain: this
   base rule *is* day/green now (no separate [data-theme="green"] override
   needed since it's the default), with night as the sole variant. */
.reader{
  --read-bg:#c8dfcb;--read-bg2:#bad5be;--read-ink:#213325;--read-ink-dim:#4b6350;--read-accent:#2f6b46;--read-line:rgba(33,51,37,.14);--read-tex:none;
}
.reader[data-theme="night"]{--read-bg:#211a12;--read-bg2:#291f15;--read-ink:#e8c98a;--read-ink-dim:#b8945f;--read-accent:#e8c98a;--read-line:rgba(232,201,138,.14);--read-tex:none;}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;min-height:100%}
/* U-toolbar-redo: the "皇木"(imperial wood) zitan→nanmu gradient used to
   live as a selectable *reading* theme (.reader[data-theme="imperial"]);
   it duplicated the site's own dark chrome and read as a no-op background
   swap. Retired as a reading option and re-homed here as the actual page
   background instead — moved, not deleted. */
body{background:linear-gradient(160deg,#2b1a16 0%,#231411 100%);color:var(--chrome);font-family:var(--mono);font-size:14px;line-height:1.6;overflow-x:hidden}
a{color:inherit;text-decoration:none}
button{font-family:inherit;border:none;background:none;color:inherit;cursor:pointer}
:focus-visible{outline:2px solid var(--teal);outline-offset:2px}

/* ---- retro CRT backdrop ---- */
.crt-bg{position:fixed;inset:0;z-index:0;pointer-events:none}
.crt-bg canvas{width:100%;height:100%;display:block;opacity:.55}
.crt-bg .scan{position:absolute;inset:0;background:repeating-linear-gradient(0deg,rgba(0,0,0,.18) 0 1px,transparent 1px 3px);opacity:.4}
.crt-bg .vig{position:absolute;inset:0;background:radial-gradient(ellipse at center,transparent 55%,rgba(0,0,0,.55) 100%)}

.wrap{position:relative;z-index:1;max-width:900px;margin:0 auto;padding:calc(14px + var(--safe-t)) clamp(12px,4vw,26px) calc(120px + var(--safe-b))}

/* ---- top bar ---- */
.top{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;border:1px solid var(--line);background:linear-gradient(90deg,rgba(201,131,74,.10),transparent 60%),var(--panel);padding:11px 14px;border-radius:2px}
.seal{display:flex;align-items:center;gap:10px;min-width:0}
.seal svg{width:34px;height:34px;flex:0 0 34px}
.seal b{font:400 15px/1.2 var(--disp);letter-spacing:.04em;color:var(--chrome);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.seal small{font:400 9.5px/1.5 var(--mono);letter-spacing:.12em;color:var(--copper-b);display:block;margin-top:3px;text-transform:uppercase}
.nav{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.nav a{position:relative;font:600 10.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--chrome-dim);border:1px solid rgba(236,226,207,.14);padding:8px 9px;border-radius:2px}
.nav a::before{content:'';position:absolute;top:-8px;bottom:-8px;left:-1px;right:-1px}
.nav a:hover{border-color:var(--teal);color:var(--teal)}
.nav a.active{background:var(--copper);border-color:var(--copper);color:#1a1410}
.lang-toggle{font:700 10.5px/1 var(--mono);letter-spacing:.08em;color:#1a1410;background:var(--copper-b);border:1px solid var(--copper-b);padding:8px 10px;border-radius:2px}
.lang-toggle:hover{background:var(--teal);border-color:var(--teal)}

/* ---- bookshelf ---- */
.shelf{margin-top:14px;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px}
.book{text-align:left;border:1px solid var(--line);background:var(--panel);padding:14px;border-radius:2px;cursor:pointer;position:relative;overflow:hidden}
.book::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(180deg,var(--copper),var(--teal));opacity:.5;transition:opacity .2s ease}
.book:hover{border-color:var(--copper-b)}
.book.active{border-color:var(--teal);background:var(--panel2)}
.book.active::before{opacity:1}
.book h3{font:400 15px/1.3 var(--serif);color:var(--chrome);margin:0 0 6px;font-weight:700}
.book .bk-sub{font:400 9.5px/1.5 var(--mono);letter-spacing:.08em;color:var(--teal);text-transform:uppercase;margin:0 0 8px}
.book .bk-meta{font:400 10.5px/1.6 var(--mono);color:var(--chrome-dim)}
.book .bk-badge{position:absolute;top:10px;right:10px;font:400 9px/1 var(--mono);color:#0d211f;background:var(--teal);padding:3px 7px;border-radius:10px;display:none}
.book.active .bk-badge{display:inline-block}

/* ---- hero ---- */
.hero{margin-top:14px;border:1px solid var(--line);background:linear-gradient(160deg,var(--panel2),var(--panel));position:relative;overflow:hidden;border-radius:2px}
.hero .bar{height:5px;background:linear-gradient(90deg,var(--copper),var(--teal))}
.hero .pad{padding:clamp(16px,4vw,28px)}
.kicker{font:400 10.5px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;color:var(--teal)}
.hero h1{font:400 clamp(26px,7vw,42px)/1.2 var(--disp);color:var(--chrome);margin:12px 0 8px;letter-spacing:.01em}
.hero .sub{font:400 12.5px/1.6 var(--mono);color:var(--copper-b);letter-spacing:.03em;margin:0 0 12px}
.hero .intro{max-width:66ch;color:var(--chrome-dim);font:400 13.5px/1.8 var(--serif)}
.tags{display:flex;flex-wrap:wrap;gap:7px;margin:14px 0 0}
.tag{font:400 10.5px/1 var(--mono);letter-spacing:.06em;color:var(--teal);border:1px solid var(--teal-d);padding:6px 9px;border-radius:20px}
.author-row{margin-top:14px;display:flex;flex-wrap:wrap;gap:8px 20px;font:400 11px/1.6 var(--mono);color:var(--chrome-dim);border-top:1px dashed rgba(236,226,207,.16);padding-top:12px}
.author-row b{color:var(--chrome)}

/* ---- HUD gauges ---- */
.hud{margin-top:14px;display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.gauge{border:1px solid var(--line);background:var(--panel);padding:11px 13px;border-radius:2px}
.gauge .lb{font:400 9.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--chrome-dim);display:flex;justify-content:space-between}
.gauge .lb b{color:var(--copper-b);font-weight:400}
.gauge .track{margin-top:8px;height:7px;background:rgba(0,0,0,.4);border:1px solid rgba(236,226,207,.1)}
.gauge .track i{display:block;height:100%;background:linear-gradient(90deg,var(--teal-d),var(--teal))}
@media(min-width:640px){.hud{grid-template-columns:repeat(4,1fr)}}

/* ---- toolbar ---- */
/* V22: top:0 (was 8px) so the toolbar sits flush against the viewport
   edge once stuck — .reader-progress below is offset by the toolbar's
   *measured* height (--toolbar-h, set in JS), so the two sticky bars
   always touch with zero gap regardless of how many rows the toolbar
   wraps to. */
.toolbar{position:sticky;top:0;z-index:5;margin-top:16px;display:flex;flex-wrap:wrap;gap:8px;align-items:center;border:1px solid var(--line);background:color-mix(in srgb,var(--panel) 92%,transparent);backdrop-filter:blur(6px);padding:9px 10px;border-radius:2px}
.tbtn{display:inline-flex;align-items:center;gap:6px;font:400 11.5px/1 var(--mono);letter-spacing:.03em;color:var(--chrome);border:1px solid rgba(236,226,207,.16);padding:9px 11px;border-radius:2px;min-height:38px}
.tbtn:hover{border-color:var(--teal);color:var(--teal)}
.tbtn.active{background:var(--copper);border-color:var(--copper);color:#1a1410}
/* U16c: compact "第N章" bookmark chip — mobile-only (desktop's .lbl already
   shows the truncated chapter title, showing both would be redundant). */
.tbtn .bk-ch{display:none;white-space:nowrap}
.swatches{display:flex;gap:6px}
.swatch{width:26px;height:26px;border-radius:50%;border:2px solid rgba(236,226,207,.25);cursor:pointer;padding:0}
.swatch.on{border-color:var(--teal);box-shadow:0 0 0 2px rgba(79,214,196,.25)}
.swatch.s-green{background:#c8dfcb}.swatch.s-night{background:#2a2015}
.fsize{display:flex;align-items:center;gap:2px;border:1px solid rgba(236,226,207,.16);border-radius:2px}
.fsize button{padding:9px 12px;min-height:38px;font:700 13px/1 var(--mono)}
.fsize button:hover{color:var(--teal)}
.spacer{flex:1 1 auto}
/* U-ambient-player: 3-button cluster, same chassis language as .fsize */
.player{display:flex;align-items:center;gap:2px;border:1px solid rgba(236,226,207,.16);border-radius:2px}
.player button{padding:9px 10px;min-height:38px;font:400 12.5px/1 var(--mono);color:var(--chrome)}
.player button:hover{color:var(--teal)}
.player button.active{color:var(--teal)}

/* ---- reader shell / TOC drawer ---- */
.reader-shell{position:relative;margin-top:14px}
.toc-drawer{position:fixed;inset:0 auto 0 0;z-index:40;width:min(320px,86vw);background:var(--chassis2);border-right:1px solid var(--line);transform:translateX(-105%);transition:transform .28s ease;overflow-y:auto;padding:calc(14px + var(--safe-t)) 14px calc(20px + var(--safe-b));box-shadow:8px 0 30px rgba(0,0,0,.5)}
.toc-drawer.open{transform:translateX(0)}
.toc-drawer h3{font:400 13px/1 var(--disp);letter-spacing:.05em;color:var(--copper-b);margin:0 0 4px;text-transform:uppercase}
.toc-drawer .note{font:400 10.5px/1.6 var(--mono);color:var(--chrome-dim);margin:0 0 14px}
.toc-item{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;text-align:left;padding:11px 10px;border:1px solid rgba(236,226,207,.10);border-radius:2px;margin-bottom:7px;color:var(--chrome);min-height:44px}
.toc-item:hover{border-color:var(--teal)}
.toc-item.current{background:rgba(201,131,74,.16);border-color:var(--copper)}
.toc-item .t{font:400 12.5px/1.4 var(--serif);flex:1}
.toc-item .wc{font:400 9.5px/1 var(--mono);color:var(--chrome-dim);white-space:nowrap}
.toc-item .bk{color:var(--copper-b);flex:0 0 auto}
.toc-backdrop{position:fixed;inset:0;z-index:39;background:rgba(0,0,0,.5);opacity:0;pointer-events:none;transition:opacity .28s ease}
.toc-backdrop.open{opacity:1;pointer-events:auto}
.toc-close{position:absolute;top:calc(10px + var(--safe-t));right:10px;font:700 18px/1 var(--mono);color:var(--chrome-dim);padding:10px;min-width:44px;min-height:44px}

/* ---- reader (eye-comfort palette lives here only) ---- */
.reader{background:var(--read-tex,none),linear-gradient(160deg,var(--read-bg) 0%,var(--read-bg2) 100%);color:var(--read-ink);border:1px solid rgba(0,0,0,.15);box-shadow:0 8px 0 rgba(0,0,0,.35);border-radius:2px;position:relative;transition:background .25s ease,color .25s ease}
.reader-progress{position:sticky;top:var(--toolbar-h,58px);height:3px;background:var(--read-line);z-index:2}
.reader-progress i{display:block;height:100%;width:0;background:var(--read-accent);transition:width .1s linear}
.reader .pad{padding:clamp(18px,5vw,34px) clamp(16px,5vw,40px) clamp(24px,5vw,40px)}
.reader h2{font:700 clamp(19px,5vw,27px)/1.4 var(--serif);color:var(--read-ink);margin:0 0 4px}
.reader .meta{font:400 11px/1.6 var(--mono);color:var(--read-ink-dim);letter-spacing:.04em;margin:0 0 20px;text-transform:uppercase}
/* U46 46-乙-③: cap the reading column at 68ch (same rule U41 set on
   signal.html) — line-height was already 1.95 (well past the 1.7 floor),
   but nothing capped line length, so at the 900px .wrap it ran ~90+ char.
   margin:0 auto centers the capped column inside .reader .pad -- without
   it the column hugs the left edge and leaves a large dead gap on the
   right on any viewport wide enough for 68ch to matter (desktop only;
   mobile's narrower .pad is already at or under 68ch so it never showed). */
.reader .body{max-width:68ch;margin:0 auto}
.reader .body p{font:400 var(--read-fs)/1.95 var(--serif);color:var(--read-ink);margin:0 0 1.35em;text-indent:2em;letter-spacing:.02em}
/* ---- U-sys-panel: SYS blocks = cross-world game terminal ----
   The novel's system prompts (技能升级/结算面板/规则卡) now render as a
   sci-fi "screen" instead of an inline quote box: cool low-blue teal
   terminal against the warm serif prose, mono type, scanlines, corner
   status bar + pulsing link-dot ("同契终端"). Distinction is the point —
   readers should feel a device switched on mid-page. Eye-care kept:
   muted duotone (no pure white/black, no saturated glow), body ink vs
   panel bg measured ≥7:1 in both reading themes; pulse animation is
   opacity-only and disabled under prefers-reduced-motion. */
.reader{--sys-bg:#223230;--sys-bg2:#1a2826;--sys-ink:#bde5da;--sys-dim:#83bbaf;--sys-accent:#59cfba;--sys-line:rgba(89,207,186,.35)}
.reader[data-theme="night"]{--sys-bg:#101b1d;--sys-bg2:#0c1618;--sys-ink:#a9ddd3;--sys-dim:#6fa89e;--sys-accent:#4fd6c4;--sys-line:rgba(79,214,196,.3)}
.reader .body .sys{position:relative;margin:0 0 1.6em;text-indent:0;border:1px solid var(--sys-line);border-radius:6px;background:linear-gradient(165deg,var(--sys-bg),var(--sys-bg2));box-shadow:0 0 0 3px color-mix(in srgb,var(--sys-accent) 8%,transparent),inset 0 0 26px rgba(0,0,0,.28);overflow:hidden}
.reader .body .sys::before{content:"";position:absolute;inset:0;pointer-events:none;background:repeating-linear-gradient(0deg,color-mix(in srgb,var(--sys-accent) 6%,transparent) 0 1px,transparent 1px 3px);opacity:.45}
.reader .body .sys::after{content:"";position:absolute;inset:5px;pointer-events:none;border:1px dashed color-mix(in srgb,var(--sys-accent) 22%,transparent);border-radius:4px}
.sys-head{display:flex;align-items:center;gap:8px;padding:9px 13px;font:600 10.5px/1.4 var(--mono);letter-spacing:.16em;color:var(--sys-accent);border-bottom:1px solid var(--sys-line);background:color-mix(in srgb,var(--sys-accent) 7%,transparent);position:relative;z-index:1}
.sys-head .sys-tag{margin-left:auto;font-weight:400;font-size:9.5px;color:var(--sys-dim);letter-spacing:.12em;white-space:nowrap}
.sys-dot{flex:0 0 auto;width:7px;height:7px;border-radius:50%;background:var(--sys-accent);box-shadow:0 0 6px var(--sys-accent);animation:sysPulse 2.2s ease-in-out infinite}
@keyframes sysPulse{0%,100%{opacity:1}50%{opacity:.3}}
.reader .body .sys .sys-body{font:400 calc(var(--read-fs) - 3px)/1.85 var(--mono);color:var(--sys-ink);padding:12px 14px 14px;white-space:pre-wrap;position:relative;z-index:1;letter-spacing:.01em}
.chapter-nav{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:26px;padding-top:16px;border-top:1px dashed var(--read-line)}
.chapter-nav button{font:400 12px/1 var(--mono);color:var(--read-ink);border:1px solid var(--read-ink-dim);padding:11px 14px;border-radius:2px;min-height:44px}
.chapter-nav button:disabled{opacity:.35;cursor:default}
.chapter-nav button:not(:disabled):hover{border-color:var(--read-accent);color:var(--read-accent)}
.chapter-nav .ind{font:400 11px/1 var(--mono);color:var(--read-ink-dim)}

/* ---- waterfall / infinite-scroll reading ---- */
.wf-chapter{margin-bottom:8px}
.wf-chapter h2{font:700 clamp(19px,5vw,27px)/1.4 var(--serif);color:var(--read-ink);margin:0 0 4px}
.wf-chapter .meta{font:400 11px/1.6 var(--mono);color:var(--read-ink-dim);letter-spacing:.04em;margin:0 0 20px;text-transform:uppercase}
.wf-divider{display:flex;align-items:center;gap:12px;margin:8px 0 30px;color:var(--read-ink-dim);font:400 11px/1 var(--mono);letter-spacing:.1em}
.wf-divider::before,.wf-divider::after{content:"";flex:1;height:1px;background:var(--read-line)}
.wf-sentinel{display:flex;align-items:center;justify-content:center;gap:10px;padding:26px 10px;color:var(--read-ink-dim);font:400 12px/1 var(--mono)}
.wf-sentinel .eq{display:flex;gap:3px;align-items:flex-end;height:14px}
.wf-sentinel .eq i{width:3px;background:var(--read-accent);height:4px;display:block;animation:wfeq 1.1s ease-in-out infinite}
.wf-sentinel .eq i:nth-child(2){animation-delay:.15s}.wf-sentinel .eq i:nth-child(3){animation-delay:.3s}
@keyframes wfeq{0%,100%{height:4px}50%{height:13px}}
.wf-sentinel.done .eq{display:none}
.wf-chip{position:sticky;top:3px;z-index:2;display:none;align-self:flex-start;font:400 10.5px/1 var(--mono);letter-spacing:.06em;color:var(--read-ink);background:color-mix(in srgb,var(--read-ink) 8%,transparent);border:1px solid var(--read-line);padding:6px 10px;border-radius:20px;margin:10px 0 0}
.wf-chip.show{display:inline-flex}

/* ---- mobile FAB quick-nav (thumb-reachable) ---- */
.fab{position:fixed;right:calc(14px + var(--safe-r));bottom:calc(16px + var(--safe-b));z-index:30;display:flex;flex-direction:column;align-items:flex-end;gap:10px}
.fab-toggle{width:52px;height:52px;border-radius:50%;background:var(--copper);color:#1a1410;font:700 20px/1 var(--mono);display:grid;place-items:center;box-shadow:0 6px 18px rgba(0,0,0,.5);border:1px solid var(--copper-b)}
.fab-menu{display:flex;flex-direction:column;gap:8px;align-items:flex-end;max-height:0;overflow:hidden;transition:max-height .25s ease}
.fab-menu.open{max-height:320px}
.fab-menu button{display:flex;align-items:center;gap:8px;font:400 11.5px/1 var(--mono);color:var(--chrome);background:var(--panel2);border:1px solid var(--line);padding:10px 13px;border-radius:24px;min-height:44px;white-space:nowrap}
.fab-menu button:hover{border-color:var(--teal);color:var(--teal)}

/* ---- toast ---- */
.toast{position:fixed;left:50%;bottom:calc(90px + var(--safe-b));transform:translate(-50%,10px);z-index:50;background:var(--panel2);border:1px solid var(--teal-d);color:var(--chrome);font:400 11.5px/1.5 var(--mono);padding:10px 16px;border-radius:20px;opacity:0;pointer-events:none;transition:opacity .25s ease,transform .25s ease;max-width:88vw;text-align:center}
.toast.show{opacity:1;transform:translate(-50%,0)}

.foot{margin-top:20px;border-top:1px solid var(--line);padding-top:14px;font:400 10.5px/1.7 var(--mono);letter-spacing:.04em;color:var(--chrome-dim);text-transform:uppercase}
.foot b{color:var(--copper-b)}

@media(max-width:640px){
  /* V22: collapse the two-row wrap into one scrollable row — icon-only
     buttons (text labels hidden via .lbl) plus flex-wrap:nowrap so it
     can never re-wrap; overflow-x:auto is a safety net if it's ever a
     few px too wide rather than breaking back into 2 rows. */
  .toolbar{gap:6px;flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .toolbar::-webkit-scrollbar{display:none}
  .toolbar .lbl{display:none}
  /* U16c: with .lbl hidden, keep a short "第N章" chip on the bookmark
     button so mobile still shows which chapter is saved; a few characters
     wide, and the toolbar is nowrap + overflow-x:auto anyway, so it can
     never spill outside the bar. */
  .toolbar .bk-ch{display:inline}
  .tbtn{padding:8px 9px;font-size:11px;flex:0 0 auto}
  /* U28: 自动翻页加长一倍 + 顺带补 44px 触控目标（22c 欠账） */
  #autoToggle{min-width:72px;min-height:44px}
  .swatches,.fsize,.player{flex:0 0 auto}
  .player button{padding:8px 8px;min-height:44px}
  .fsize button{padding:8px 9px}
  .spacer{display:none}
  .hero .pad{padding-bottom:20px}
}
@media (prefers-reduced-motion: reduce){
  .toc-drawer,.toc-backdrop,.fab-menu,.reader-progress i,.toast{transition:none}
  .sys-dot{animation:none}
  /* U30 R1: kill the shelf→hero morph animation, keep the instant swap */
  ::view-transition-group(novelMorph),::view-transition-old(novelMorph),::view-transition-new(novelMorph){animation:none!important}
}
