/* ============================================================
   BookChive — Design System v4 (Mobile-first, clean rebuild)
   Layer 0: Reset + Variables
   Layer 1: Layout primitives
   ============================================================ */

/* 
Mobile-first CSS architecture:

- Write mobile styles first
- Group ALL desktop rules at the bottom of each component
- Never scatter media queries across the file
*/


/* ── Pretendard ─────────────────────────────────────────────── */

@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Thin.woff2') format('woff2');
  font-weight: 100; font-display: swap;
}
@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-ExtraLight.woff2') format('woff2');
  font-weight: 200; font-display: swap;
}
@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Light.woff2') format('woff2');
  font-weight: 300; font-display: swap;
}
@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Regular.woff2') format('woff2');
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-SemiBold.woff2') format('woff2');
  font-weight: 600; font-display: swap;
}
@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Bold.woff2') format('woff2');
  font-weight: 700; font-display: swap;
}
@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-ExtraBold.woff2') format('woff2');
  font-weight: 800; font-display: swap;
}
@font-face {
  font-family: 'Pretendard';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/pretendard@1.0/Pretendard-Black.woff2') format('woff2');
  font-weight: 900; font-display: swap;
}

/* ── Layer 0-A: Reset ──────────────────────────────────────── */

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Body is the scroll container; #root fills at least the full viewport */
#root {
  min-height: 100dvh;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--bg);
}

body {
  font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Segoe UI", sans-serif;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  background: var(--bg);
  color: var(--ink);
}

button {
  cursor: pointer;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
}

a {
  color: inherit;
  text-decoration: none;
}

img, svg { display: block; }

.author-avatar {
  border-radius: 50%;
  background: var(--surface);
  display: inline-block;
  flex: none;
  overflow: hidden;
  position: relative;
}

.author-avatar img,
.author-avatar__fallback {
  width: 100%;
  height: 100%;
  display: block;
}

.author-avatar img {
  object-fit: cover;
}


.author-avatar--20 { width: 20px; height: 20px; }
.author-avatar--28 { width: 28px; height: 28px; }
.author-avatar--36 { width: 36px; height: 36px; }
.author-avatar--56 { width: 56px; height: 56px; }
.author-avatar--64 { width: 64px; height: 64px; }

ul, ol { list-style: none; }

/* ── Layer 0-B: CSS Variables (light theme default) ──────── */

:root {
  /* Brand */
  --brand:      #0066CC;
  --brand-soft: #F1F0EF;
  --link:       #0066CC;

  /* Backgrounds — Notion-verified: content=white, panel=warm off-white */
  --bg:            #FFFFFF;
  --bg-2:          #F9F8F7;
  --bg-card:       #FFFFFF;
  --surface:       #F1F0EF;
  --surface-raised: var(--bg-card);

  /* Dividers — warm hairlines */
  --line:       #E8E7E5;
  --line-2:     #EDECEB;

  /* Text — warm stone scale */
  --ink:        #1A1917;
  --ink-soft:   #57534E;
  --ink-faint:  #7C7873;

  /* Accent (reader highlights) */
  --accent:     #0066CC;
  --accent-bg:  #EAF3FF;
  --accent-focus: #0071E3;
  --accent-on-dark: #2997FF;
  --on-accent:  #fff;

  /* Reader interior — background unified with --bg (see var usages replaced with --bg). */
  --reader-ink:       var(--ink);
  --reader-ink-soft:  var(--ink-soft);
  --reader-line:      var(--line);
  --reader-sel:       var(--accent-bg);

  /* Reading typography */
  --reader-font-size: 17px;
  --reader-leading:   2.0;
  --reader-tracking:  0;
  --reader-para-gap:  0.5em;
  --reader-pad:       var(--pad-lg);

  /* Reader progress bar — subtle, never competes with text */
  --reader-progress-bg:  var(--line-2);
  --reader-progress-ink: var(--ink-faint);

  /* Animation */
  --ease-snap: cubic-bezier(0.2, 0, 0, 1);
  --dur-screen: 320ms;

  /* z-index scale */
  --z-nav:      100;
  --z-sheet:    800;
  --z-sheet-2:  810;
  --z-ctx:      820;
  --z-toast:    910;
  --z-lightbox: 9000;

  /* Overlay geometry */
  --ov-radius:   var(--r-lg);
  --ov-pad-x:    20px;
  --ov-backdrop: rgba(0, 0, 0, 0.36);

  /* Status */
  --ok:         #22C55E;
  --warn:       #F59E0B;
  --danger:     #EF4444;
  --heart:      #E0355A;

  /* Tag / badge tokens */
  --tag-bg:          var(--surface);
  --tag-adult-bg:    #F5A847;
  --tag-adult-color: #FFEDCF;

  /* Spacing — 8px grid */
  --pad:        16px;
  --pad-sm:     12px;
  --pad-xs:     8px;
  --pad-lg:     24px;
  --pad-side:   20px;

  /* Radius — 5-level scale. No hardcoded px border-radius in screen CSS.
   * --r-sm  : marks, handles, small thumbnails          (4px)
   * --r-base: filter/tab chips, icon buttons            (6px)
   * --r-md  : inputs, cards, panels                     (8px)
   * --r-lg  : modals, dropdowns, sheet top-corners      (12px)
   * --r-pill: tags, chat bubbles, pill bars, toasts     (999px)
   */
  --r-sm:   4px;
  --r-base: 6px;
  --r-md:   8px;
  --r-lg:   12px;
  --r-pill: 999px;

  /* Elevation — Notion-style barely-there layered shadows.
   * Rule: use ONLY these three levels. No hardcoded rgba shadows in screen CSS.
   * --shadow-1   : cards resting on canvas (subtle lift, hairline preferred)
   * --shadow-2   : floating elements — popovers, dropdowns, tooltips
   * --shadow-3   : modals, overlays, sheets (max allowed depth)
   */
  --shadow-1: 0 1px 3px rgba(0,0,0,.05), 0 1px 2px rgba(0,0,0,.04);
  --shadow-2: 0 4px 14px rgba(0,0,0,.08), 0 2px 4px rgba(0,0,0,.05);
  --shadow-3: 0 8px 28px rgba(0,0,0,.09), 0 2px 8px rgba(0,0,0,.05);
  --product-shadow: var(--shadow-3);

  /* Monospace — for code, IDs, counters */
  --mono:       'SF Mono', 'Cascadia Code', monospace;

  /* Typography scale. Never use raw px font-size outside this list. */
  --font-nano:  9px;
  --font-2xs:   11px;
  --font-xs:    12px;
  --font-compact: 13px;
  --font-sm:    14px;
  --font-icon:  16px;
  --font-md:    17px;
  --font-lg:    21px;
  --font-xl:    24px;
  --font-2xl:   28px;
  --font-3xl:   34px;

  /* Nav */
  --nav-h:      52px;

  /* Topbar (desktop) */
  --topbar-h:   60px;

  /* Page bar — unified header height for all screens */
  --bar-h:      52px;

  /* Transitions */
  --ease:       cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --dur:        180ms;

  /* Platform layout — responsive overrides live in 6-platforms.css */
  --platform-content-max:    730px;
  --platform-reader-max:     770px;
  --platform-grid-min:       120px;

  /* Admin design system */
  --adm-control-h:   34px;
  --adm-card-pad:    16px;
  --adm-section-gap: 12px;
  --adm-content-max: 810px;

  /* Reader chrome */
  --reader-chrome-bg:     var(--bg-card);
  --reader-chrome-line:   var(--line);
  --reader-chrome-radius: var(--r-lg);
}

/* Light theme — only overrides that differ from :root defaults */
[data-theme="light"] {
  --accent-bg:  #EAF0FF;
}

/* Dark theme — Apple Books warm dark */
[data-theme="dark"] {
  --brand:      #2997FF;
  --brand-soft: #1B2633;
  --link:       #2997FF;

  --bg:         #141312;
  --bg-2:       #201F1D;
  --bg-card:    #1C1B1A;
  --surface:    #2B2A27;

  --line:       rgba(255,255,255,.10);
  --line-2:     rgba(255,255,255,.06);

  --ink:        #F5F4F2;
  --ink-soft:   #C8C4BE;
  --ink-faint:  #8A8681;

  --accent:     #2997FF;
  --accent-bg:  #102A44;
  --accent-focus: #0071E3;
  --accent-on-dark: #2997FF;

  --ov-backdrop: rgba(0, 0, 0, 0.55);
  --shadow-1:   0 0 0 1px rgba(255,255,255,.08);
  --shadow-2:   0 0 0 1px rgba(255,255,255,.12);
  --shadow-3:   0 0 0 1px rgba(255,255,255,.16), 0 8px 24px rgba(0,0,0,.4);

  --tag-adult-bg:    #d4891a;
  --tag-adult-color: #3a2000;
}

:root                { color-scheme: light; }
[data-theme="light"] { color-scheme: light; }
[data-theme="dark"]  { color-scheme: dark; }

/* ── Utility classes ─────────────────────────────────────── */

.tnum  { font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-faint); font-size: var(--font-xs); }

/* ── Error boundary ─────────────────────────────────────── */

.error-boundary {
  padding: 2rem;
  font-family: monospace;
  color: var(--danger);
}
.error-boundary__trace {
  margin-top: 1rem;
  white-space: pre-wrap;
  font-size: 0.85rem;
}
.error-boundary button {
  margin-top: 1rem;
}

/* ── Page bar — unified header for every screen ──────────────────────────
 * Usage: <header className="page-bar">
 *          <button className="icon-btn"> ← back </button>
 *          <span className="page-bar__title">Screen name</span>
 *          <span className="page-bar__spacer" />
 *          ... action buttons ...
 *        </header>
 * For reader (hides on scroll): add class "page-bar--hidden"
 * ──────────────────────────────────────────────────────────────────────── */
.page-bar {
  display: flex;
  align-items: center;
  height: var(--bar-h);
  padding: 0 var(--pad);
  gap: 4px;
  background: var(--bg);
  border-bottom: 1px solid transparent;
  flex-shrink: 0;
  position: sticky;
  top: 0;
  z-index: 90;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

.page-bar--hidden {
  transform: translateY(-110%);
  pointer-events: none;
  transition: transform 0.22s var(--ease);
}

.page-bar__title {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.224px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

.page-bar__spacer { flex: 1; }

/* Show divider + elevation when scrolled */
.page-bar.page-bar--scrolled {
  border-bottom-color: var(--line);
  box-shadow: 0 8px 20px -12px color-mix(in srgb, var(--ink) 22%, transparent);
}

/* Buttons */
.icon-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--ink-soft);
  background: transparent;
  transition:
    background var(--dur) var(--ease),
    color var(--dur) var(--ease),
    transform var(--dur) var(--ease);
  -webkit-tap-highlight-color: transparent;
}

.icon-btn:active,
.icon-btn:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  color: var(--ink);
}

.icon-btn:active { transform: scale(0.95); }

.icon-btn--sm {
  width: 36px;
  height: 36px;
  border-radius: 50%;
}

.hidden-file-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 44px;
  padding: 0 var(--pad-lg);
  border-radius: var(--r-md);
  font-size: var(--font-md);
  font-weight: 400;
  letter-spacing: -0.374px;
  background: var(--accent);
  color: var(--on-accent);
  transition: background var(--dur) var(--ease), transform 0.12s var(--ease), opacity var(--dur) var(--ease);
  -webkit-tap-highlight-color: transparent;
}

.btn:active { transform: scale(0.95); }
.btn:focus-visible {
  outline: 2px solid var(--accent-focus);
  outline-offset: 2px;
}
.btn--ghost   {
  background: var(--bg);
  color: var(--accent);
  border: 1px solid var(--accent);
}
.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:hover:not(:disabled) { background: var(--accent-focus); }
.btn--danger  { background: var(--danger); color: var(--on-accent); }
.btn--sm {
  height: 30px;
  padding: 0 11px;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  letter-spacing: -0.224px;
}
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Form fields */
.form-textarea,
.adm-search,
.adm-field input[type="text"],
.adm-field input:not([type="checkbox"]),
.adm-textarea,
.adm-url-input {
  border: 1px solid var(--line);
  background: var(--bg-card);
  color: var(--ink);
  font: inherit;
  outline: none;
  transition:
    border-color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.form-textarea:focus,
.adm-search:focus,
.adm-field input:not([type="checkbox"]):focus,
.adm-textarea:focus,
.adm-url-input:focus {
  border-color: var(--accent-focus);
  background: var(--bg-card);
}

.form-textarea::placeholder,
.adm-search::placeholder,
.adm-field input::placeholder,
.adm-textarea::placeholder,
.adm-url-input::placeholder {
  color: var(--ink-faint);
}

/* Segmented controls */
.seg-control {
  display: inline-flex;
  border-radius: var(--r-pill);
  background: var(--surface);
  padding: 3px;
  gap: 2px;
}

.seg {
  height: 30px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-soft);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), transform 0.12s var(--ease);
  white-space: nowrap;
}

.seg.is-on {
  background: var(--bg-card);
  color: var(--ink);
  border: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
}
.seg:active { transform: scale(0.95); }

/* Stepper — shared by reader sheet and settings screen */
.font-stepper {
  display: flex;
  align-items: center;
  gap: 4px;
  background: var(--surface);
  border-radius: var(--r-pill);
  padding: 3px;
}

.step-btn {
  width: 32px;
  height: 30px;
  border-radius: var(--r-pill);
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink-soft);
  display: grid;
  place-items: center;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.step-btn:active,
.step-btn:hover { background: var(--bg); color: var(--ink); }
.step-btn:active { transform: scale(0.95); }

.step-value {
  min-width: 44px;
  text-align: center;
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
}

/* Badges */
.adult-mark,
.badge-19 {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  min-width: 22px;
  height: 18px;
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
  padding: 0 7px;
  border-radius: var(--r-pill);
  border: none;
  background: var(--tag-adult-color);
  color: var(--tag-adult-bg);
  vertical-align: middle;
  margin-right: 5px;
}

[data-small="1"].adult-mark,
[data-small="1"].badge-19 {
  min-width: 18px;
  height: 15px;
  font-size: 8.5px;
  padding: 0 5px;
  margin-right: 4px;
}

/* Dividers / empty states */
.divider {
  height: 1px;
  background: var(--line);
  margin: 0 var(--pad);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 64px var(--pad);
  color: var(--ink-faint);
  text-align: center;
}

.empty-state p { font-size: var(--font-sm); }

/* Interactive rows */
.book-row,
.author-row,
.sheet-row,
.toc-item,
.adm-book-row,
.series-card {
  text-align: left;
  cursor: pointer;
  transition:
    background var(--dur) var(--ease),
    color var(--dur) var(--ease);
}

.book-row:hover,
.sheet-row:hover,
.toc-item:hover,
.adm-book-row:hover {
  background: var(--bg-2);
}

.series-card:active {
  background: var(--surface);
}

.book-row:last-child,
.sheet-row:last-child {
  border-bottom: none;
}

/* ── Entity row: author avatar + stacked title/sub ──────────── */
/* Shared BEM sub-elements used in notes group header. */

.entity-row__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.entity-row__title {
  font-size: var(--font-base);
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.entity-row__sub {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--font-xs);
  color: var(--ink-faint);
}

.entity-row__aside {
  flex-shrink: 0;
  font-size: var(--font-xs);
  color: var(--ink-faint);
}

/* ── Compact list row: space-minimized, mobile-first list row ──────────
 * Unlike .entity-row (avatar as a persistent left column for the whole
 * row height), the avatar here sits inline with name/date/handle on line
 * 1 only — every line below (title/excerpt/tags/meta) runs full width
 * with no left indent. Use where vertical density matters more than a
 * persistent avatar column, e.g. a work's Series / Other Works lists. */

.compact-list-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}

.compact-list-row:last-child { border-bottom: none; }
.compact-list-row:hover,
.compact-list-row.is-current { background: var(--bg-2); }

.compact-list-row__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.compact-list-row__name {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.224px;
}

.compact-list-row__date,
.compact-list-row__handle {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  letter-spacing: -0.12px;
}

.compact-list-row__title {
  font-size: var(--font-md);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.4;
  letter-spacing: -0.374px;
  margin: 0;
}

.compact-list-row__excerpt {
  font-size: var(--font-sm);
  color: var(--ink-faint);
  line-height: 1.47;
  letter-spacing: -0.224px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.compact-list-row__meta {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  margin-top: 2px;
}

/* ── Content tag ─────────────────────────────────────────── */
/* Single primitive: .tag + .tag--adult + .tag--link.        */
/* No # prefix — text is rendered as-is from data.           */

.tag {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  font-size: var(--font-xs);
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--surface);
  border: none;
  white-space: nowrap;
}

.tag--link {
  cursor: pointer;
  font-family: inherit;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.tag--link:hover {
  background: var(--line);
  color: var(--ink);
}

.tag--adult {
  color: var(--tag-adult-color);
  background: var(--tag-adult-bg);
  font-weight: 600;
}

/* Wrapping tag container — use instead of per-screen det-fandom-row / det-tags */
.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

@keyframes screen-push {
  from { opacity: 0; transform: translateX(18px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes screen-pop {
  from { opacity: 0; transform: translateX(-18px); }
  to   { opacity: 1; transform: translateX(0); }
}

@media (prefers-reduced-motion: no-preference) {
  /* push (forward) — new screen slides in from the right */
  [data-nav-dir="push"] .library-screen,
  [data-nav-dir="push"] .reader-screen,
  [data-nav-dir="push"] .detail-screen,
  [data-nav-dir="push"] .series-screen,
  [data-nav-dir="push"] .notes-screen,
  [data-nav-dir="push"] .settings-screen,
  [data-nav-dir="push"] .author-screen,
  [data-nav-dir="push"] .search-screen {
    animation: screen-push var(--dur-screen) var(--ease-snap);
    will-change: transform, opacity;
  }

  /* pop (back) — new screen slides in from the left */
  [data-nav-dir="pop"] .library-screen,
  [data-nav-dir="pop"] .reader-screen,
  [data-nav-dir="pop"] .detail-screen,
  [data-nav-dir="pop"] .series-screen,
  [data-nav-dir="pop"] .notes-screen,
  [data-nav-dir="pop"] .settings-screen,
  [data-nav-dir="pop"] .author-screen,
  [data-nav-dir="pop"] .search-screen {
    animation: screen-pop var(--dur-screen) var(--ease-snap);
    will-change: transform, opacity;
  }
}

/* ── Scroll column — used across all screens ─────────────────────────────
 * Body is the scroll container. col-scroll provides overflow clipping only.
 * Centering is done by .col itself via margin: auto — no flex dependency.
 * Admin overrides this to restore overflow-y: auto (admin has its own 100dvh lock).
 * ──────────────────────────────────────────────────────────────────────── */
.col-scroll {
  width: 100%;
  overflow-x: hidden;
}

.col {
  width: 100%;
  max-width: 730px;
  margin: 0 auto;
  padding: 16px var(--pad-lg) 24px;
}

.col--narrow {
  max-width: 730px;
}

/* ── Section labels ───────────────────────────────────────────────────────
 * .section-lbl           : large heading above a content group
 * .section-lbl--row      : small uppercase label on the same line as a count/action
 * .section-lbl--flush    : removes default margin (use inside flex rows)
 * ──────────────────────────────────────────────────────────────────────── */
.section-lbl {
  padding: 0 var(--pad);
  margin: 4px 0 10px;
  font-size: var(--font-lg);
  font-weight: 600;
  letter-spacing: -0.3px;
  color: var(--ink);
}

.section-lbl--row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 0 8px;
  font-size: var(--font-xs);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink-faint);
}

.section-lbl--flush {
  margin: 0;
  flex-shrink: 0;
}

/* ── Filter pills ─────────────────────────────────────────────────────────
 * Usage: <div className="pills"><button className="is-on">Active</button>…</div>
 * ──────────────────────────────────────────────────────────────────────── */
.pills {
  display: flex;
  gap: 6px;
  padding: 0 var(--pad) 14px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.pills::-webkit-scrollbar { display: none; }

.pills button {
  flex-shrink: 0;
  min-height: 44px;
  height: auto;
  padding: 12px 14px;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  font-weight: 400;
  letter-spacing: -0.224px;
  background: var(--bg);
  color: var(--accent);
  border: 1px solid var(--accent);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), transform 0.12s var(--ease);
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}

.pills button.is-on {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}
.pills button:active { transform: scale(0.95); }


/*
MOBILE-FIRST RULES (enforced):
  1. Base styles = mobile (no @media guard)
  2. Desktop rules = @media (min-width: 768px) { ... } ONLY
  3. NEVER scatter desktop rules across non-@media blocks
  4. .sheet  = dark backdrop overlay (position:fixed, inset:0, dark bg)
             MUST NOT be used as a card/content container — use .sheet-panel
  5. col content width is set once in 0-reset.css; never re-declare .col here
*/

/* ── Layer 1-A: App shell ─────────────────────────────────────────────── */

.phone {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  position: relative;
}

/* ── Layer 1-B: App header ────────────────────────────────────────────── */

.app-header {
  height: var(--bar-h);
  display: flex;
  align-items: center;
  padding: 0 12px;
  gap: 2px;
  background: var(--bg);
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 90;
  transition: transform 0.22s var(--ease), border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
  border-bottom: 1px solid transparent;
}

.app-header--hidden {
  transform: translateY(-110%);
  pointer-events: none;
}

.app-header__spacer { flex: 1; }

/* Search/add expanded inline in the header itself (replaces the header icon
   row while open) -- the actual <input>/<textarea> lives here, not in the
   toggle panel below, so typing survives the panel remounting between opens.
   Rough framework pass -- see .nav-toggle-panel below. */
.app-header__inline {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.app-header__inline-icon {
  flex-shrink: 0;
  color: var(--ink-faint);
}

.app-header__inline-input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: inherit;
  font-size: var(--font-md);
  color: var(--ink);
}

.app-header__inline-input::placeholder { color: var(--ink-faint); }

/* Search only. Mobile (base rule): the header itself becomes the search bar
   -- App.tsx hides breadcrumb/spacer while searching on mobile
   (isDesktop check), so this box is the only header
   child and can take the full row without the header growing to two lines
   (which would have pushed .nav-toggle-panel's fixed `top: var(--bar-h)`
   off -- see devlogs/DEVLOG-2026-07.md). Desktop override (6-platforms.css)
   restores the small right-aligned pill next to breadcrumb/spacer. */
.app-header__inline--compact {
  flex: 1 1 auto;
  width: 100%;
  height: 44px;
  padding: 0 12px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-1);
}

/* Show a subtle divider and elevation when the header is scrolled */
.app-header.app-header--scrolled {
  border-bottom-color: var(--line);
  box-shadow: 0 8px 20px -12px color-mix(in srgb, var(--ink) 22%, transparent);
}

.app-header__inline--compact .app-header__inline-input {
  font-size: var(--font-sm);
}

/* ── Layer 1-C: App shell body ────────────────────────────────────────── */

.app-shell {
  flex: 1;
  display: flex;
  min-height: 0;
}

/* .app-header is now position:fixed (stays put while the page scrolls), so
   it no longer reserves its own space in the flow the way sticky/static did
   -- compensate here. Scoped with `~` (not a plain rule) so this padding
   only applies when .app-header actually renders as a preceding sibling:
   reader screens and the full-page search screen (design/screens/panels/
   index.tsx's `!compact` PageBar) render neither .app-header nor this
   sibling, and already handle their own top offset independently. */
.app-header ~ .app-shell {
  padding-top: var(--bar-h);
}

/* ── Layer 1-D: Breadcrumb navigation ─────────────────────────────────── */

/* ── Layer 1-E: Main content area ─────────────────────────────────────── */

.app-breadcrumb {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--ink-soft);
}

.app-breadcrumb__root {
  position: relative;
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
}

.app-breadcrumb__root-btn,
.app-breadcrumb__segment {
  height: 32px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  padding: 0 8px;
  border-radius: var(--r-md);
  color: var(--ink-soft);
  font: inherit;
  font-size: var(--font-sm);
  font-weight: 600;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.app-breadcrumb__root-btn:hover,
.app-breadcrumb__segment:hover {
  background: var(--surface);
  color: var(--ink);
}

/* Separate hit target from the root label -- clicking the label navigates
   straight to the root screen, clicking this chevron opens the root-switch
   dropdown. Kept visually joined to the label button (no gap) so together
   they still read as one "[ 📁 Library ▾ ]" pill. */
.app-breadcrumb__root-toggle {
  height: 32px;
  width: 22px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-md);
  color: var(--ink-soft);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.app-breadcrumb__root-toggle:hover {
  background: var(--surface);
  color: var(--ink);
}

.app-breadcrumb__root-label,
.app-breadcrumb__segment {
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-breadcrumb__chevron {
  flex: 0 0 auto;
  transform: rotate(90deg);
  transition: transform var(--dur) var(--ease);
}

.app-breadcrumb__chevron.is-open {
  transform: rotate(-90deg);
}

.app-breadcrumb__sep {
  color: var(--ink-faint);
  font-size: var(--font-sm);
}

.app-breadcrumb__menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: 220px;
  padding: 6px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 12px 24px -8px color-mix(in srgb, var(--ink) 22%, transparent);
  z-index: var(--z-nav);
}

.app-breadcrumb__menu-item {
  width: 100%;
  height: 36px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 10px;
  border-radius: var(--r-md);
  color: var(--ink-soft);
  font-size: var(--font-sm);
  font-weight: 600;
  text-align: left;
}

.app-breadcrumb__menu-item:hover,
.app-breadcrumb__menu-item.is-active {
  background: var(--surface);
  color: var(--ink);
}

.app-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.screen-scroll {
  flex: 1;
  outline: none;
}

/* ── Layer 1-F0: Search/add toggle panel ──────────────────────────────── *
 * Rough framework pass -- docked in normal document flow directly under
 * the header (not a modal/overlay), toggled open/closed. Bounded height +
 * its own scroll so a long result list can't push page content far down. */
.nav-toggle-panel {
  position: absolute;
  top: var(--bar-h);
  right: 12px;
  width: min(560px, calc(100% - 24px));
  max-height: min(35dvh, 350px);
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 12px 24px -8px color-mix(in srgb, var(--ink) 22%, transparent);
  z-index: var(--z-nav);
  animation: nav-toggle-panel-slide var(--dur) var(--ease);
}

@keyframes nav-toggle-panel-slide {
  from { transform: translateY(-6px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ── Layer 1-F: Library layout ────────────────────────────────────────── */

.lib-body {
  flex: 1;
  display: flex;
  position: relative;
}

/* ── Layer 1-G: Reader layout ─────────────────────────────────────────── */

.reader-body {
  flex: 1;
  display: flex;
  overflow: hidden;
  position: relative;
  min-height: 0;
}

/* Desktop TOC: fixed right sidebar (not overlay) */
.toc-panel--desktop {
  position: relative;
  width: 260px;
  flex-shrink: 0;
  border-left: 1px solid var(--line);
  box-shadow: none;
}

.toc-panel--desktop .toc-panel__inner {
  height: 100%;
}

/* Mobile TOC: overlay from right */
.reader-body--toc .col-scroll { flex: 1; min-width: 0; }

/* ============================================================
   Layer 2: Library screen
   ============================================================ */

/*  Screen shell  */

.library-screen {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--bg);
}


/*  Collection icon row  */

.lib-coll-strip-wrap {
  border-bottom: 1px solid var(--line-2);
  background: transparent;
}

.coll-row-wrap {
  position: relative;
  padding: 8px 0 12px;
}

.coll-row {
  display: flex;
  flex-direction: row;
  gap: 2px;
  padding: 0 var(--pad) 4px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.coll-row::-webkit-scrollbar { display: none; }

.coll-row-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-60%);
  z-index: 10;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line);
  box-shadow: none;
  display: grid;
  place-items: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s var(--ease);
  color: var(--ink);
}
.coll-row-wrap:hover .coll-row-arrow { opacity: 1; }
.coll-row-arrow--left  { left: 2px; }
.coll-row-arrow--right { right: 2px; }
.coll-row-arrow:hover  { background: var(--surface); }
@media (hover: none) { .coll-row-arrow { opacity: 1; } }

.coll {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 6px 6px;
  border-radius: var(--r-lg);
  cursor: pointer;
  scroll-snap-align: start;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.18s var(--ease);
  width: 72px;
}
.coll:hover,
.coll:active { background: rgba(0,0,0,.06); }
.coll--active { background: var(--brand-soft); }
.coll--active .coll__name { color: var(--ink); font-weight: 600; }

.coll__icon {
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

.coll__icon--add { color: var(--ink-soft); }
.coll--active .coll__icon--add { color: var(--ink); }

.coll__icon-pill {
  width: 48px;
  height: 48px;
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  color: var(--ink-soft);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.coll__icon-pill--star {
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border-color: transparent;
  color: var(--warn);
}

.coll__icon-pill--add {
  background: transparent;
  border: 1.5px dashed var(--line);
  color: var(--ink-faint);
}

.coll__icon-pill--emoji {
  background: var(--surface);
  border-color: transparent;
  font-size: 26px;
  line-height: 1;
  user-select: none;
}

.coll--active .coll__icon-pill {
  background: var(--surface);
  border-color: var(--line);
  color: var(--ink);
}

.coll {
  position: relative;
}

.coll__more-btn {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font-size: var(--font-compact);
  background: var(--surface);
  color: var(--ink-soft);
  display: grid;
  place-items: center;
  z-index: 1;
  line-height: 1;
}

.coll__name {
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-soft);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
}

.coll__count {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  text-align: center;
  line-height: 1;
}

/*  Continue reading card  */

.continue-card--new {
  margin: 0 var(--pad) 20px;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  grid-template-areas:
    "cover src"
    "cover title"
    "cover chap"
    "bar   bar";
  gap: 6px 16px;
  align-items: center;
}

.continue-card--new:active {
  background: var(--surface);
}

.continue-card--new .src-col {
  grid-area: src;
  margin: 0;
}

.continue-card--new .ttl {
  grid-area: title;
  font-size: var(--font-xl);
  font-weight: 600;
  letter-spacing: -0.28px;
  line-height: 1.14;
  color: var(--ink);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.continue-card--new .bar-row {
  grid-area: bar;
  display: flex;
  align-items: center;
  gap: 8px;
}
.continue-card--new .bar-row .bar { flex: 1; width: auto; }
.continue-card--new .bar-pct {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  flex-shrink: 0;
  min-width: 28px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.continue-card--new .chap {
  grid-area: chap;
  font-size: var(--font-xs);
  color: var(--ink-faint);
  margin: 0;
}

.continue-card--new .bar {
  grid-area: bar;
  display: block;
  width: 100%;
  height: 3px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--surface);
  -webkit-appearance: none;
  appearance: none;
}

.continue-card__cover {
  grid-area: cover;
  width: 96px;
  aspect-ratio: 2 / 3;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface);
}

@media (max-width: 520px) {
  .continue-card--new {
    grid-template-columns: 78px minmax(0, 1fr);
    grid-template-areas:
      "cover src"
      "cover title"
      "cover chap"
      "bar   bar";
    padding: 14px;
    gap: 5px 13px;
  }

  .continue-card__cover {
    width: 78px;
  }

  .continue-card--new .ttl {
    font-size: var(--font-md);
    letter-spacing: 0;
    line-height: 1.25;
  }
}

.continue-card--new .bar::-webkit-progress-bar   { background: var(--surface);   border-radius: var(--r-pill); }
.continue-card--new .bar::-webkit-progress-value { background: var(--ink-soft);  border-radius: var(--r-pill); }
.continue-card--new .bar::-moz-progress-bar      { background: var(--ink-soft);  border-radius: var(--r-pill); }

/*  Book list  */

.book-list {
  display: flex;
  flex-direction: column;
}


/* Feed view (replaces grid when viewMode=grid) */
.feed-list {
  display: flex;
  flex-direction: column;
}

.library-rating-group {
  padding: 18px 0 8px;
  color: var(--ink-soft);
  font-size: var(--font-xs);
  font-weight: 700;
  letter-spacing: 0;
  border-bottom: 1px solid var(--line-2);
}

.feed-card {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  grid-template-areas:
    "avatar meta actions"
    "avatar body body";
  column-gap: 10px;
  row-gap: 4px;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  position: relative;
}

.feed-card:last-child { border-bottom: none; }
.feed-card:active { opacity: 0.85; }

.feed-card__avatar-btn {
  grid-area: avatar;
  align-self: start;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  border-radius: 50%;
}

.feed-card__meta {
  grid-area: meta;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding-top: 2px;
}

.feed-card__author {
  background: none;
  border: none;
  padding: 0;
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  line-height: 1.4;
  letter-spacing: -0.224px;
}

.feed-card__author:hover { color: var(--ink); }

.feed-card__date {
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-faint);
  line-height: 1.4;
  letter-spacing: -0.12px;
}

.feed-card__handle {
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-faint);
  line-height: 1.4;
  letter-spacing: -0.12px;
}

.feed-card__views {
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-faint);
  line-height: 1.4;
  letter-spacing: -0.12px;
}

.feed-card__actions {
  grid-area: actions;
  display: flex;
  align-items: center;
  gap: 4px;
}

.feed-card__more {
  opacity: 0;
  transition: opacity 0.15s;
}

.feed-card:hover .feed-card__more,
.feed-card__more:focus-visible { opacity: 1; }

.feed-card__select {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}

.feed-card.is-selected .feed-card__select {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.feed-card__body {
  grid-area: body;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.feed-card__title {
  font-size: var(--font-md);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.4;
  letter-spacing: -0.374px;
  margin: 0;
  word-break: keep-all;
}

/* "외 N편" -- signals a series_registry-linked entry is not a standalone
   one-shot (devlogs/TODO.md "retire physical series merging" sub-item ③).
   Deliberately muted/informational, unlike .tag--adult's warning-orange
   fill -- this is metadata, not a content warning. */
.feed-card__series-badge {
  display: inline-flex;
  align-items: center;
  height: 18px;
  margin-left: 6px;
  padding: 0 7px;
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-faint);
  font-size: var(--font-xs);
  font-weight: 500;
  letter-spacing: -0.12px;
  vertical-align: middle;
  white-space: nowrap;
}

.feed-card__subtitle {
  font-size: var(--font-sm);
  font-weight: 400;
  color: var(--ink-soft);
  margin: 0;
  line-height: 1.47;
  letter-spacing: -0.224px;
  word-break: keep-all;
}

.feed-card__excerpt {
  font-size: var(--font-sm);
  color: var(--ink-faint);
  margin: 0;
  line-height: 1.47;
  letter-spacing: -0.224px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: keep-all;
}

/* Thread cards show the full first-card text, not a teaser -- no clamp. */
.feed-card__excerpt--full {
  display: block;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
  white-space: pre-line;
}

/* Tweet-quote card -- visually sets a thread's first tweet apart from a
   plain prose excerpt (borderless soft-fill panel, Notion callout-block
   style -- no hairline border, signal comes from the fill alone). A
   capped height keeps very long first tweets from making one list row
   far taller than its neighbors, without re-truncating the text itself
   (Session 201 removed hard truncation on purpose; the bottom edge is a
   hard clip, no fade). */
.feed-card__tweet-quote {
  background: #F6F5F4;
  border-radius: var(--r-md);
  padding: 14px 16px;
  max-height: 320px;
  overflow: hidden;
  position: relative;
}

[data-theme="dark"] .feed-card__tweet-quote {
  background: var(--bg-2);
}

.feed-card__tweet-quote .feed-card__excerpt--full {
  color: var(--ink-soft);
}

.feed-card__tweet-quote .feed-card__image-strip {
  margin-top: 8px;
}

.feed-card__image-strip {
  display: grid;
  gap: 3px;
  border-radius: var(--r-md);
  overflow: hidden;
  margin-top: 6px;
}
.feed-card__image-strip--1 { grid-template-columns: 1fr; }
.feed-card__image-strip--2 { grid-template-columns: repeat(2, 1fr); }
.feed-card__image-strip--3 { grid-template-columns: repeat(3, 1fr); }
.feed-card__image-strip img {
  width: 100%;
  height: 160px;
  object-fit: cover;
  display: block;
}

.feed-card__tweet-count {
  display: block;
  text-align: right;
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-faint);
  line-height: 1.4;
  letter-spacing: -0.12px;
}

.feed-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 4px;
}


/*  Grid view  */
.book-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 18px 12px;
  padding: 4px 0 8px;
}

.book-grid > .library-rating-group {
  grid-column: 1 / -1;
  margin-top: 4px;
}

.book-grid-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.book-grid-card.is-selected .book-grid-card__cover {
  box-shadow: 0 0 0 2px var(--accent), var(--product-shadow);
}

.book-grid-card:hover .book-grid-card__cover {
  box-shadow: var(--product-shadow);
}

.book-grid-card__cover {
  position: relative;
  width: 100%;
  aspect-ratio: 3/4;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
  box-shadow: none;
  transition: opacity 0.15s var(--ease), box-shadow 0.18s var(--ease);
}

/* Cover image fills the cell */
.book-grid-card__cover img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.book-cover {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
}

.book-cover img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.book-cover__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface);
  overflow: hidden;
  padding: 8px;
}

.book-cover__placeholder-text {
  font-size: var(--font-2xs);
  font-weight: 600;
  color: var(--ink-faint);
  line-height: 1.4;
  text-align: center;
  word-break: keep-all;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  max-width: 100%;
}

.book-cover--grid,
.book-cover--detail {
  border-radius: inherit;
}

.book-cover--row,
.book-cover--note {
  border-radius: inherit;
}

/* 19 badge inside grid card cover -- positioned top-right */
/* Solid --tag-adult-bg fill (same as every other adult-mark/tag--adult
   use) -- was a translucent frosted-glass tint + var(--tag-adult-color)
   text, which read as near-invisible after --tag-adult-bg/-color were
   swapped to a solid-orange-fill design (2026-08-05, user request: the
   badge should read as a filled orange chip, not a soft tinted number). */
.book-grid-card__cover .adult-mark {
  position: absolute;
  top: 7px;
  right: 7px;
  margin: 0;
  z-index: 2;
}

/* "외 N편" corner overlay -- grid-card equivalent of .feed-card__series-badge
   above. top-LEFT (adult-mark owns top-right) so both can show at once
   without overlapping. */
.book-grid-card__series-badge {
  position: absolute;
  top: 7px;
  left: 7px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 7px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--bg-card) 88%, transparent);
  color: var(--ink-soft);
  font-size: var(--font-xs);
  font-weight: 500;
  letter-spacing: -0.12px;
  white-space: nowrap;
}

.book-grid-card__more {
  position: absolute;
  right: 7px;
  bottom: 7px;
  z-index: 3;
  width: 28px;
  height: 28px;
  background: color-mix(in srgb, var(--bg-card) 88%, transparent);
  box-shadow: none;
  color: var(--ink-soft);
  opacity: 0;
  transition: opacity var(--dur) var(--ease), color var(--dur) var(--ease);
}

.book-grid-card:hover .book-grid-card__more,
.book-grid-card__more:focus-visible {
  opacity: 1;
}

.book-grid-card__more:hover {
  color: var(--ink);
}

.book-grid-card__select {
  position: absolute;
  top: 7px;
  left: 7px;
  z-index: 4;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1.5px solid var(--line-2);
  background: color-mix(in srgb, var(--bg-card) 92%, transparent);
  color: var(--bg-card);
  box-shadow: none;
  cursor: pointer;
}

.is-selected .book-grid-card__select {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
}

@media (hover: none) {
  .book-grid-card__more { opacity: 1; }
}

/* Progress bar -- thin line below cover, no overlay */
.book-grid-card__progress {
  display: block;
  width: 100%;
  height: 3px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--surface);
  -webkit-appearance: none;
  appearance: none;
  margin-top: 2px;
}
.book-grid-card__progress::-webkit-progress-bar   { background: var(--surface); border-radius: var(--r-pill); }
.book-grid-card__progress::-webkit-progress-value { background: var(--accent);  border-radius: var(--r-pill); }
.book-grid-card__progress::-moz-progress-bar      { background: var(--accent);  border-radius: var(--r-pill); }

.book-grid-card__title {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink);
  line-height: 1.35;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* Detail screen */
.det-subtitle {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  margin-top: 1px;
  font-weight: 400;
}

.det-author-handle {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  margin-left: 5px;
}

/* Search result */
.book-row-subtitle {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  margin-top: 1px;
}

.book-row-handle {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
}

/* Bottom row: author (left) + heart (right) */
.book-grid-card__bottom {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 0;
}

.book-grid-card__author {
  flex: 1;
  min-width: 0;
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  line-height: inherit;
  text-align: left;
  cursor: pointer;
}
.book-grid-card__author:hover { color: var(--ink); }


/* Heart button -- below cover, visible only when favorited or on hover */
.book-grid-card__fav {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: var(--r-md);
  color: var(--ink-faint);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s, color 0.15s;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.book-grid-card:hover .book-grid-card__fav,
.book-grid-card__fav.is-on {
  opacity: 1;
}

.book-grid-card__fav.is-on {
  color: var(--heart, #e05);
}

@media (hover: none) {
  .book-grid-card__fav { opacity: 1; }
}

.author-hero-handle {
  margin-top: 2px;
  color: var(--ink-faint);
  font-size: var(--font-xs);
  font-weight: 400;
}



.library-empty,
.library-loading {
  text-align: center;
  color: var(--ink-soft);
}

.library-empty {
  padding: 40px 0;
  font-size: var(--font-sm);
}

.library-loading {
  padding: 16px 0;
  font-size: var(--font-xs);
}

/*  Section head  */

.lib-section-head {
  display: flex;
  align-items: center;
  padding: 18px var(--pad) 8px;
}

.lib-section-lbl {
  font-size: var(--font-sm);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink);
}

/*  All-books controls row  */

.lib-toolbar {
  display: flex;
  align-items: center;
  padding: 0 var(--pad) 10px;
  gap: 8px;
}

.lib-kind-pills {
  flex: 1 1 0;
  min-width: 0;
}

.lib-toolbar__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.lib-filter-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 34px;
  min-width: 34px;
  padding: 0 13px;
  border-radius: var(--r-base);
  background: transparent;
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-soft);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), transform 0.12s var(--ease);
  white-space: nowrap;
}

.lib-filter-btn:hover,
.lib-filter-btn.is-open {
  background: color-mix(in srgb, var(--ink) 7%, var(--surface));
  color: var(--ink);
}

.lib-filter-btn:hover svg,
.lib-filter-btn.is-open svg {
  stroke-width: 2.3;
}

.lib-filter-btn:active {
  transform: scale(0.96);
}

.lib-select-btn.is-on {
  background: var(--ink);
  color: var(--bg);
}

.lib-icon-btn {
  width: 34px;
  padding: 0;
}

.library-select-bar {
  margin: 0 var(--pad) 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--bg-card) 96%, transparent);
}

/* lib-sort-menu / lib-sort-item removed — use shared .dropdown / .dropdown__item (4-overlays.css) */

/* Content kind filter pills — lives inside .lib-toolbar, flex-child */
.lib-kind-pills {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
}
.lib-kind-pills::-webkit-scrollbar { display: none; }

.lib-kind-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 34px;
  padding: 0 11px;
  border-radius: var(--r-base);
  background: transparent;
  font-size: var(--font-xs);
  font-weight: 500;
  color: var(--ink-soft);
  white-space: nowrap;
  flex-shrink: 0;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.lib-kind-pill:hover { background: color-mix(in srgb, var(--ink) 7%, var(--surface)); color: var(--ink); }
.lib-kind-pill:active { transform: scale(0.96); }
.lib-kind-pill.is-on {
  background: color-mix(in srgb, var(--ink) 7%, var(--surface));
  color: var(--ink);
  font-weight: 600;
}
.lib-kind-pill__count {
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  opacity: 0.55;
  font-size: 0.9em;
}

.library-sentinel {
  height: 1px;
}

/* Heart button in list row */
/* Always-visible fav button variant (used in search/aux-panel lists where hover doesn't apply) */
.book-row-fav {
  color: var(--ink-faint);
  transition: color var(--dur) var(--ease);
}
.book-row-fav.is-on--heart { color: var(--heart, #e05); }

/* ── Compact action menu (··· action popup) ─────────────
   Shell (backdrop/card/grip/header) is the shared .sheet/.sheet-card/
   .sheet-grip/.sheet-head system from css/4-overlays.css — see the
   "BookChive detail sheet spec" in design/DESIGN-notion.md. Only the
   action-list content below is specific to this menu. Width is capped
   via .sheet-card--action (desktop-only, see css/6-platforms.css). */
.ctx-list {
  list-style: none;
  margin: 0;
  padding: 6px 0;
}

.ctx-item {
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 15px 20px;
  font-size: var(--font-md);
  font-weight: 400;
  color: var(--ink);
  cursor: pointer;
  display: block;
  transition: background 0.12s var(--ease);
}

.ctx-item--core {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}

.ctx-item--core svg {
  flex-shrink: 0;
  color: var(--ink-soft);
}

.ctx-item--danger svg {
  color: var(--danger);
}

.ctx-item:hover,
.ctx-item:active { background: var(--surface); }

.ctx-item--danger { color: var(--danger); }
.ctx-item--empty  { color: var(--ink-faint); cursor: default; }
.ctx-item--empty:hover { background: none; }

.ctx-item__check { color: var(--ink-soft); font-weight: 600; }

.ctx-back {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-bottom: 1px solid var(--line-2);
  padding: 10px 18px;
  font-size: var(--font-xs);
  color: var(--ink-soft);
  cursor: pointer;
}

/* Rating row inside action sheet */
.ctx-rating-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px 6px;
  border-bottom: 1px solid var(--line-2);
}

.ctx-rating-label {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  flex-shrink: 0;
}

/* Collection rows (name + delete) inside action sheet */
.ctx-col-row {
  display: flex;
  align-items: center;
}
.ctx-col-name {
  flex: 1;
  text-align: left;
  background: none;
  border: none;
  padding: 13px 8px 13px 20px;
  font-size: var(--font-md);
  color: var(--ink);
  cursor: pointer;
  transition: background 0.12s var(--ease);
}
.ctx-col-name:hover { background: var(--surface); }
.ctx-col-emoji { font-style: normal; }
.ctx-col-del {
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 13px 18px;
  color: var(--ink-faint);
  font-size: 18px;
  cursor: pointer;
  line-height: 1;
  transition: color 0.12s var(--ease);
}
.ctx-col-del:hover { color: var(--danger); }

/* New collection form at bottom of collection view */
.ctx-col-new {
  display: flex;
  gap: 8px;
  padding: 10px 16px 12px;
  border-top: 1px solid var(--line);
}
.ctx-col-new__btn {
  padding: 8px 14px;
  border: none;
  border-radius: var(--r-sm);
  background: var(--accent);
  color: #fff;
  font-size: var(--font-sm);
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.ctx-col-new__btn:disabled { opacity: 0.35; cursor: default; }

/* Memo textarea inside action sheet */
.ctx-memo-wrap {
  padding: 8px 14px;
  border-bottom: 1px solid var(--line-2);
}

.ctx-memo {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 8px 10px;
  font-size: var(--font-xs);
  color: var(--ink);
  font-family: inherit;
  resize: none;
  outline: none;
  line-height: 1.5;
  box-sizing: border-box;
}

.ctx-memo:focus { border-color: var(--accent-focus, #0071e3); }

/*  Dark mode: cover shadows  */
[data-theme="dark"] .book-grid-card__cover { box-shadow: none; }
[data-theme="dark"] .book-grid-card:hover .book-grid-card__cover { box-shadow: var(--product-shadow); }
[data-theme="dark"] .book-grid-card__cover {
  outline: 1px solid var(--line);
  outline-offset: -1px;
}

/* ── Collection modal ────────────────────────────────────────────────────── */
.col-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.48);
  z-index: var(--z-sheet, 800);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.col-modal {
  background: var(--bg-card);
  border-radius: var(--r-lg);
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-3);
}

.col-modal__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 16px 4px;
}

.col-modal__title {
  font-size: var(--font-md);
  font-weight: 600;
  color: var(--ink);
}

.col-modal__preview {
  display: flex;
  justify-content: center;
  padding: 10px 0 8px;
}

.col-modal__chosen {
  font-size: 52px;
  line-height: 1;
  user-select: none;
}

.col-modal__search {
  margin: 0 12px 8px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 8px 12px;
  font-size: var(--font-sm);
  background: var(--bg);
  color: var(--ink);
  outline: none;
  width: calc(100% - 24px);
}

.col-modal__search:focus { border-color: var(--accent-focus, #0071e3); }

.col-modal__cats {
  display: flex;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 0 12px 6px;
  gap: 2px;
}
.col-modal__cats::-webkit-scrollbar { display: none; }

.col-modal__cat-btn {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--r-md);
  font-size: 20px;
  display: grid;
  place-items: center;
  background: transparent;
  transition: background var(--dur) var(--ease);
}
.col-modal__cat-btn.is-on { background: var(--surface); }

.col-modal__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  padding: 4px 12px 8px;
  max-height: 200px;
  overflow-y: auto;
  min-height: 100px;
  overscroll-behavior: contain;
}

.col-modal__emoji-btn {
  font-size: var(--font-xl);
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--r-md);
  background: transparent;
  transition: background var(--dur) var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.col-modal__emoji-btn:hover,
.col-modal__emoji-btn:active { background: var(--surface); }
.col-modal__emoji-btn.is-selected { background: color-mix(in srgb, var(--accent) 15%, transparent); }

.col-modal__empty {
  grid-column: 1 / -1;
  color: var(--ink-faint);
  font-size: var(--font-sm);
  text-align: center;
  padding: 20px 0;
}

.col-modal__name-input {
  margin: 0 12px 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 10px 12px;
  font-family: var(--font-sans);
  font-size: var(--font-sm);
  background: var(--bg);
  color: var(--ink);
  outline: none;
}
.col-modal__name-input:focus { border-color: var(--accent-focus, #0071e3); }

.col-modal__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px 14px;
  gap: 8px;
}

.col-modal__actions-right {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.col-modal__delete-btn {
  margin-right: auto;
}


.author-select-btn {
  height: 30px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-base);
  background: var(--surface);
  color: var(--ink-soft);
  font-size: var(--font-xs);
  font-weight: 600;
  cursor: pointer;
}

.author-select-btn.is-on {
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
}

.author-select-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  margin: 0 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--bg-card) 96%, transparent);
  box-shadow: none;
}

.det-cover img {
  display: block;
  object-fit: cover;
}


/* ============================================================
   Layer 3: Reader — Article & Thread
   ============================================================ */

/* ── Shared: screen shell ─────────────────────────────────── */

.reader-screen {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  background: var(--bg);
  position: relative;
}

/* Reading surfaces use the same app background, including overscroll bounce. */
.reader-screen .reader-body,
.reader-screen .col-scroll {
  background: var(--bg);
}

.reader-screen .reader-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}


/* ── Shared: thin progress bar ────────────────────────────── */

.reader-vbar {
  position: fixed;
  right: 0;
  top: 50%;
  height: 25vh;
  transform: translateY(-50%);
  width: 3px;
  z-index: 129;
  pointer-events: none;
  background: color-mix(in srgb, var(--line) 60%, transparent);
}

/* Native scrollbar is a persistent, space-taking element only on desktop
   (mouse/trackpad) browsers — mobile uses transient overlay scrollbars,
   so only push the bar away from the edge when pointer:fine. */
@media (pointer: fine) {
  .reader-vbar {
    right: 10px;
  }
}

.reader-vbar__fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(var(--chapter-pct, 0) * 100%);
  background: var(--ink-faint);
  transition: height 0.3s var(--ease);
}

/* Reader-specific column sizing (base col defined in 1-primitives.css) */
.reader-pref-scroll:focus { outline: none; }

.reader-screen .reader-pref-scroll .col {
  padding-left: var(--reader-pad, var(--pad-lg));
  padding-right: var(--reader-pad, var(--pad-lg));
  padding-top: calc(var(--bar-h) + 36px);
  padding-bottom: 128px;
}

.reader-screen .col,
.reader-screen .col--narrow {
  max-width: min(770px, 100%);
}

.reader-body--toc,
.reader-body--works {
  display: flex;
  flex-direction: row;
}

.reader-body--toc .reader-pref-scroll {
  flex: 1;
  min-width: 0;
}

.reader-body--toc .reader-pref-scroll .col {
  max-width: min(770px, 100%);
}

.toc-panel__inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.toc-panel__head {
  padding: 12px 14px 8px;
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-faint);
  letter-spacing: 0.04em;
  flex-shrink: 0;
  border-bottom: 1px solid var(--line);
}

.toc-panel__list {
  flex: 1;
  overflow-y: auto;
  padding: 6px 0;
}

.reader-mode-page .reader-pref-scroll {
  display: block;
  overflow-x: auto;
  overflow-y: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.reader-mode-page .reader-pref-scroll::-webkit-scrollbar {
  display: none;
}

.reader-mode-page .reader-pref-scroll .col {
  height: 100%;
  max-width: none;
    column-width: min(720px, calc(100vw - (var(--reader-pad, var(--pad-lg)) * 2)));
}

.reader-mode-scroll .reader-pref-scroll {
  overflow-x: hidden;
  overflow-y: auto;
}

.reader-screen .col {
  padding-top: calc(var(--bar-h) + 12px);
  padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px));
}

/* ── Author block ─────────────────────────────────────────── */

.author--new {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 0 16px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 18px;
}

.author--new .author-name {
  font-size: var(--font-md);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink);
}

.author--new .author-source {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--font-xs);
  color: var(--ink-soft);
  margin-top: 2px;
}

/* ── Article: chapter meta + title + tags ─────────────────── */

.read-meta {
  font-size: var(--font-xs);
  color: var(--reader-ink-soft);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  letter-spacing: 0;
  margin-bottom: 12px;
}

.read-title {
  margin: 0 0 18px;
  font-family: 'Pretendard', system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Apple SD Gothic Neo", sans-serif;
  font-size: var(--font-3xl);
  line-height: 1.18;
  letter-spacing: 0;
  font-weight: 600;
  color: var(--reader-ink);
}

.read-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}


.det-tag-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.det-tag-label {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-faint);
  letter-spacing: 0.05em;
}

/* ── Article body ─────────────────────────────────────────── */

.read-body {
  font-size: var(--reader-font-size);
  line-height: var(--reader-leading);
  color: var(--reader-ink);
  letter-spacing: var(--reader-tracking);
  /* CJK character-based wrapping (not word/eojeol-based keep-all) -- lets
     justified text stay dense and gap-free at any width, including the
     narrow mobile widths where keep-all+justify used to force a left-align
     fallback (removed below, no longer needed). English-heavy paragraphs
     opt back into word-safe wrapping via .reader-para--en-heavy so a URL
     or English phrase doesn't fracture mid-word. */
  word-break: break-all;
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

.read-body .reader-text {
  font-size: inherit;
  line-height: inherit;
}

/* Paragraphs */
.reader-para {
  margin: 0 0 var(--reader-para-gap);
  text-align: left;
  text-wrap: pretty;
  word-break: break-all;
  overflow-wrap: anywhere;
}

/* English-heavy paragraph (design/reader-utils.tsx::isEnglishHeavyParagraph,
   applied in BodyText.tsx) -- protects English words/URLs from the
   character-based breaking above. No `lang` attribute is set on the
   element, so `hyphens: auto` is a harmless no-op until/unless that's
   added; word-break/overflow-wrap alone already prevent mid-word breaks. */
.reader-para--en-heavy {
  word-break: keep-all;
  overflow-wrap: break-word;
  hyphens: auto;
}

.reader-para--align-left { text-align: left; }
.reader-para--align-center { text-align: center; }
.reader-para--align-right { text-align: right; }

.reader-text--justify .reader-para:not(.reader-para--align-left):not(.reader-para--align-center):not(.reader-para--align-right) {
  text-align: justify;
  text-justify: inter-character;
}

/* inter-character justify (above) spreads extra space across every
   character gap on a line, not just word spaces -- fine and even for a
   normal full line, but if a link forces an early wrap, the short line
   left behind has very few gaps to stretch and each one balloons
   (confirmed visually, see the 2026-08-21 session log). Falling back to
   the browser's normal word-based justify for any paragraph that contains
   a link avoids that specifically, at the cost of slightly less even
   spacing on that one paragraph's other lines -- a better trade than
   dramatic per-character gaps right next to the link. */
.reader-text--justify .reader-para:not(.reader-para--align-left):not(.reader-para--align-center):not(.reader-para--align-right):has(a) {
  text-align: left;
}

.reader-para-gap { height: 0.8em; }

.reader-hr {
  border: none;
  border-top: 1px solid var(--reader-line);
  width: 56px;
  margin: 30px auto;
}

.reader-hr--dashed {
  border-top-style: dashed;
  width: 100%;
  opacity: 0.4;
}

.reader-locked {
  text-align: center;
  color: var(--c-text-3, #aaa);
  font-size: 0.78em;
  margin: 1.4em 0;
  user-select: none;
}

.reader-comment {
  border: 1px solid var(--reader-line, #ddd);
  border-radius: var(--r-md);
  padding: 10px 14px 8px;
  margin: 6px 0;
  font-size: 0.9em;
}
.reader-comment-header {
  font-size: 0.82em;
  color: var(--c-text-3, #aaa);
  padding-bottom: 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--reader-line, #eee);
}
.reader-comment .reader-para {
  margin: 2px 0;
}

/* Blockquote -- three source styles, split from Postype's own editor CSS
   (blockquote-type1..4, see devlogs/DEVLOG-2026-08.md): [박스]/box is now
   marker-left specifically (border-left only, matching type2), [콜아웃]/
   callout is a bordered card (all four sides, matching type3), [인용구]/
   pullquote is a centered decorative quote with no border (matching
   type1/type4). Previously all three collapsed into one undifferentiated
   `.reader-box`, which is the "marker-left/callout 구분 못 함" bug. */
.reader-box {
  margin: 22px 0;
  padding: 2px 0 2px 16px;
  border-left: 3px solid var(--reader-line, #ddd);
  font-style: italic;
}

.reader-callout {
  margin: 22px 0;
  padding: 12px 16px;
  border: 1px solid var(--reader-line, #ddd);
  border-radius: var(--r-md);
}

/* .reader-para's margin is bottom-only (see its own rule above), so the
   last paragraph inside a container block stacked its own margin-bottom
   on top of the box's own padding-bottom -- the box's bottom edge ended
   up visibly further from its last line than its top edge is from its
   first line, and "reduce padding" alone wouldn't have fixed the
   asymmetry since the extra gap was para margin, not box padding. */
.reader-box > :last-child,
.reader-callout > :last-child,
.reader-pullquote > :last-child {
  margin-bottom: 0;
}

.reader-pullquote {
  position: relative;
  margin: 30px auto;
  padding: 34px 8px 4px;
  max-width: 82%;
  text-align: center;
  font-style: italic;
}

.reader-pullquote::before {
  content: '\201C';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  font-family: Georgia, Times, serif;
  font-size: 44px;
  line-height: 1;
  color: var(--ink-faint, #999);
  pointer-events: none;
}

.reader-pullquote .reader-para {
  text-align: center;
}

/* ── Format-based paragraph rhythm (devlogs/TODO.md [Feature] reader
   typography) ─────────────────────────────────────────────────────────
   Consecutive blocks of the SAME format tighten (read as one visual
   group); a format change keeps each type's own already-generous default
   margin (22-30px for box/callout/pullquote, set above) as the transition
   cue, so no separate "wide" value is needed there. Every rule below
   targets BOTH sides of the pair (:has(+ X) for the earlier sibling's
   bottom margin, `+ X` for the later sibling's top margin) since adjacent
   margins collapse to their max, not their sum -- overriding only one
   side would leave the untouched side's original (larger) margin in
   effect and the tightening would silently do nothing. */

.reader-box:has(+ .reader-box)           { margin-bottom: 8px; }
.reader-box + .reader-box                { margin-top: 8px; }
.reader-callout:has(+ .reader-callout)   { margin-bottom: 8px; }
.reader-callout + .reader-callout        { margin-top: 8px; }
.reader-pullquote:has(+ .reader-pullquote) { margin-bottom: 12px; }
.reader-pullquote + .reader-pullquote      { margin-top: 12px; }

/* Dialogue paragraphs (design/reader-utils.tsx::isDialogueParagraph) tighten
   against each other -- a run of back-to-back quoted lines reads as one
   exchange, not separate beats. .reader-para's own margin-top is always 0
   (margin is bottom-only, see above), so only the earlier sibling's
   bottom margin needs overriding for the collapsed gap to actually shrink. */
.reader-para--dialogue:has(+ .reader-para--dialogue) {
  margin-bottom: 0.2em;
}

/* A format change between narrative prose and dialogue widens to 2x
   the normal paragraph gap (user request, 2026-08-25 -- 1.75x, itself a
   correction of an earlier 0.5x/"tighten" mistake, was narrowed down to
   exactly 2x). Uses --reader-para-gap (not a fixed value) so it scales
   with the user's own paragraph-spacing setting. */
.reader-para--dialogue:has(+ .reader-para:not(.reader-para--dialogue)),
.reader-para:not(.reader-para--dialogue):has(+ .reader-para--dialogue) {
  margin-bottom: calc(var(--reader-para-gap) * 2);
}

/* Two consecutive "bare" paragraphs -- no dialogue, no explicit align, no
   font-category -- widen the same way (user request, 2026-08-25, same 2x
   value applied to both rules together). `[class="reader-para"]` is an
   EXACT match on the class attribute (not a `:not()` chain enumerating
   every modifier), so this stays correct if a new reader-para--*
   modifier is added later without needing to update this selector. */
.reader-para[class="reader-para"]:has(+ .reader-para[class="reader-para"]) {
  margin-bottom: calc(var(--reader-para-gap) * 2);
}

/* Spoiler */
.reader-spoiler {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  margin: 14px 0;
  overflow: hidden;
}

.reader-spoiler-title {
  padding: 10px 14px;
  font-size: var(--font-sm);
  font-weight: 600;
  cursor: pointer;
  color: var(--ink-soft);
  background: var(--bg-2);
  list-style: none;
}

/* Chat bubbles (Postype blockquote-type5/6) */
.reader-bubble {
  display: flex;
  margin: 6px 0;
}

.reader-bubble--left  { justify-content: flex-start; }
.reader-bubble--right { justify-content: flex-end; }

.reader-bubble-text {
  max-width: 72%;
  padding: 11px 18px;
  /* Was var(--r-pill) (999px) -- a true pill only reads correctly for a
     single short line. Longer/multi-line content (e.g. an embedded link
     card's title) distorted into a lopsided blob with text spilling past
     the curved edge, since a 999px corner radius on a box that's taller
     than it is wide consumes most of the box height per corner. */
  border-radius: 18px;
  font-size: 0.92em;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: keep-all;
  overflow-wrap: break-word;
}

.reader-bubble--left .reader-bubble-text {
  background: var(--surface);
  color: var(--reader-ink);
  border-bottom-left-radius: 4px;
}

.reader-bubble--right .reader-bubble-text {
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}

/* .reader-link's own `color: var(--link)` (0-reset.css) always wins over
   the bubble's inherited white text -- and --link/--accent are literally
   the same color, so a link inside a right-side (accent-colored) bubble
   rendered fully invisible (identical to its own background). */
.reader-bubble--right .reader-link {
  color: #fff;
  text-decoration-color: rgba(255, 255, 255, 0.6);
}

.reader-image {
  max-width: 100%;
  width: auto;
  height: auto;
  border-radius: var(--r-lg);
  display: block;
  margin: 0 auto;
  cursor: zoom-in;
}

.reader-img-box {
  position: relative;
  content-visibility: auto;
  contain-intrinsic-size: 1px 520px;
  margin: 8px auto;
  text-align: center;
}

/* [Cleaning] merged in from design/screens/library/library.css (2026-08-06)
   -- was defined there for no library-specific reason, splitting this
   component's rules across two screen CSS files. */
.reader-img-box img,
.reader-img-box video {
  max-width: 100%;
  width: auto;
  height: auto;
  display: block;
  margin: 0 auto;
}

.reader-img-save-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  display: grid;
  place-items: center;
  opacity: 0;
  transition: opacity 0.15s;
  backdrop-filter: blur(4px);
}

.reader-img-box:hover .reader-img-save-btn,
.reader-img-save-btn.is-on { opacity: 1; }

@media (pointer: coarse) {
  .reader-img-save-btn { opacity: 1; }
}

.reader-image.is-pending,
.reader-gallery-img.is-pending,
.tweet-img.is-pending,
.thread-media.is-pending {
  min-height: min(62vh, 520px);
  width: 100%;
  background:
    linear-gradient(90deg,
      color-mix(in srgb, var(--surface) 88%, transparent),
      color-mix(in srgb, var(--line) 55%, transparent),
      color-mix(in srgb, var(--surface) 88%, transparent));
  background-size: 220% 100%;
  animation: reader-image-pending 1.4s ease-in-out infinite;
}

.reader-image.is-loaded,
.reader-gallery-img.is-loaded,
.tweet-img.is-loaded,
.thread-media.is-loaded {
  min-height: 0;
  animation: none;
}

@keyframes reader-image-pending {
  from { background-position: 100% 0; }
  to { background-position: -100% 0; }
}

.reader-gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  content-visibility: auto;
  contain-intrinsic-size: 1px 520px;
}

.reader-gallery-cell {
  position: relative;
}

.reader-gallery-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-lg);
  cursor: zoom-in;
}

/* Strip/comic mode: consecutive images flow seamlessly with no gap */
.reader-image--strip {
  width: 100%;
  max-width: 100%;
  border-radius: 0;
  margin: 0;
  display: block;
}
.reader-text--strip .reader-img-box {
  margin: 0;
  padding: 0;
  line-height: 0;
}

/* Visual/comic screen: remove col padding so images touch screen edges.
 * Mobile: max-width:100% so images fill the screen.
 * Desktop: capped at 900px (wider than article 680px, but not unbounded). */
.reader-visual .col {
  padding-left: 0;
  padding-right: 0;
  padding-top: 0;
  max-width: 100%;
}

@media (min-width: 768px) {
  .reader-visual .col {
    max-width: 680px;
    padding-left: var(--reader-pad, var(--pad-lg));
    padding-right: var(--reader-pad, var(--pad-lg));
    padding-top: 20px;
  }
}

/* End of article marker */
.reader-end {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24px 0 8px;
  border-top: 1px solid var(--line);
  margin-top: 32px;
}

.end-meta {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
}

/* Active TTS paragraph */
.audio-para-active {
  background: var(--reader-sel);
  border-radius: var(--r-md);
  padding: 2px 6px;
  margin: 0 -6px;
}

/* Body-search deep-link landing flash (ThreadReader.tsx) -- briefly marks
   the tweet a search result actually matched, since scrollIntoView alone
   doesn't tell the eye where to look on a long thread. */
.reader-search-jump-flash {
  animation: reader-search-jump-flash 2s ease-out;
  border-radius: var(--r-md);
}
@keyframes reader-search-jump-flash {
  0%, 65% { background: var(--reader-sel); }
  100% { background: transparent; }
}

/* ── Tweet cards (thread mode inside article reader) ────────── */

.thread-feed { display: flex; flex-direction: column; }

/* tweet-card: avatar removed — simple block */
.tweet-card {
  position: relative;
  display: block;
  padding: 16px 8px;
  border-bottom: 1px solid var(--line-2);
  transition: background 0.12s var(--ease);
  border-radius: var(--r-md);
  margin: 0 -8px;
}

.tweet-card:last-child { border-bottom: none; }

/* Per-tweet hover tint — card has -8px bleed margin + 8px inner padding
   above precisely so this background can round off inside the reading
   column instead of touching its edges. */
.tweet-card:hover {
  background: #F6F5F4;
}

/* Bookmarked card: left accent line */
.tweet-card--bookmarked {
  border-left: 2px solid var(--warn);
  padding-left: 10px;
}

.tweet-para { margin: 0; letter-spacing: -0.1px; }

.tweet-img {
  width: calc(100% - 10px);
  max-width: calc(100% - 10px);
  height: auto;
  border-radius: var(--r-lg);
  margin: 10px auto;
  display: block;
}

.tweet-box {
  margin: 10px 0;
  padding: 4px 0 4px 12px;
  border-left: 2px solid var(--line);
  color: var(--ink-soft);
  font-size: var(--font-md);
}

.tweet-callout {
  margin: 10px 0;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--ink-soft);
  font-size: var(--font-md);
}

.tweet-pullquote {
  margin: 14px auto;
  padding: 6px 8px 2px;
  max-width: 85%;
  text-align: center;
  font-style: italic;
  color: var(--ink-soft);
  font-size: var(--font-md);
}

/* Per-tweet numbered divider */
.tweet-divider {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 16px 0 8px;
}

.tweet-divider__num {
  font-size: var(--font-xs);
  font-weight: 700;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}

.tweet-divider__date {
  font-weight: 400;
  color: var(--ink-faint);
  letter-spacing: 0;
}

/* "..." toggle now lives at the right edge of the divider row (moved off
   its own line, wrapped in the shared .dropdown-wrap for positioning) and
   stays invisible until the tweet is hovered/active, matching the
   tweet-card hover tint above. */
.tweet-card-more-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: var(--r-sm);
  color: var(--ink-faint);
  opacity: 0;
  transition: opacity 0.15s var(--ease), background 0.15s var(--ease), color 0.15s var(--ease);
}

.tweet-card-more-btn:hover {
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  color: var(--ink);
}

.tweet-card:hover .tweet-card-more-btn,
.tweet-card-more.is-open .tweet-card-more-btn,
.tweet-card-more-btn:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  .tweet-card-more-btn { opacity: 1; }
}

/* Author works section */

.author-works-section {
  margin-top: 36px;
  border-top: 1px solid var(--line);
  padding-top: 20px;
  padding-bottom: 16px;
}

.author-works-head {
  font-size: var(--font-sm);
  font-weight: 400;
  color: var(--ink-soft);
  margin-bottom: 12px;
  line-height: 1.4;
}

.author-works-name {
  font-weight: 700;
  color: var(--ink);
}

.author-works-tier + .author-works-tier { margin-top: 20px; }

.author-works-tier-label {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-faint);
  letter-spacing: 0.03em;
  margin-bottom: 6px;
}

.author-works-list { display: flex; flex-direction: column; }

.author-works-see-all {
  width: 100%;
  margin-top: 16px;
  padding: 10px 0;
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink-soft);
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.author-works-see-all:hover {
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  color: var(--ink);
}

.author-works-item {
  width: 100%;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-2);
  text-align: left;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.author-works-item:last-child { border-bottom: none; }
.author-works-item:hover {
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}

.author-works-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.author-works-item-title {
  font-size: var(--font-sm);
  font-weight: 400;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.author-works-item-meta {
  font-size: var(--font-xs);
  color: var(--ink-faint);
}

.reader-works-sidebar { display: none; }

@media (min-width: 768px) {
  .reader-body--works .col-scroll { flex: 1; min-width: 0; }

  .reader-works-sidebar {
    display: block;
    width: 260px;
    flex-shrink: 0;
    border-left: 1px solid var(--reader-line, var(--line));
    overflow-y: auto;
    padding: calc(var(--bar-h) + 32px) 20px 60px;
    background: var(--bg);
  }

  .reader-works-sidebar .author-works-section {
    margin-top: 0;
    border-top: none;
    padding-top: 0;
  }
}

/* ── TOC side panel ───────────────────────────────────────── */

.toc-panel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 280px;
  background: var(--bg);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  z-index: 20;
}

.toc-panel__inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 18px 18px 24px;
}

.toc-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
  font-size: var(--font-sm);
  font-weight: 600;
}

.toc-panel__list {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.toc-item {
  display: flex;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--r-md);
  color: var(--ink-soft);
  font-size: var(--font-sm);
  line-height: 1.4;
}

.toc-item:hover { color: var(--ink); }
.toc-item.is-on  { background: var(--bg-2); color: var(--ink); font-weight: 600; }

.toc-item .toc-num {
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  flex: none;
  width: 22px;
  font-size: var(--font-xs);
}


/* ── Reader footer nav ───────────────────────────────────── */
.read-foot {
  position: fixed;
  left: 50%;
  right: auto;
  bottom: max(16px, env(safe-area-inset-bottom, 0px));
  z-index: 34;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: min(calc(100vw - 32px), 420px);
  min-height: 52px;
  padding: 7px 10px;
  border: 1px solid var(--reader-chrome-line);
  border-radius: var(--r-pill);
  background: var(--bg);
  box-shadow: var(--shadow-2);
  pointer-events: auto;
  flex-shrink: 0;
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}

.read-foot--hidden {
  transform: translate(-50%, calc(100% + 24px));
  opacity: 0;
  pointer-events: none;
}

.read-foot__btn {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex: 0 0 auto;
  width: clamp(96px, 28vw, 132px);
  min-width: 0;
  height: 36px;
  padding: 0 14px;
  border-radius: var(--r-md);
  font-size: var(--font-xs);
  font-weight: 400;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), opacity var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
  -webkit-tap-highlight-color: transparent;
}

/* Nav buttons — Prev / Next */
.read-foot__btn.btn--ghost {
  background: transparent;
  color: var(--accent);
  border: 1px solid transparent;
  box-shadow: none;
}
.read-foot__btn.btn--ghost:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
  border-color: transparent;
}
.read-foot__btn.btn--ghost:active:not(:disabled) { transform: scale(0.95); }
.read-foot__btn.btn--ghost:disabled {
  opacity: 0.34;
  box-shadow: none;
  cursor: not-allowed;
}
[data-theme="dark"] .read-foot__btn.btn--ghost {
  background: transparent;
  box-shadow: none;
}

[data-theme="dark"] .read-foot {
  border-color: color-mix(in srgb, #fff 14%, var(--line) 86%);
  background: var(--bg);
  box-shadow: var(--shadow-3);
}

/* Chapter position counter */
.read-foot__pos {
  pointer-events: none;
  flex: 0 0 58px;
  text-align: center;
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}

.text-btn {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-base);
  font-size: var(--font-sm);
  color: var(--ink);
  font-weight: 400;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur) var(--ease);
}

.text-btn:hover { background: var(--bg-2); }
.text-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.text-btn.primary:hover { opacity: 0.88; }

/* Thread loading state */
.thread-loading {
  padding: 32px 20px;
  text-align: center;
  font-size: var(--font-sm);
  color: var(--ink-faint);
}

/* ── Source status banners ───────────────────────────────── */

.source-status-banner {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 12px 20px;
  font-size: var(--font-sm);
  line-height: 1.5;
  flex-shrink: 0;
}

.source-status-banner--deleted {
  background: var(--bg-2);
  color: var(--ink-soft);
}

.source-status-banner--blocked {
  background: var(--bg-2);
  color: var(--ink-soft);
}

.source-status-banner--unreachable {
  background: var(--bg-2);
  color: var(--ink-soft);
  border-left: 3px solid var(--warn);
}

.source-status-banner--needs-confirm {
  background: var(--bg-2);
  color: var(--ink-soft);
  border-left: 3px solid var(--danger);
}

.source-status-banner--unchanged {
  background: var(--bg-2);
  color: var(--ink-faint);
}

.source-status-icon { flex-shrink: 0; font-size: var(--font-md); }

.source-status-recrawl {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 20px 12px;
}

.source-status-recrawl__msg {
  font-size: var(--font-xs);
  color: var(--ink-faint);
}

/* ── ReaderEditorBar (.reb) ──────────────────────────────── */

.reb {
  position: fixed;
  top: var(--bar-h, 48px);
  left: 0;
  right: 0;
  z-index: 128;
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border-bottom: 1px solid var(--reader-chrome-line, var(--line));
  color: var(--ink);
  font-size: var(--font-compact);
}

.reb__row {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 5px 10px;
  min-height: 40px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.reb__row::-webkit-scrollbar { display: none; }

/* Row 1: Insert row */
.reb__row--insert {
  gap: 0;
  padding: 4px 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
}

.reb__insert-group {
  display: flex;
  align-items: center;
  gap: 2px;
}

.reb__ins-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 9px;
  font-size: var(--font-xs);
  font-weight: 500;
  color: var(--ink-soft);
  background: none;
  border: none;
  border-radius: var(--r-sm, 6px);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  white-space: nowrap;
}
.reb__ins-btn:hover:not(:disabled) { background: var(--surface); color: var(--ink); }
.reb__ins-btn:disabled { opacity: 0.38; cursor: default; }
.reb__ins-btn.is-active { background: var(--accent-bg); color: var(--accent); }

.reb__ins-icon { flex-shrink: 0; }

.reb__ins-right {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
  flex-shrink: 0;
}

.reb__edit-state {
  font-size: var(--font-2xs);
  font-weight: 500;
  color: var(--ink-faint);
  padding: 0 6px;
  white-space: nowrap;
}
.reb__edit-state.is-dirty { color: var(--warn); }

.reb__adult-toggle { padding: 0 2px; }

.reb__action-btn {
  padding: 5px 11px;
  font-size: var(--font-xs);
  font-weight: 600;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  cursor: pointer;
  color: var(--ink);
  transition: background 0.1s;
  white-space: nowrap;
}
.reb__action-btn:hover { background: var(--surface-raised, var(--surface)); }
.reb__action-btn--primary {
  background: var(--accent);
  border-color: transparent;
  color: #fff;
}
.reb__action-btn--primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 88%, #000);
}
.reb__action-btn--primary:disabled { opacity: 0.55; cursor: default; }
.reb__action-btn--danger {
  padding: 5px 8px;
  background: none;
  border-color: transparent;
  color: var(--danger, #e53);
}
.reb__action-btn--danger:hover {
  background: color-mix(in srgb, var(--danger, #e53) 10%, transparent);
}

/* Row 2: Format row */
.reb__row--format {
  gap: 3px;
  padding: 4px 10px;
}

.reb__select {
  height: 28px;
  padding: 0 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  background: var(--bg, #fff);
  color: var(--ink);
  font-size: var(--font-xs);
  cursor: pointer;
}
.reb__select--font { min-width: 80px; max-width: 110px; }
.reb__select--size { width: 52px; }

.reb__sep {
  width: 1px;
  height: 20px;
  background: var(--line);
  flex-shrink: 0;
  margin: 0 4px;
}

.reb__fmt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: none;
  border: none;
  border-radius: var(--r-sm, 6px);
  cursor: pointer;
  color: var(--ink-soft);
  font-size: var(--font-compact);
  transition: background 0.1s, color 0.1s;
}
.reb__fmt-btn:hover { background: var(--surface); color: var(--ink); }
.reb__fmt-btn--b { font-size: var(--font-sm); }
.reb__fmt-btn--i { font-style: italic; }
.reb__fmt-btn--u { text-decoration: underline; }
.reb__fmt-btn--align { font-size: 0; } /* use SVG only */

/* Steppers (자간/줄간) */
.reb__stepper {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  overflow: hidden;
  height: 28px;
  font-size: var(--font-xs);
}

.reb__stepper-label {
  padding: 0 6px 0 8px;
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  white-space: nowrap;
  border-right: 1px solid var(--line);
  height: 100%;
  display: flex;
  align-items: center;
}

.reb__step {
  width: 24px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  font-size: var(--font-sm);
  color: var(--ink-soft);
  transition: background 0.1s;
}
.reb__step:hover { background: var(--surface); color: var(--ink); }

.reb__stepper-val {
  min-width: 28px;
  text-align: center;
  font-size: var(--font-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

/* Link dropdown */
.reb__link-drop {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 12px 10px;
  border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  background: var(--reader-chrome-bg, var(--surface-raised, #f5f5f7));
}

.reb__link-url-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.reb__link-input {
  flex: 1;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  background: var(--bg, #fff);
  color: var(--ink);
  font-size: var(--font-compact);
}

.reb__link-insert,
.reb__link-cancel {
  padding: 0 12px;
  height: 32px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  cursor: pointer;
  font-size: var(--font-xs);
  font-weight: 600;
  background: none;
  white-space: nowrap;
}
.reb__link-insert { background: var(--accent); border-color: transparent; color: #fff; }
.reb__link-cancel { color: var(--ink-soft); }
.reb__link-cancel:hover { background: var(--surface); }

@media (max-width: 767px) {
  .reb__row--insert { flex-wrap: wrap; }
  .reb__ins-right { width: 100%; justify-content: flex-end; }
}

/* ── Editable book meta in header ────────────────────────── */
.read-meta-edit {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 14px;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--line));
  border-radius: var(--r-md, 8px);
  background: color-mix(in srgb, var(--accent) 4%, var(--bg, #fff));
}

.read-meta-edit__label {
  font-size: var(--font-2xs);
  font-weight: 600;
  color: var(--ink-faint);
  letter-spacing: 0.03em;
  margin-top: 4px;
}
.read-meta-edit__label:first-child { margin-top: 0; }

.read-meta-edit__input {
  width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 6px);
  background: var(--bg, #fff);
  color: var(--ink);
  font-size: var(--font-sm, 14px);
  font-family: inherit;
  box-sizing: border-box;
  transition: border-color 0.12s;
}
.read-meta-edit__input:focus {
  outline: none;
  border-color: var(--accent);
}
.read-meta-edit__input--title {
  font-size: 1.1em;
  font-weight: 600;
}

.adult-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--font-sm);
  color: var(--ink-soft);
  cursor: pointer;
}


.editor-tool {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--bg);
  border: 1px solid var(--line);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.editor-tool:hover, .editor-tool:active {
  background: var(--bg-2);
  color: var(--ink);
}

.editor-tool--italic { font-style: italic; }
.editor-tool--underline { text-decoration: underline; }


.edit-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 10px;
}

.edit-btn {
  padding: 7px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-base);
  font-size: var(--font-sm);
  font-weight: 400;
  background: var(--bg);
  color: var(--ink);
  cursor: pointer;
}

.edit-btn--primary {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

.edit-btn--danger {
  color: var(--danger, #e53);
  border-color: var(--danger, #e53);
  margin-right: auto;
}

/* icon-btn / icon-btn--sm — compact icon buttons (reader settings, note, fix sheets) */
/* Shared compact icon buttons live in 1-primitives.css. */

/* ── Reader-context warm theme ──────────────────────────────── */

.reader-screen .read-body .reader-para,
.reader-screen .read-body .reader-text { color: var(--reader-ink); }

.reader-screen .author--new { border-bottom-color: var(--reader-line); }

.reader-screen .tag {
  color: var(--reader-ink-soft);
  background: var(--reader-surface, var(--surface));
}

.reader-screen .reader-end { border-top-color: var(--reader-line); }
.reader-screen .reader-end .end-meta { color: var(--reader-ink-soft); }

/* ── Dark / no-flash guard — slow images never flash white ─── */

.reader-image,
.reader-img-box img,
.reader-img-box video,
.tweet-img {
  background: var(--surface);
}

[data-theme="dark"] .reader-image,
[data-theme="dark"] .reader-img-box img,
[data-theme="dark"] .tweet-img {
  background: var(--bg-2);
}

/* ── Thread: missing media + layout classes ──────────────────
   These were never written to CSS. All class names match TSX exactly.
   ──────────────────────────────────────────────────────────── */


/* ── Selection action bar ────────────────────────────────────
   Floats above selected text in both article + thread reader  */
/* position: fixed so coords are pure viewport — no .phone-screen dependency */
.sel-bar {
  position: fixed;
  left: var(--sel-x, 50%);
  top: var(--sel-y, 0);
  transform: translateX(-50%) translateY(-100%);
  display: flex;
  align-items: center;
  background: var(--bg-card);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 0 4px;
  gap: 2px;
  z-index: var(--z-toast);
  box-shadow: var(--shadow-2);
  white-space: nowrap;
  pointer-events: auto;
  /* prevent toolbar from clipping off-screen */
  max-width: calc(100vw - 32px);
}

.sel-bar button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
  border-radius: var(--r-pill);
  transition: background 0.12s;
  -webkit-tap-highlight-color: transparent;
}

.sel-bar button:active { background: var(--surface); }
.sel-bar button:hover  { background: var(--bg-2); }

/* Highlight note preview/edit popup reuses sel-bar look, but grows into a
   column card instead of staying a single pill row -- it needs room for the
   note preview text (or a textarea when editing inline). See devlogs/
   DEVLOG-2026-08.md [UX] highlight notes: tapping a highlight with a saved
   note shows it immediately here instead of requiring a trip through the
   full NoteSheet modal just to re-read it. */
.hl-note-popup {
  left: var(--hl-x, 50%);
  top: var(--hl-y, 0);
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 0;
  width: max-content;
  min-width: 200px;
  max-width: min(320px, calc(100vw - 32px));
  border-radius: var(--r-lg);
}

.hl-note-popup__preview {
  padding: 10px 14px 4px;
  font-size: var(--font-compact);
  color: var(--ink-soft);
  line-height: 1.4;
  white-space: pre-wrap;
  word-break: break-word;
}

.hl-note-popup__actions {
  display: flex;
  align-items: center;
}

.hl-note-popup__edit {
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.hl-note-popup__input {
  width: 100%;
  min-height: 64px;
  resize: none;
}

.hl-note-popup__edit .hl-note-popup__actions {
  justify-content: flex-end;
  gap: 6px;
}

.sel-bar .hl-delete-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  width: auto;
  padding: 8px 14px;
  font-size: var(--font-compact);
  font-weight: 400;
  color: var(--danger);
}
.sel-bar .hl-delete-btn:hover  { background: color-mix(in srgb, var(--danger) 15%, transparent); }
.sel-bar .hl-delete-btn:active { background: color-mix(in srgb, var(--danger) 25%, transparent); }

.sel-bar .hl-note-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  width: auto;
  padding: 8px 14px;
  font-size: var(--font-compact);
  font-weight: 400;
  color: var(--ink);
}

.sel-divider {
  width: 1px;
  height: 20px;
  background: var(--line);
  flex-shrink: 0;
}

/* ── Resume banner ───────────────────────────────────────────── */

.resume-banner {
  position: fixed;
  bottom: 72px; /* above bottom nav */
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--r-pill);
  padding: 10px 14px;
  font-size: var(--font-sm);
  box-shadow: none;
  z-index: var(--z-toast, 900);
  max-width: calc(100vw - 32px);
  animation: resume-in 0.25s var(--ease-snap, ease) both;
}
@keyframes resume-in {
  from { opacity: 0; transform: translateX(-50%) translateY(12px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.resume-banner__msg {
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.88;
}
.resume-banner__btn {
  flex-shrink: 0;
  background: rgba(255,255,255,0.15);
  color: inherit;
  border: none;
  border-radius: var(--r-lg);
  padding: 5px 12px;
  font-size: var(--font-xs);
  font-weight: 600;
  cursor: pointer;
}
.resume-banner__btn--yes {
  background: var(--accent);
  color: #fff;
}
.resume-banner__btn:hover { opacity: 0.85; }

/* ── Saved highlight marks ──────────────────────────────────── */

.reader-mark {
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background 0.15s;
}

/* Only two colors are ever actually assigned: ArticleReader hardcodes
   "navy", ThreadReader (and the addHighlight default) hardcodes/falls back
   to "yellow" -- there is no color-picker UI, so this list must always
   match exactly what the two creation paths can produce (see DEVLOG
   [Cleaning P10]). */
.reader-mark[data-color="yellow"] { background: rgba(255, 214, 10, 0.38); }
.reader-mark[data-color="navy"]   { background: rgba(26, 42, 122, 0.20); }

.reader-mark:hover { filter: brightness(0.88); }

/* ── Image lightbox overlay ─────────────────────────────────── */

.img-lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  background: rgba(0, 0, 0, 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  cursor: zoom-out;
  animation: sheet-fade-in 0.18s var(--ease);
}

.img-lightbox-img {
  max-width: 100%;
  max-height: 90dvh;
  object-fit: contain;
  border-radius: var(--r-md);
  cursor: default;
  box-shadow: none;
}

.img-lightbox-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(255,255,255,0.15);
  color: #fff;
  font-size: var(--font-md);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s;
}

.img-lightbox-close:hover { background: rgba(255,255,255,0.28); }

.tweet-gallery {
  display: grid;
  gap: 8px;
  margin-top: 8px;
}

.tweet-gallery-1 { grid-template-columns: 1fr; }
.tweet-gallery-2,
.tweet-gallery-3,
.tweet-gallery-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.tweet-gallery-cell {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--surface);
}

.tweet-gallery-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── Column view: images shown full-height, no crop ──────────────────────── */
.thread-view-column .tweet-gallery-2,
.thread-view-column .tweet-gallery-3,
.thread-view-column .tweet-gallery-4 {
  grid-template-columns: 1fr;
}
.thread-view-column .tweet-gallery-cell {
  aspect-ratio: unset;
  overflow: visible;
  background: none;
}
.thread-view-column .tweet-gallery-cell img {
  height: auto;
  object-fit: contain;
  border-radius: var(--r-lg);
}

.reader-head-page {
  color: var(--ink-soft);
  margin-left: 6px;
}

/* .reader-menu* removed — use shared .dropdown / .dropdown__item (4-overlays.css) */

.reader-author-block {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 24px 0 8px;
}

.reader-author-name {
  font-weight: 600;
  font-size: var(--font-sm);
}

.reader-author-source {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: 4px;
}

.reader-author-bio {
  font-size: var(--font-sm);
  color: var(--ink-soft);
  line-height: 1.55;
  margin: 0 0 16px;
}

.tweet-gif-inline {
  cursor: pointer;
  display: block;
  width: 100%;
  border-radius: var(--r-lg);
  margin-top: 8px;
}

.tweet-gap {
  height: 0.5em;
}

/* ── Segmented control (reader-settings / aux-panel) ──────── */

/* Shared segmented controls live in 1-primitives.css. */

/* ── Adult badge ──────────────────────────────────────────── */

/* Shared adult badge lives in 1-primitives.css. */

/* ── Similar books list ───────────────────────────────────── */

.similar-item {
  list-style: none;
}

/* ── Preview mode ─────────────────────────────────────────── */

.reader-text--preview {
  opacity: 0.55;
  pointer-events: none;
  user-select: none;
  border-left: 3px solid var(--line);
  padding-left: 12px;
}


/* ── Inline hyperlinks ────────────────────────────────────── */

.reader-link {
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: 2px;
  /* keep-all (not break-all) so a URL doesn't fracture character-by-
     character now that the surrounding .reader-para default is break-all
     (was the reverse before: this override existed to let a long URL
     break at all against a keep-all parent). overflow-wrap still forces a
     break as a last resort if the URL alone is wider than the container. */
  word-break: keep-all;
  overflow-wrap: break-word;
  transition: opacity 0.12s;
}
.reader-link:hover  { opacity: 0.72; }
.reader-link:active { opacity: 0.45; }
.reader-link--yt { color: #c00; }
.reader-link--soundcloud { color: #f26a21; }

.reader-inline-color--muted,
.reader-inline-color--gray {
  color: var(--muted);
}

/* ── YouTube thumbnail card ───────────────────────────────── */

.yt-card {
  display: block;
  margin: 0.75em 0;
}

.yt-card iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  display: block;
  border: 0;
}

.soundcloud-card {
  display: block;
  margin: 0.75em 0;
}

.soundcloud-card iframe {
  width: 100%;
  height: 166px;
  display: block;
  border: 0;
}

/* ── Article header: Postype-style layout ─────────────────── */

.read-status-row {
  margin: 20px 0 6px;
}
.read-status-tag {
  display: inline-flex;
  align-items: center;
  height: 20px;
  font-size: var(--font-xs);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-soft);
  background: var(--surface);
  border-radius: var(--r-pill);
  padding: 0 8px;
}
.read-subtitle {
  font-size: 1rem;
  font-weight: 400;
  color: var(--ink-soft);
  margin: 2px 0 14px;
  letter-spacing: 0.01em;
}
.reader-author-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.reader-author-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--font-xs);
  color: var(--ink-soft);
  flex-wrap: wrap;
}
.reader-meta-sep {
  color: var(--ink-faint);
  font-size: 0.65rem;
}
.read-divider {
  border: none;
  border-top: 1px solid var(--line);
  margin: 16px 0 12px;
}

/* ── Chapter char count (next to chapter title in ToC) ──── */
.reader-char-count {
  font-size: var(--font-xs);
  color: var(--ink-faint);
}

/* ── TTS voice selector ───────────────────────────────────── */
.tts-voice-select {
  flex: 1;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-card);
  color: var(--ink);
  font: inherit;
  font-size: var(--font-sm);
  outline: none;
  cursor: pointer;
  min-width: 0;
}

/* ── Error states ─────────────────────────────────────────── */
.thread-media {
  width: 100%;
  border-radius: var(--r-md);
  display: block;
}

.thread-broken,
.tweet-video-err {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  font-size: var(--font-sm);
  color: var(--ink-faint);
  background: var(--surface);
  border-radius: var(--r-md);
}

/* ── Reader image: desktop vs mobile sizing ─────────────────────────────── */

/* Desktop: add side breathing room so images don't fill the full column */
@media (min-width: 768px) {
  .reader-img-box {
    margin-top: 8px;
    margin-bottom: 8px;
    padding-left: 24px;
    padding-right: 24px;
  }
  /* strip/visual mode images stay edge-to-edge */
  .reader-image--strip,
  .reader-text--strip .reader-img-box {
    padding-left: 0;
    padding-right: 0;
  }
}

/* ── Font category variants (per-paragraph, from Postype ql-font-* classes) */
/* Priority: user global font setting > per-paragraph font_category > default */

.reader-para--font-serif {
  font-family: Georgia, "Noto Serif KR", "KoPub Batang", Batang, serif;
}
.reader-para--font-sans-serif {
  font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, "Noto Sans KR", "Apple SD Gothic Neo", sans-serif;
}
.reader-para--font-monospace {
  font-family: "JetBrains Mono", "Fira Code", "D2Coding", Consolas, monospace;
  font-size: 0.92em;
}
.reader-para--font-display {
  font-family: Georgia, "Noto Serif KR", "KoPub Batang", Batang, serif;
  font-weight: 600;
  letter-spacing: 0;
}

/* Mobile: images break out of col padding and fill screen width */
@media (max-width: 767px) {
  .reader-img-box {
    margin-top: 4px;
    margin-bottom: 4px;
    margin-left: calc(-1 * var(--pad-lg));
    margin-right: calc(-1 * var(--pad-lg));
    padding: 0;
  }
  .reader-img-box .reader-image {
    width: 100%;
    max-width: 100%;
    border-radius: 0;
  }
  /* strip mode already handles its own edge-to-edge layout */
  .reader-text--strip .reader-img-box {
    margin-left: 0;
    margin-right: 0;
  }
}


/* ============================================================
   Layer 4: Overlays, sheets, toasts, audio bar
   ============================================================ */

/* ── Sheet backdrop ─────────────────────────────────────── */

.sheet {
  position: fixed;
  inset: 0;
  background: var(--ov-backdrop);
  z-index: var(--z-sheet);
  display: flex;
  align-items: flex-end;
  animation: sheet-fade-in 0.2s var(--ease);
}

@keyframes sheet-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* The card that slides up */
.sheet-card {
  width: 100%;
  background: color-mix(in srgb, var(--bg-card) 96%, transparent);
  border-radius: var(--ov-radius) var(--ov-radius) 0 0;
  border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
  max-height: 92dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: sheet-slide-up 0.26s var(--ease);
  overflow-y: auto;
}

@keyframes sheet-slide-up {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

.sheet-card--settings { max-height: 88dvh; }
.sheet-card--confirm  { max-height: 52dvh; }

/* Drag handle */
.sheet-grip {
  width: 36px;
  height: 4px;
  background: var(--line-2);
  border-radius: var(--r-sm);
  margin: 14px auto 0;
  flex-shrink: 0;
}

/* Header row */
.sheet-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px 20px 10px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--line-2);
}

.sheet-title {
  font-size: var(--font-md);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink);
  line-height: 1.3;
}

.sheet-sub {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  margin-top: 2px;
}

/* Scrollable body */
.sheet-card .reader-settings,
.sheet-card .tts-settings,
.sheet-card .corrections-section,
.sheet-card .danger-zone,
.sheet-card .similar-section,
.sheet-card .sheet-toc,
.sheet-card .sheet-recent {
  flex-shrink: 0;
}

.confirm-sheet {
  align-items: flex-end;
}

.confirm-sheet__body {
  padding: 18px 20px 8px;
}

.confirm-sheet__eyebrow {
  color: var(--danger);
  font-size: var(--font-xs);
  font-weight: 600;
  margin-bottom: 8px;
}

.confirm-sheet__message {
  color: var(--ink);
  font-size: var(--font-md);
  font-weight: 600;
  line-height: 1.45;
}

.confirm-sheet__detail {
  margin-top: 8px;
  color: var(--ink-soft);
  font-size: var(--font-sm);
  line-height: 1.55;
}

.confirm-sheet__actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 12px 20px max(18px, env(safe-area-inset-bottom));
}


/* ── Reader/TTS settings containers (sheet-internal) ────── */

.tts-settings {
  padding: 4px 20px 8px;
}

.tts-status-hint {
  font-size: var(--font-xs);
  color: var(--ink-faint);
}

/* ── TOC sheet ───────────────────────────────────────────── */

.sheet-recent {
  padding: 8px 16px;
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sheet-recent-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 8px;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  color: var(--ink-soft);
  text-align: left;
  width: 100%;
}

.sheet-recent-row:hover { background: var(--bg-2); }
.sheet-recent-title { font-weight: 600; color: var(--ink); }
.sheet-recent-preview { display: block; font-size: var(--font-2xs); color: var(--ink-faint); margin-top: 1px; }

.sheet-toc {
  padding: 8px 16px 32px;
  list-style: none;
  overflow-y: auto;
}

.toc-item-row {
  display: flex;
  align-items: center;
  gap: 4px;
}

.sheet-row {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  color: var(--ink-soft);
}

.sheet-row:hover { color: var(--ink); }
.sheet-row.is-cur { color: var(--ink); font-weight: 600; background: var(--surface); }
.sheet-row.is-read { color: var(--ink-soft); }

.chapter-num {
  color: var(--ink-faint);
  font-size: var(--font-xs);
  width: 22px;
  flex-shrink: 0;
}

.chapter-label {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chapter-read {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-faint);
  margin-left: auto;
  flex-shrink: 0;
}

.toc-del-btn {
  width: 36px;
  height: 36px;
  border-radius: var(--r-md);
  color: var(--ink-faint);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

.toc-del-btn:hover { background: var(--danger); color: var(--on-accent); }

/* ── Text corrections section ────────────────────────────── */

.corrections-section {
  padding: 12px 20px;
  border-top: 1px solid var(--line);
}

.corrections-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.corrections-title {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  display: flex;
  align-items: center;
  gap: 6px;
}

.corrections-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: var(--ink-faint);
  color: var(--on-accent);
  border-radius: var(--r-pill);
  font-size: var(--font-2xs);
  font-weight: 700;
}

.corrections-hint {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
}

.corrections-empty {
  font-size: var(--font-sm);
  color: var(--ink-faint);
  padding: 6px 0;
}

.corrections-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  list-style: none;
}

.correction-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 10px;
  background: var(--bg-2);
  border-radius: var(--r-md);
}

.correction-texts {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: var(--font-xs);
  min-width: 0;
}

.correction-original {
  color: var(--ink-soft);
  text-decoration: line-through;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.correction-arrow { color: var(--ink-faint); flex-shrink: 0; }

.correction-fixed {
  color: var(--ink);
  font-weight: 600;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.correction-ch {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

.correction-del {
  width: 36px;
  height: 36px;
  border-radius: var(--r-md);
  font-size: var(--font-md);
  color: var(--ink-faint);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  line-height: 1;
}

.correction-del:hover { background: var(--danger); color: var(--on-accent); }

/* ── Fix-text sheet (reuses .sheet/.sheet-card shell) ────────────────── */

.fix-sheet__original {
  margin: 4px 20px 12px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  background: var(--bg-2);
  color: var(--ink-soft);
  font-size: var(--font-sm);
  text-decoration: line-through;
}

.fix-sheet__input {
  display: block;
  width: calc(100% - 40px);
  margin: 0 20px 14px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  resize: vertical;
}

.fix-sheet__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 0 20px 20px;
}

/* ── Danger zone ─────────────────────────────────────────── */

.danger-zone {
  padding: 12px 20px 16px;
  border-top: 1px solid var(--line);
}

.danger-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--danger);
  border-radius: var(--r-md);
  color: var(--danger);
  font-size: var(--font-sm);
  font-weight: 600;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.danger-btn:hover { background: var(--danger); color: var(--on-accent); }

/* ── Similar books section ───────────────────────────────── */

.similar-section {
  padding: 12px 20px 20px;
  border-top: 1px solid var(--line);
}

.similar-list { list-style: none; display: flex; flex-direction: column; gap: 2px; }

.similar-btn {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 9px 10px;
  border-radius: var(--r-md);
  text-align: left;
  transition: background var(--dur) var(--ease);
}

.similar-btn:hover { background: var(--bg-2); }
.similar-title { font-size: var(--font-sm); font-weight: 600; color: var(--reader-ink, var(--ink)); }
.similar-meta  { font-size: var(--font-xs); color: var(--reader-ink-soft, var(--ink-soft)); }
.similar-tags  { font-size: var(--font-2xs); color: var(--ink-faint); }

/* ── Simple text toast ───────────────────────────────────── */

.toast {
  position: fixed;
  bottom: calc(var(--nav-h) + 16px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--bg);
  font-size: var(--font-sm);
  font-weight: 400;
  padding: 10px 18px;
  border-radius: var(--r-pill);
  white-space: nowrap;
  z-index: 900;
  pointer-events: none;
  animation: toast-in 0.2s var(--ease);
}

@keyframes toast-in {
  from { opacity: 0; transform: translateX(-50%) translateY(8px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* ── SyncToast — progress & success notification ─────────── */

.sync-toast {
  position: fixed;
  bottom: calc(var(--nav-h) + 16px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 220px;
  max-width: calc(100vw - 32px);
  box-sizing: border-box;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 12px 14px 10px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  z-index: 910;
  animation: sync-toast-in 0.22s var(--ease);
  overflow: hidden;
}

.sync-toast--dismissible {
  cursor: pointer;
}

@keyframes sync-toast-in {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

.sync-toast__icon {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  margin-top: 1px;
}

.sync-toast--success .sync-toast__icon {
  background: var(--ok);
  color: var(--on-accent);
}

.sync-toast--progress .sync-toast__icon {
  background: var(--surface);
}

.sync-toast--error .sync-toast__icon {
  background: var(--danger);
  color: var(--on-accent);
  font-size: var(--font-xs);
  font-weight: 700;
}

.sync-toast__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sync-toast__label {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0;
}

.sync-toast__sub {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  font-weight: 400;
}

/* Progress bar inside toast */
.sync-toast__bar {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--line);
  border-radius: 0 0 12px 12px;
  overflow: hidden;
}

.sync-toast__fill {
  display: block;
  height: 100%;
  width: 100%;
  border: none;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
}

.sync-toast__fill::-webkit-progress-bar {
  background: transparent;
}

.sync-toast__fill::-webkit-progress-value {
  max-width: 100%;
  background: var(--accent);
  border-radius: 0 0 12px 12px;
  transition: width 0.4s var(--ease);
}

.sync-toast__fill::-moz-progress-bar {
  background: var(--accent);
  border-radius: 0 0 12px 12px;
}

/* ── Long operation chip ──────────────────────────────────── */

.longop-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 10px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink);
  max-width: 260px;
  pointer-events: none;
}

.longop-chip-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  flex-shrink: 0;
  animation: spin 0.7s linear infinite;
}

.longop-chip-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.longop-chip-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink);
}

.longop-chip-bar {
  height: 3px;
  background: var(--surface);
  border-radius: var(--r-sm);
  overflow: hidden;
}

.longop-chip-bar-fill {
  display: block;
  height: 100%;
  width: 100%;
  border: none;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
}

.longop-chip-bar-fill::-webkit-progress-bar {
  background: transparent;
}

.longop-chip-bar-fill::-webkit-progress-value {
  background: var(--accent);
  border-radius: var(--r-sm);
  transition: width 0.3s var(--ease);
}

.longop-chip-bar-fill::-moz-progress-bar {
  background: var(--accent);
  border-radius: var(--r-sm);
}

.longop-chip-pct {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  flex-shrink: 0;
}

.longop-chip-more {
  font-size: var(--font-2xs);
  font-weight: 700;
  color: var(--ink-faint);
  flex-shrink: 0;
}

/* Desktop: keep centered, adjust bottom offset (no nav-h) */
@media (min-width: 768px) {
  .sync-toast {
    bottom: 28px;
    left: 50%;
    transform: translateX(-50%);
  }
  .toast {
    bottom: 28px;
    left: 50%;
    transform: translateX(-50%);
  }
}

/* Spinner */
.sync-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid var(--line-2);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ── Audio mini-player bar ───────────────────────────────── */

.audio-bar {
  position: fixed;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  width: min(calc(100vw - 32px), 480px);
  z-index: 35;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--reader-chrome-radius);
  background: var(--reader-chrome-bg);
  border: 1px solid var(--reader-chrome-line);
  box-shadow: var(--product-shadow);
}

[data-theme="dark"] .audio-bar {
  background: var(--bg-card);
  border-color: var(--line);
  box-shadow: var(--product-shadow);
}

.audio-bar__play {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  transition: opacity 0.15s;
}

.audio-bar__play:disabled { opacity: 0.5; }

.audio-bar__info {
  flex: 1;
  min-width: 0;
}

.audio-bar__title {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.audio-bar__tts-tag {
  font-weight: 400;
  color: var(--ink-faint);
}

.audio-bar__sub {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}

.audio-bar__rate {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.audio-bar__rate-btn {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--ink-soft);
  background: var(--surface);
  transition: background 0.12s;
}

[data-theme="dark"] .audio-bar__rate-btn {
  background: var(--line);
  color: var(--ink);
}

.audio-bar__rate-btn:hover { background: var(--bg-2); }

.audio-bar__rate-val {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink);
  min-width: 34px;
  text-align: center;
}

/* ── Reader settings sheet ──────────────────────────────── */

.reader-settings {
  padding: 0 var(--pad);
}

/* section-lbl inside reader-settings includes a divider */
.reader-settings .section-lbl,
.tts-settings .section-lbl {
  padding: 16px 0 8px;
  border-top: 1px solid var(--line);
}

/* Segmented control */

/* Voice select */
/* ── Select / delete bar ─────────────────────────────────── */

.select-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px var(--pad);
  background: var(--bg-2);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}

.select-bar__count {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  flex: 1;
}

/* ── is-on state for icon buttons ───────────────────────── */

.icon-btn.is-on {
  color: var(--ink);
  background: var(--surface);
}

.icon-btn.is-on--heart {
  color: var(--heart);
}

/* ── Trash sheet ─────────────────────────────────────────── */

.sheet-card--trash   { max-height: 72dvh; }

.sheet-close-btn {
  background: none;
  border: none;
  padding: 4px 8px;
  font-size: var(--font-md);
  color: var(--ink-faint);
  cursor: pointer;
  border-radius: var(--r-md);
  line-height: 1;
}
.sheet-close-btn:hover { color: var(--ink); background: var(--surface); }

.trash-sheet-empty {
  padding: 32px 20px;
  color: var(--ink-faint);
  font-size: var(--font-sm);
  text-align: center;
}

.trash-sheet-list {
  flex: 1;
  overflow-y: auto;
}

.trash-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 20px;
  border-bottom: 1px solid var(--line);
}

.trash-item__info {
  flex: 1;
  min-width: 0;
}

.trash-item__name {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.trash-item__meta {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  margin-top: 3px;
}

.trash-item__restore {
  flex-shrink: 0;
  padding: 5px 13px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-base);
  background: none;
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.trash-item__restore:hover:not(:disabled) {
  background: var(--accent-bg);
  color: var(--accent);
  border-color: var(--accent);
}
.trash-item__restore:disabled { opacity: 0.45; cursor: not-allowed; }

.trash-sheet-footer {
  padding: 10px 20px 14px;
  border-top: 1px solid var(--line);
  flex-shrink: 0;
}

.trash-sheet-purge {
  width: 100%;
  padding: 10px;
  border: none;
  background: none;
  color: var(--danger);
  font-size: var(--font-sm);
  font-weight: 400;
  font-family: inherit;
  cursor: pointer;
  border-radius: var(--r-lg);
  transition: background 0.15s;
}
.trash-sheet-purge:hover { background: color-mix(in srgb, var(--danger) 7%, transparent); }

.trash-purge-confirm {
  display: flex;
  align-items: center;
  gap: 8px;
}

.trash-purge-confirm__text {
  flex: 1;
  font-size: var(--font-sm);
  color: var(--ink-soft);
}

.trash-purge-confirm__yes {
  padding: 6px 14px;
  background: var(--danger);
  color: var(--on-accent);
  border: none;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
}
.trash-purge-confirm__yes:disabled { opacity: 0.5; cursor: not-allowed; }

.trash-purge-confirm__no {
  padding: 6px 12px;
  background: var(--surface);
  color: var(--ink-soft);
  border: none;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  font-family: inherit;
  cursor: pointer;
}
.trash-purge-confirm__no:hover { background: var(--line); }

/* ── Merge suggestions badge ─────────────────────────────── */

/* ── Merge suggestions sheet ─────────────────────────────── */

/* Merge suggestions panel sizing */
.merge-sheet {
  max-height: 80vh;
}

.merge-sheet-head-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.merge-sheet-close {
  background: none;
  border: none;
  font-size: 16px;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 4px 6px;
}

.merge-sheet-body {
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.merge-sheet-empty {
  color: var(--ink-soft);
  font-size: var(--font-sm);
  text-align: center;
  padding: 24px 0;
}

.merge-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.merge-card-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.merge-card-series {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
}

.merge-card-author {
  font-size: var(--font-2xs);
  color: var(--ink-soft);
}

.merge-card-titles {
  margin: 0;
  padding: 0 0 0 14px;
  list-style: disc;
  font-size: var(--font-xs);
  color: var(--ink-soft);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.merge-card-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.merge-btn {
  padding: 6px 14px;
  border-radius: var(--r-md);
  border: none;
  font-size: var(--font-sm);
  font-family: inherit;
  font-weight: 600;
  cursor: pointer;
}
.merge-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.merge-btn-accept {
  background: var(--accent);
  color: var(--on-accent);
}
.merge-btn-accept:hover:not(:disabled) { opacity: 0.85; }

.merge-btn-ignore {
  background: var(--surface);
  color: var(--ink-soft);
  border: 1px solid var(--line);
}
.merge-btn-ignore:hover:not(:disabled) { background: var(--line); }

/* ── Dropdown popover (shared) ───────────────────────────── */
/* Notion-style: r-lg container, r-sm items, surface hover, weight 400 */

.dropdown-wrap {
  position: relative;
  flex: 0 0 auto;
}

.dropdown {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 70;
  min-width: 152px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  box-shadow: var(--shadow-2);
}

.dropdown__item {
  width: 100%;
  min-height: 32px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 8px;
  border-radius: var(--r-sm);
  color: var(--ink);
  font-size: var(--font-sm);
  font-weight: 400;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  background: none;
  border: none;
  font-family: inherit;
}

.dropdown__item:hover,
.dropdown__item:active {
  background: var(--surface);
}

.dropdown__item svg {
  flex: 0 0 auto;
  color: var(--ink-soft);
}


.dropdown__item.is-on {
  color: var(--ink);
  font-weight: 600;
  background: var(--surface);
}

/* For items with trailing icon (e.g. checkmark) — text left, icon right */
.dropdown__item--check {
  justify-content: space-between;
}

.dropdown__item--danger {
  color: var(--danger);
}
.dropdown__item--danger svg {
  color: var(--danger);
}
.dropdown__item--danger:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}


/* ============================================================
   Layer 5: Screens — Detail, Author, Notes, Search, Add, Settings, Series

   OWNS:   CSS for all secondary screens listed above
   DO NOT: define shared primitives (→ 1-primitives.css)
           define reader-specific CSS (→ 3-reader.css)
           define overlay/sheet CSS (→ 4-overlays.css)
           define library-list CSS (→ 2-library.css)
   ============================================================ */

/* ── Screen shells ────────────────────────────────────────── */

.search-screen,
.add-screen,
.notes-screen,
.settings-screen {
  display: flex;
  flex-direction: column;
  background: var(--bg);
}


/* ── Shared: muted micro text ────────────────────────────── */

.muted-tiny {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}

/* ── Shared: chip rows ───────────────────────────────────── */

.chip-row {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}

.chip-row::-webkit-scrollbar { display: none; }

.chip-row--wrap {
  flex-wrap: wrap;
  overflow-x: visible;
}

.recent-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 36px;
  padding: 0 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--bg);
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.recent-chip:hover, .recent-chip:active {
  background: var(--surface);
  color: var(--ink);
}

/* Recent-search list -- one search term per line (see design/screens/panels/
   index.tsx's Recent section) instead of a horizontal scrolling chip row.
   .recent-chip is reused as the row itself rather than a pill: this rule
   overrides its pill-specific properties (border/bg/fixed-height/nowrap) so
   each becomes a full-width, left-aligned list row. */
.recent-list {
  display: flex;
  flex-direction: column;
}

.recent-list .recent-chip {
  display: flex;
  width: 100%;
  height: auto;
  padding: 10px 4px;
  border: none;
  border-radius: 0;
  background: transparent;
  white-space: normal;
  justify-content: flex-start;
  border-bottom: 1px solid var(--line-2);
}

.recent-list .recent-chip:last-child { border-bottom: none; }
.recent-list .recent-chip:hover, .recent-list .recent-chip:active {
  background: var(--surface);
}

/* tag-chip: shared filter/tab chip — matches lib-kind-pill style (monochrome active) */
.tag-chip {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 12px;
  border-radius: var(--r-base);
  border: none;
  background: color-mix(in srgb, var(--surface) 88%, var(--bg));
  font-size: var(--font-xs);
  font-weight: 400;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.tag-chip:hover { background: color-mix(in srgb, var(--ink) 7%, var(--surface)); color: var(--ink); }
.tag-chip.is-active, .tag-chip.is-on {
  background: var(--ink);
  color: var(--bg);
  font-weight: 600;
}

/* ── Shared: empty state ─────────────────────────────────── */

.empty-note {
  font-size: var(--font-sm);
  color: var(--ink-faint);
  padding: 32px 0;
  text-align: center;
}

/* ── Shared: util card (white card with rows) ────────────── */

.util-section {
  margin-bottom: 8px;
}

.util-card {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-card);
}

/* Settings-style row inside util-card */
.util-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line-2);
}

.util-row:last-child { border-bottom: none; }

.util-row-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  flex-shrink: 0;
}

.util-row-head svg { color: var(--ink-soft); }

/* Action row inside util-card */
.util-action {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  text-align: left;
  color: var(--ink);
  border-bottom: 1px solid var(--line-2);
  transition: background var(--dur) var(--ease);
}

.util-action:last-child { border-bottom: none; }
.util-action:hover:not(:disabled) { background: var(--bg-2); }
.util-action:disabled { opacity: 0.45; }

.util-action-body  { flex: 1; min-width: 0; }
.util-action-title { font-size: var(--font-sm); font-weight: 600; color: var(--ink); }
.util-action-sub   { font-size: var(--font-xs); color: var(--ink-faint); margin-top: 2px; }
.util-action-emoji { font-size: var(--font-icon); line-height: 1; flex-shrink: 0; }

/* ── Login gate ──────────────────────────────────────────── */

.login-center {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.login-form {
  width: 100%;
  max-width: 320px;
  padding: 2rem 1.5rem;
}

.login-title {
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
}

.login-subtitle {
  font-size: 0.9rem;
  color: var(--ink-faint);
  margin-bottom: 1.5rem;
}

.login-input {
  width: 100%;
  padding: 0.75rem 1rem;
  font-size: 1rem;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--ink);
  box-sizing: border-box;
}

.login-error {
  color: var(--danger);
  font-size: 0.85rem;
  margin-top: 0.5rem;
}

.login-btn {
  width: 100%;
  margin-top: 1rem;
  padding: 0.75rem;
  font-size: 1rem;
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  font-weight: 600;
  cursor: pointer;
}

.login-btn:disabled {
  cursor: wait;
  opacity: 0.7;
}

/* ============================================================
   Panels: Search, Add, BookDetail, Author, Settings, Login
   Extracted from 5-screens.css
   ============================================================ */

/* ── Search: scope filter row ─────────────────────────────── */

/* Scoped overrides of the shared .tag-chip/.chip-row classes (design/css/
   5-screens.css) -- do NOT edit those shared rules directly, other screens
   (author-tab pills, etc.) reuse them. Idle/hover/selected colors here are
   deliberately matched to `.lib-kind-pill` (design/screens/library/
   library.css, the Home screen's 전체/스레드/글/그림 content-type filter) --
   user-confirmed reference screenshot: selected is a light gray fill with
   bold ink text, NOT a solid black/white fill (an earlier pass here used
   solid --ink + white text, since corrected). This is the same "unify the
   two filter-pill implementations" fix the pre-existing Cleaning TODO for
   this pair of screens asked for. IMPORTANT: `.search-scope-row .tag-chip`
   and `.tag-chip:hover`/`.tag-chip.is-on` all tie at (0,2,0) specificity, so
   without redeclaring hover/active here too, source order alone decides --
   and since this file loads after 5-screens.css, a plain idle override
   would otherwise also cancel hover/active (happened once, see
   devlogs/DEVLOG-2026-07.md). Redeclare hover/active at higher specificity
   so they always win regardless of load order. */
.search-scope-row {
  padding: 8px 16px 0;
  flex-shrink: 0;
  justify-content: center;
}

.search-scope-row .tag-chip {
  background: transparent;
  font-weight: 500;
}

.search-scope-row .tag-chip:hover {
  background: color-mix(in srgb, var(--ink) 7%, var(--surface));
  color: var(--ink);
}

.search-scope-row .tag-chip.is-active,
.search-scope-row .tag-chip.is-on {
  background: color-mix(in srgb, var(--ink) 7%, var(--surface));
  color: var(--ink);
  font-weight: 600;
}

.search-section {
  padding: 0;
}

/* Fulltext (body scope) chapter-level results */
.search-ft-list { list-style: none; padding: 0; margin: 0; }
.search-ft-item {
  padding: 10px 0;
  border-bottom: 1px solid var(--line-2);
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.search-ft-item:last-child { border-bottom: none; }
.search-ft-item:hover { background: var(--bg-2); margin: 0 -8px; padding: 10px 8px; border-radius: var(--r-md); }
.search-ft-title { font-size: var(--font-sm); font-weight: 500; color: var(--ink); }
.search-ft-chapter { font-size: var(--font-xs); color: var(--ink-soft); margin-top: 2px; }
.search-ft-preview { font-size: var(--font-xs); color: var(--ink-faint); margin-top: 4px; line-height: 1.5; }
.search-ft-preview mark { background: color-mix(in srgb, var(--accent) 25%, transparent); color: var(--ink); border-radius: var(--r-sm); padding: 0 1px; }

/* Author list */
.author-list { display: flex; flex-direction: column; }

.author-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-2);
  text-align: left;
  transition: background var(--dur) var(--ease);
}

.author-row:last-child { border-bottom: none; }
.author-row:hover { background: var(--bg-2); margin: 0 -8px; padding: 10px 8px; border-radius: var(--r-md); }

.author-initial {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface);
  display: grid;
  place-items: center;
  font-size: var(--font-xs);
  font-weight: 700;
  color: var(--ink-soft);
  flex-shrink: 0;
}

.author-name {
  flex: 1;
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
}

/* Search result book rows */
.book-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 0;
  border-bottom: 1px solid var(--line-2);
}

.book-row-body { flex: 1; min-width: 0; }
.book-row-title {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.book-row-meta {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: var(--font-xs);
  color: var(--ink-faint);
  margin-top: 2px;
}
.book-row-meta .dot { opacity: 0.5; }
.book-row-tail {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  margin-left: auto;
}

.book-row-cover {
  width: 40px;
  height: 56px;
  border-radius: var(--r-sm);
  overflow: hidden;
  flex-shrink: 0;
  background: var(--surface);
}

.book-row-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── Search: full-page query input (lives inside PageBar's children slot,
   see design/screens/panels/index.tsx's `!compact` branch) ─────────────
   Mirrors .app-header__inline's layout (design/css/1-layout.css) since it
   replaces that same input when the user taps through to the full page. */
.search-full-input-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.search-full-input-icon {
  flex-shrink: 0;
  color: var(--ink-faint);
}

.search-full-input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: inherit;
  font-size: var(--font-md);
  color: var(--ink);
}

.search-full-input::placeholder { color: var(--ink-faint); }

/* ── Search: "더보기" -- compact-mode-only, routes to the full search
   screen (onSeeAll => go("search")) with the same query. ───────────── */
.search-see-all {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  margin-top: 6px;
  padding: 9px 0;
  border-top: 1px solid var(--line-2);
  font-size: var(--font-xs);
  color: var(--ink-soft);
  transition: color var(--dur) var(--ease);
}

.search-see-all:hover { color: var(--ink); }

/* ── Search: compact mode (docked inline under the header, see .nav-inline-
   panel in design/css/1-layout.css) ─────────────────────────────────────
   User feedback: the inline dropdown reused full-page type/control sizes
   and read as oversized/overwhelming for a header dropdown. Every rule
   below only shrinks spacing/type -- it does not hide anything already
   gated by `compact` in the TSX (that's a content decision, not styling). */
.search-screen--compact .col {
  padding: 4px var(--pad) 12px;
}

.search-screen--compact .search-scope-row {
  padding: 6px var(--pad) 0;
}

.search-screen--compact .tag-chip {
  height: 26px;
  padding: 0 10px;
  font-size: var(--font-2xs);
}

.search-screen--compact .recent-chip {
  font-size: var(--font-2xs);
}

.search-screen--compact .section-lbl--row {
  padding: 10px 0 4px;
}

.search-screen--compact .book-row {
  padding: 8px 0;
  gap: 8px;
}

.search-screen--compact .book-row-cover {
  width: 30px;
  height: 42px;
}

.search-screen--compact .book-row-title {
  font-size: var(--font-xs);
}

.search-screen--compact .book-row-meta {
  font-size: var(--font-2xs);
}

/* CTA row -- matches the mockup: no stats row, no progress bar (both
 * dropped per direct feedback, devlogs/DEVLOG-2026-08.md). A series book
 * shows 2 buttons (secondary "1화부터 읽기" + primary contextual); a
 * standalone book shows 1, full width (.det-cta--full). */
.det-cta-row {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.det-cta-secondary {
  flex: 0 0 auto;
  height: 48px;
  padding: 0 18px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  font-size: var(--font-sm);
  font-weight: 600;
  transition: background var(--dur) var(--ease);
}
.det-cta-secondary:hover { background: var(--bg-2); }

.det-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
  height: 48px;
  padding: 0 20px;
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--r-lg);
  font-size: var(--font-sm);
  font-weight: 600;
  letter-spacing: 0;
  transition: background var(--dur) var(--ease), transform 0.12s var(--ease);
}
.det-cta--full { width: 100%; }
.det-cta:hover:not(:disabled) { background: var(--ink-soft); }
.det-cta:active:not(:disabled) { transform: scale(0.97); }
.det-cta:disabled { opacity: 0.35; cursor: default; }
.det-cta .arrow { font-size: var(--font-sm); }

/* File Metadata section -- 5 fixed rows, icon+label left / value right.
 * --nodata rows (file size, version -- no backing field exists) dim to
 * 0.5 opacity and italicize their value, matching the mockup's explicit
 * "데이터 없음" convention instead of fabricating a number. */
.det-file-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}

.det-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 4px;
  border-bottom: 1px solid var(--line-2);
}
.det-meta-row:last-child { border-bottom: none; }
.det-meta-row--nodata { opacity: 0.5; }

.det-meta-row__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--font-sm);
  color: var(--ink-soft);
}
.det-meta-row__label svg { flex-shrink: 0; color: var(--ink-faint); }

.det-meta-row__value {
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--ink);
}
.det-meta-row__hint {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  font-weight: 400;
}
.det-meta-row__nodata {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  font-style: italic;
}

/* ── BookDetailScreen redesign ───────────────────────────── */
.detail-screen {
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

.det-body {
  background: var(--bg);
  display: flex;
  justify-content: center;
}

.det-body > .col {
  padding-top: 20px;
  padding-bottom: 48px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Mobile detail: large cover hero */
.det-mobile-hero {
  display: none;
}
.det-mobile-info { display: none; }

/* Hero: hidden by default; shown only on desktop via explicit media query below */
.det-hero { display: none; }

/* ── Series section — sits inside the reading column, right after File
 * Metadata; replaces the old in-file chapter TOC entirely (removed per
 * direct feedback — see devlogs/DEVLOG-2026-08.md). Absent entirely (not
 * empty) for a standalone work or a lone series member — see
 * DetSeriesSection's early-return in BookDetailScreen.tsx. Head row
 * (title/count + prev/next nav) styled below, under .det-series-head. ── */
.det-series-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
}

/* ── Other Works / Similar — bottom-pinned, full-width, tinted background,
 * replacing the old sidebar's grid/card layout (direct feedback: "그리드말
 * 고 리스트 뷰로 해"). Sibling of .det-body, not nested inside .col, so it
 * spans full width while its own inner wrapper matches .col's reading
 * width. ─────────────────────────────────────────────────────────────── */
.det-other-works {
  background: var(--bg-2);
  padding: 8px 0 40px;
}

.det-other-works__inner {
  width: 100%;
  max-width: 730px;
  margin: 0 auto;
  padding: 0 var(--pad-lg);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.det-other-works + .det-other-works {
  padding-top: 0;
}

/* ── Mobile layout ──────────────────────────────── */
@media (max-width: 899px) {
  .det-mobile-hero {
    display: block;
    width: calc(100% + var(--pad-lg) * 2);
    margin: -20px calc(-1 * var(--pad-lg)) 0;
    aspect-ratio: 3 / 4;
    max-height: 60vw;
    overflow: hidden;
    background: var(--surface);
    position: relative;
    z-index: 0;
  }

  .det-mobile-hero .book-cover {
    width: 100%;
    height: 100%;
  }

  .det-mobile-hero .book-cover img {
    object-position: top center;
  }

  /* No cover: collapse hero — placeholder takes zero space */
  .det-mobile-hero:has(.book-cover__placeholder) {
    aspect-ratio: unset;
    max-height: 0;
    height: 0;
    margin: 0;
    overflow: hidden;
  }

  .det-mobile-info {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-top: 16px;
  }

  .det-mobile-info .det-eyebrow { font-size: var(--font-xs); }
  .det-mobile-info .det-title   { font-size: 20px; line-height: 1.25; margin: 0; }
  .det-mobile-info .det-author  { margin-top: 2px; }
  .det-mobile-info .det-rating  { margin-top: 6px; }
}

/* ── Desktop layout ──────────────────────────────── */
@media (min-width: 900px) {
  .det-hero {
    display: flex;
    gap: 16px;
    align-items: flex-start;
  }
}

.det-cover {
  flex-shrink: 0;
  width: 100px;
  position: relative;
}

.det-cover > * {
  width: 100px;
  height: 140px;
  object-fit: cover;
  border-radius: var(--r-md);
  overflow: hidden;
}

.det-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 2px;
}

.det-eyebrow {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-xs);
  font-weight: 600;
  letter-spacing: 0.125px;
  color: var(--ink-faint);
  opacity: 0.82;
}


/* ── Platform text tag ── */
.platform-tag {
  font-size: 9px;
  color: var(--ink-faint);
  white-space: nowrap;
}

.platform-tag-link {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}
.platform-tag-link:hover .platform-tag {
  color: var(--ink);
}

/* ── SourceBadge — shared across library, detail, reader ── */
.src-badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--font-2xs);
  font-weight: 400;
  padding: 1px 6px;
  border-radius: var(--r-pill);
  white-space: nowrap;
  text-decoration: none;
  cursor: default;
  line-height: 1.4;
}
.src-badge--link {
  color: var(--ink-soft);
  background: var(--surface);
  cursor: pointer;
}
.src-badge--link:hover { opacity: 0.75; }
.src-badge--deleted {
  color: var(--ink-faint);
  background: var(--bg-2);
  border: 1px solid var(--line);
}
.src-badge--blocked {
  color: var(--ink-soft);
  background: var(--bg-2);
  border: 1px solid var(--line);
  cursor: pointer;
}
.src-badge--error {
  color: var(--ink-soft);
  background: var(--surface);
  cursor: pointer;
}

.det-title {
  font-size: 20px;
  font-weight: 600;
  font-family: 'Pretendard', system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Apple SD Gothic Neo", sans-serif;
  color: var(--ink);
  line-height: 1.4;
  letter-spacing: -0.125px;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.det-author {
  font-size: var(--font-sm);
  color: var(--ink-soft);
}

.det-rating {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
}

/* Favorite/Download/Edit -- moved out of the old second PageBar header into
   the hero itself (see devlogs/DEVLOG-2026-08.md, detail-page redesign
   session); "View source" was dropped entirely rather than relocated. */
.det-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}


/* heart icon: red when active */
.is-on--heart {
  color: var(--heart);
}

.favorite-button {
  position: relative;
  overflow: hidden;
}

.favorite-button__icon {
  position: relative;
  display: grid;
  place-items: center;
}

.favorite-button__outline {
  transition:
    opacity 0.18s var(--ease),
    color 0.18s var(--ease),
    transform 0.18s var(--ease);
}

.favorite-button__fill {
  position: absolute;
  inset: 0;
  color: var(--heart);
  opacity: 0;
  clip-path: inset(100% 0 0 0);
  transform: translateY(4px) scale(0.88);
  transform-origin: 50% 82%;
  transition:
    clip-path 0.28s var(--ease),
    opacity 0.24s var(--ease),
    transform 0.28s var(--ease);
}

.favorite-button.is-on .favorite-button__outline {
  opacity: 0;
}

.favorite-button.is-on .favorite-button__fill {
  opacity: 1;
  clip-path: inset(0 0 0 0);
  transform: translateY(0) scale(1);
}

.favorite-button.is-draining {
  color: var(--ink-faint);
}

.favorite-button.is-draining .favorite-button__outline {
  opacity: 1;
  transform: scale(1);
}

.favorite-button.is-draining .favorite-button__fill {
  opacity: 0;
  clip-path: inset(100% 0 0 0);
  transform: translateY(5px) scale(0.84);
  transition-duration: 0.34s;
}

@media (prefers-reduced-motion: reduce) {
  .favorite-button__outline,
  .favorite-button__fill {
    transition: none;
  }
}

/* meta section below CTA (tags, blurb, memo) */
.det-meta-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 0 24px;
  border-top: 1px solid var(--line-2);
}

/* book memo textarea */
.det-memo {
  margin-top: 2px;
}

/* Desktop: memo lives in det-info (next to cover). Mobile: memo lives in det-meta-section. */
.det-memo--inline { display: none; }

@media (min-width: 900px) {
  .det-memo--inline {
    display: block;
    margin-top: 10px;
  }
  .det-meta-section .det-memo:not(.det-memo--inline) { display: none; }
}
.det-memo__textarea {
  width: 100%;
  box-sizing: border-box;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--font-sm);
  line-height: 1.6;
  padding: 8px 10px;
  resize: none;
  outline: none;
  transition: border-color 0.15s;
}
.det-memo__textarea:focus {
  border-color: var(--accent);
  background: var(--bg);
}
.det-memo__textarea::placeholder {
  color: var(--ink-faint);
}

/* Tags — use .tag-row + .tag primitives from 1-primitives.css */

.det-blurb {
  font-size: var(--font-sm);
  color: var(--ink-soft);
  line-height: 1.6;
  margin: 0;
}

/* Shared with reader-settings.tsx's chapter-jump list (design/css/4-overlays.css) --
 * not detail-screen-specific, do not scope or remove without checking that file too. */
.chapter-chars {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
  letter-spacing: 0.01em;
}

/* Series section head -- title/count left, prev/next nav right. */
.det-series-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}
.det-series-count { font-weight: 400; color: var(--ink-faint); }

.det-series-nav { display: flex; gap: 4px; }
.det-series-nav__btn {
  display: flex;
  align-items: center;
  gap: 3px;
  height: 28px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--bg);
  font-size: var(--font-xs);
  color: var(--ink-soft);
}
.det-series-nav__btn:hover:not(:disabled) { background: var(--bg-2); }
.det-series-nav__btn:disabled { opacity: 0.35; cursor: default; }

/* ── Author screen ───────────────────────────────────────── */
.author-screen {
  display: flex;
  flex-direction: column;
}

.author-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px var(--pad-side) 12px;
  border-bottom: 1px solid var(--line);
}

.author-hero-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.author-hero-name {
  font-size: var(--font-md);
  font-weight: 600;
  color: var(--ink);
}

.author-hero-count {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  margin-top: 2px;
}

.author-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
}
.author-tabs::-webkit-scrollbar { display: none; }

.author-tab {
  flex-shrink: 0;
  padding: 10px 16px;
  font-size: var(--font-sm);
  font-weight: 400;
  color: var(--ink-soft);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  transition: color 0.12s var(--ease), border-color 0.12s var(--ease);
}

.author-tab.is-on {
  color: var(--ink);
  font-weight: 600;
  border-bottom-color: var(--ink);
}

.author-tab-count {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 1px 6px;
}

/* author name — clickable button */
.author-link {
  background: none;
  border: none;
  color: var(--ink-soft);
  font-size: inherit;
  font-family: inherit;
  cursor: pointer;
  padding: 0;
  text-decoration: none;
}
.author-link:hover { color: var(--ink); }

/* ── Add: clipboard hint + action bar ────────────────────── *
 * The actual textarea now lives in the header (.app-header__inline-input,
 * see design/css/1-layout.css); this panel only holds the clipboard
 * suggestion and the validation/submit bar below it, so both get their own
 * rounded card treatment instead of assuming a shared wrapping box. */

.add-clipboard-hint {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 14px;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-base);
  font-size: var(--font-xs);
}

.add-input-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-base);
  background: var(--bg-2);
}

.add-input-meta {
  flex: 1;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.add-meta-warn {
  font-size: var(--font-2xs);
  color: var(--danger);
  font-weight: 600;
}

.add-submit-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 7px 14px;
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: var(--r-base);
  font-size: var(--font-sm);
  font-weight: 400;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, transform 0.12s var(--ease);
  flex-shrink: 0;
  white-space: nowrap;
}
.add-submit-btn:hover:not(:disabled) { background: var(--accent-focus); }
.add-submit-btn:active:not(:disabled) { transform: scale(0.95); }
.add-submit-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.add-submit-arrow { font-size: var(--font-sm); }

/* ── Add: crawl status panel ─────────────────────────────── */

.add-status-panel {
  margin-top: 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.add-status-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  background: var(--bg-2);
  gap: 8px;
}

.add-status-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-sm);
  color: var(--ink-soft);
  font-weight: 400;
}

.add-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-faint);
  flex-shrink: 0;
}

.add-status-dot--running {
  background: var(--warn);
  animation: add-dot-pulse 1s ease-in-out infinite;
}

.add-status-dot--done {
  background: var(--ok);
}

@keyframes add-dot-pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.35; }
}

.add-status-log {
  max-height: 180px;
  overflow-y: auto;
  border-top: 1px solid var(--line);
  border-radius: 0;
  margin: 0;
}

.footer-line {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 0 8px;
  font-size: var(--font-xs);
  color: var(--ink-faint);
  border-top: 1px solid var(--line-2);
  margin-top: 16px;
}


/* ── BookEditPage — unified book-edit surface ─────────────────────────────
   Matches the confirmed Claude Design mockup (Main.dc.html):
   https://claude.ai/code/artifact/0fd46678-ee79-4760-aba7-56489e6d6124
   Not yet wired into any screen -- see devlogs/TODO.md, "Retire the
   Admin/user mode distinction..." sub-item 2. */

.bep-status {
  padding: 24px;
  color: var(--ink-faint);
  font-size: var(--font-compact);
}
.bep-status--err { color: var(--danger); }

.page-frame { display: flex; flex: 1; height: 100%; min-height: 0; background: var(--bg); }

/* ── Sidebar ── */
.toc-rail {
  width: 240px; flex-shrink: 0;
  background: var(--bg-2);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  overflow: hidden;
  transition: width .15s var(--ease-snap, ease), border-color .15s var(--ease-snap, ease);
}
.toc-rail.is-collapsed { width: 0; border-right-color: transparent; }

.toc-rail__top { padding: 12px 8px 8px 14px; display: flex; align-items: center; justify-content: space-between; }
.toc-rail__brand { font-size: var(--font-sm); font-weight: 700; letter-spacing: -0.3px; color: var(--ink); cursor: pointer; white-space: nowrap; }
.toc-rail__brand:active { opacity: .6; }

.toc-rail__divider { height: 1px; background: var(--line-2); margin: 4px 14px 6px; }

.toc-rail__book {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 8px; margin: 0 8px;
  border-radius: var(--r-md);
  font-size: var(--font-sm); font-weight: 600; color: var(--ink);
  white-space: nowrap;
}
.toc-rail__book .book-ic { color: var(--ink-faint); flex-shrink: 0; }

.toc-list { padding: 2px 10px 8px 20px; overflow-y: auto; flex: 1; }
.bep-toc-item { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: var(--r-md); font-size: var(--font-sm); color: var(--ink-soft); cursor: pointer; }
.bep-toc-item:hover { background: var(--surface); }
.bep-toc-item.is-cur { background: var(--surface); color: var(--ink); font-weight: 600; }
.bep-toc-item .n { width: 20px; flex-shrink: 0; font-size: var(--font-xs); color: var(--ink-faint); font-variant-numeric: tabular-nums; }

/* ── Editor column ── */
.editor-col { flex: 1; min-width: 0; display: flex; flex-direction: column; background: var(--bg); }
.editor-topbar { height: var(--bar-h); flex-shrink: 0; display: flex; align-items: center; gap: 8px; padding: 0 20px; border-bottom: 1px solid var(--line); }
.editor-topbar__spacer { flex: 1; }
.breadcrumb { font-size: var(--font-xs); color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.breadcrumb--link { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; padding: 4px 6px; margin: 0 -6px; border-radius: var(--r-base); }
.breadcrumb--link:hover { background: var(--bg-2); color: var(--ink-soft); }

.btn-primary {
  height: 34px; padding: 0 16px; border-radius: var(--r-md);
  background: var(--ink); color: var(--bg);
  font-size: var(--font-sm); font-weight: 600;
  transition: background .15s ease, transform .12s ease;
}
.btn-primary:hover:not(:disabled) { background: var(--ink-soft); }
.btn-primary:active:not(:disabled) { transform: scale(.97); }
.btn-primary:disabled { opacity: .45; cursor: not-allowed; }

.save-state {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 8px; border-radius: var(--r-pill);
  font-size: var(--font-xs); color: var(--ink-faint);
}
.save-state__dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; background: var(--ink-faint); }
.save-state--saving .save-state__dot { animation: bep-save-pulse 1.1s ease-in-out infinite; }
.save-state--unsaved { color: var(--warn); font-weight: 500; }
.save-state--unsaved .save-state__dot { background: var(--warn); }
@keyframes bep-save-pulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

.editor-scroll { flex: 1; overflow-y: auto; display: flex; justify-content: center; }
.editor-col-inner { width: 100%; max-width: 720px; padding: 40px 40px 80px; }

.title-input {
  width: 100%; border: none; outline: none; background: none;
  font-family: inherit; font-size: var(--font-3xl); font-weight: 700; letter-spacing: -0.6px;
  color: var(--ink);
}
.title-input::placeholder { color: var(--ink-faint); }

/* ── Properties ── */
.prop-list { margin-top: 18px; display: flex; flex-direction: column; gap: 1px; }
.prop-row { display: flex; align-items: center; min-height: 32px; border-radius: var(--r-base); }
.prop-row:hover { background: var(--bg-2); }
.prop-label { width: 88px; flex-shrink: 0; font-size: var(--font-xs); color: var(--ink-faint); }
.prop-value-input {
  flex: 1; min-width: 0; border: none; outline: none; background: none; font: inherit;
  font-size: var(--font-sm); color: var(--ink); padding: 5px 6px; border-radius: var(--r-base);
}
.prop-value-input::placeholder { color: var(--ink-faint); }

.prop-toggle {
  display: flex; align-items: center; gap: 6px;
  margin-top: 2px; padding: 6px 6px 6px 2px;
  border-radius: var(--r-base);
  font-size: var(--font-xs); color: var(--ink-faint);
}
.prop-toggle:hover { background: var(--bg-2); color: var(--ink-soft); }
.prop-toggle .chev { transition: transform .15s var(--ease-snap, ease); }
.prop-toggle .chev.is-open { transform: rotate(90deg); }

.prop-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; flex: 1; }
.bep-tag-chip {
  display: inline-flex; align-items: center; height: 24px; padding: 0 10px;
  border-radius: var(--r-pill); font-size: var(--font-xs); font-weight: 500;
  color: var(--ink-soft); background: var(--tag-bg);
}

.adult-switch { display: inline-flex; align-items: center; gap: 8px; }
.adult-switch span { font-size: var(--font-sm); color: var(--ink); }

.prop-memo {
  width: 100%; min-height: 44px; border: none; outline: none; background: none; font: inherit;
  font-size: var(--font-sm); color: var(--ink); line-height: 1.5; resize: none;
}
.prop-memo::placeholder { color: var(--ink-faint); }

.prop-divider { height: 1px; background: var(--line-2); margin: 18px 0 8px; }

/* ============================================================
   Notes screen — book-grouped redesign
   ============================================================ */

/* ── Toolbar (sort control, replaces PageBar) ───────────────── */

.notes-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 10px var(--pad) 4px;
}

/* ── Sort control ────────────────────────────────────────────── */

.notes-sort-btn {
  font-size: var(--font-sm);
  color: var(--ink-faint);
  padding: 4px 8px;
  border-radius: var(--r-base);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.notes-sort-btn:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  color: var(--ink);
}

/* notes-sort-menu / notes-sort-item removed — use shared .dropdown / .dropdown__item (4-overlays.css) */

/* ── Note list ───────────────────────────────────────────────── */

.notes-list {
  display: flex;
  flex-direction: column;
  padding: 16px 16px 48px;
  gap: 24px;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  max-width: 680px;
  width: 100%;
  margin-inline: auto;
}

/* ── Book group ──────────────────────────────────────────────── */

.note-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.note-group:first-child {
  padding-top: 0;
  border-top: none;
}

.note-group-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 4px;
  cursor: pointer;
  transition: opacity var(--dur) var(--ease);
  text-align: left;
  width: 100%;
}

.note-group-head:hover {
  opacity: 0.75;
}

.note-group-head:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.note-group-head--orphan {
  cursor: default;
  opacity: 0.5;
}

.note-group-head--orphan:hover {
  opacity: 0.5;
}

.note-group-rating {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-soft);
  flex-shrink: 0;
  white-space: nowrap;
}

.note-group-deleted {
  color: var(--danger);
  font-weight: 600;
}

/* Book-level free-text memo (core/overrides.py `memo` field) -- visually
   separated from the highlight/note list below, not a separate tab/section. */
.note-group-memo {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 4px 0 10px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--ink) 5%, var(--surface));
}

.note-group-memo__rating {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-soft);
}

.note-group-memo__text {
  font-size: var(--font-sm);
  color: var(--ink);
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: keep-all;
}

.note-group-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ── Note card ───────────────────────────────────────────────── */

.note-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  position: relative;
}

/* ── More menu ───────────────────────────────────────────────── */

.note-more {
  position: absolute;
  top: 8px;
  right: 8px;
}

.note-more-btn {
  width: 30px;
  height: 30px;
  border-radius: var(--r-sm);
  color: var(--ink-faint);
  display: grid;
  place-items: center;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.note-more-btn:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  color: var(--ink);
}

.note-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 130px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-2);
  z-index: var(--z-ctx);
  overflow: hidden;
}

.note-menu-item {
  display: block;
  width: 100%;
  padding: 10px 14px;
  text-align: left;
  font-size: var(--font-sm);
  color: var(--ink);
  transition: background var(--dur) var(--ease);
}

.note-menu-item:hover {
  background: var(--surface);
}

.note-menu-item--danger {
  color: var(--danger);
}

.note-menu-item--danger:hover {
  background: color-mix(in srgb, var(--danger) 8%, transparent);
}

/* ── Quote ───────────────────────────────────────────────────── */

.note-quote {
  margin: 14px 14px 0;
  padding-right: 32px;
  font-size: var(--font-sm);
  color: var(--ink-soft);
  line-height: 1.65;
  white-space: pre-line;
}

/* ── Image highlight ─────────────────────────────────────────── */

.note-img {
  display: block;
  width: calc(100% - 10px);
  max-width: calc(100% - 10px);
  height: auto;
  border-radius: var(--r-lg);
  margin: 10px auto 0;
  background: var(--surface);
}

/* ── Same-chapter image gallery ──────────────────────────────── */

.note-gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
  margin: 8px 5px 0;
  border-radius: var(--r-md);
  overflow: hidden;
}

/* 3 images: first cell spans full width */
.note-gallery-3 .note-gallery-cell:first-child {
  grid-column: 1 / -1;
}

.note-gallery-cell {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--surface);
}

.note-gallery-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.note-gallery-more {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: var(--font-md);
  font-weight: 600;
}

/* ── Gallery lightbox ────────────────────────────────────────── */

.note-lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay, 900);
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 56px 16px 48px;
  -webkit-tap-highlight-color: transparent;
}

.note-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--r-md);
  display: block;
}

.note-lightbox-close {
  position: fixed;
  top: 12px;
  right: 12px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  display: grid;
  place-items: center;
  transition: background var(--dur) var(--ease);
}

.note-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.24);
}

.note-lightbox-nav {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  display: grid;
  place-items: center;
  transition: background var(--dur) var(--ease);
}

.note-lightbox-nav:hover {
  background: rgba(255, 255, 255, 0.24);
}

.note-lightbox-nav--prev { left: 12px; }
.note-lightbox-nav--next { right: 12px; }

.note-lightbox-counter {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  font-size: var(--font-xs);
  color: rgba(255, 255, 255, 0.6);
  pointer-events: none;
}

/* ── Note body text ──────────────────────────────────────────── */

.note-body {
  margin: 10px 14px 0;
  font-size: var(--font-sm);
  color: var(--ink);
  line-height: 1.65;
}

.note-body--attached {
  color: var(--ink-faint);
  font-style: italic;
  font-size: var(--font-xs);
  margin-top: 6px;
}

/* ── Card footer: chapter tag + date ─────────────────────────── */

.note-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
  border-top: 1px solid var(--line-2);
}

.note-chapter-name {
  padding: 7px 12px;
  font-size: var(--font-xs);
  color: var(--ink-faint);
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 60%;
  transition: color var(--dur) var(--ease);
}

.note-chapter-name:hover {
  color: var(--ink-soft);
}

.note-date {
  padding: 7px 12px;
  font-size: var(--font-xs);
  color: var(--ink-faint);
  flex-shrink: 0;
}

/* ============================================================
   Series admin screen
   Extracted from 5-screens.css
   ============================================================ */

/* ── Series admin screen ──────────────────────────────────────────────────── */
.series-screen { display: flex; flex-direction: column; background: var(--bg); }
.series-screen--embedded { height: auto; background: transparent; }

.series-embed-head {
  display: flex;
  justify-content: flex-end;
  padding: 4px 0 12px;
}
.series-detail-embed-head {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) 30px;
  align-items: center;
  gap: 8px;
  padding: 2px 0 10px;
}
.series-detail-embed-title {
  min-width: 0;
  color: var(--ink);
  font-size: var(--font-sm);
  font-weight: 650;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.series-detail-back-icon { transform: rotate(180deg); }

.adm-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--bg);
  font-size: var(--font-xs);
  padding: 7px 16px;
  border-radius: var(--r-pill);
  z-index: 9999;
  pointer-events: none;
}

/* list */
.series-list { padding: 8px 0; }
.series-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; padding: 12px 16px; border-bottom: 1px solid var(--line-2);
  background: var(--bg);
  -webkit-tap-highlight-color: transparent;
}
.series-card__body  { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.series-card__title { font-size: var(--font-sm); font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.series-card__meta   { display: flex; align-items: center; gap: 6px; min-width: 0; color: var(--ink-faint); }
.series-card__author { min-width: 0; font-size: var(--font-xs); color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.series-card__id     { max-width: 92px; padding: 1px 6px; border-radius: var(--r-pill); background: var(--surface); font-size: var(--font-2xs); color: var(--ink-faint); font-family: var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.series-card__right  { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex-shrink: 0; color: var(--ink-faint); }
.series-card__count  { font-size: var(--font-sm); font-weight: 600; color: var(--ink-soft); }
.series-card__platform { flex-shrink: 0; font-size: var(--font-2xs); color: var(--ink-faint); }
.series-list-more {
  width: 100%;
  min-height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid var(--line-2);
  background: var(--bg);
  color: var(--accent);
  font-size: var(--font-sm);
  font-weight: 600;
}

/* info strip (detail top) */
.series-info-strip { display: flex; gap: 8px; align-items: center; padding: 8px 16px; background: var(--surface); border-bottom: 1px solid var(--line-2); flex-wrap: wrap; }
.series-info-id     { min-width: 0; font-size: var(--font-xs); color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.series-info-author { font-size: var(--font-xs); color: var(--ink-soft); }
.series-info-count  { font-size: var(--font-xs); font-weight: 600; color: var(--ink-soft); margin-left: auto; }

/* book list */
.series-book-list { }
.series-book-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-bottom: 1px solid var(--line-2);
}
.series-book-num   { width: 22px; text-align: right; font-size: var(--font-xs); color: var(--ink-faint); flex-shrink: 0; }
.series-book-info  { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.series-book-title { font-size: var(--font-sm); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.series-book-date  { font-size: var(--font-xs); color: var(--ink-faint); }
.series-book-acts  { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.series-action-bar {
  display: flex; gap: 8px; padding: 10px 14px;
  border-top: 1px solid var(--line); background: var(--bg);
  padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  position: sticky; bottom: 0; z-index: 10;
}

/* empty / status */
.series-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; padding: 40px 20px; color: var(--ink-faint); text-align: center; }
.series-status { padding: 20px; text-align: center; color: var(--ink-faint); font-size: var(--font-sm); }

/* modal */
.series-modal-overlay {
  position: fixed; inset: 0; background: var(--ov-backdrop); z-index: 200;
  display: flex; align-items: flex-end; justify-content: center;
}
.series-modal {
  width: 100%; max-width: 520px; background: var(--bg); border-radius: var(--ov-radius) var(--ov-radius) 0 0;
  padding: 20px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; gap: 14px;
  max-height: 85vh; overflow-y: auto;
}
.series-modal--tall { max-height: 90vh; }
.series-modal--confirm { border-radius: var(--r-lg); max-width: 360px; align-self: center; margin: auto 0; }
.series-modal__head { display: flex; align-items: center; justify-content: space-between; }
.series-modal__title { font-size: var(--font-md); font-weight: 600; color: var(--ink); }
.series-modal__foot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }

/* form fields */
.series-field { display: flex; flex-direction: column; gap: 5px; font-size: var(--font-xs); color: var(--ink-soft); font-weight: 600; }
.series-input {
  padding: 9px 12px; border-radius: var(--r-md); font-size: var(--font-sm);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  outline: none; width: 100%;
}
.series-input:focus { border-color: var(--accent); }
.series-select {
  padding: 9px 12px; border-radius: var(--r-md); font-size: var(--font-sm);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  outline: none; width: 100%; cursor: pointer;
}

/* add book search */
.series-search-wrap { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--r-pill); }
.series-search-wrap .series-input { border: none; background: transparent; padding: 0; font-size: var(--font-sm); }
.series-pick-list { display: flex; flex-direction: column; }
.series-pick-row {
  display: flex; align-items: center; gap: 10px; padding: 10px 4px;
  border-bottom: 1px solid var(--line-2); cursor: pointer; text-align: left;
  background: transparent; transition: background var(--dur) var(--ease);
}
.series-pick-row:hover { background: var(--surface); }
.series-pick-row--added { opacity: 0.5; cursor: default; }
.series-pick-row--selected { background: var(--surface); color: var(--ink); }
.series-pick-row--selected .series-pick-title { color: var(--ink); font-weight: 600; }
.series-pick-badge { margin-left: 8px; font-size: var(--font-xs); color: var(--ink-soft); font-weight: 700; }
.series-field--col { display: flex; flex-direction: column; gap: 5px; font-size: var(--font-xs); color: var(--ink-soft); font-weight: 600; }
.series-field--col .series-pick-list { max-height: 240px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-lg); }
.series-pick-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.series-pick-title  { font-size: var(--font-sm); color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.series-pick-author { font-size: var(--font-xs); color: var(--ink-faint); }

/* merge description */
.series-merge-desc { font-size: var(--font-sm); color: var(--ink-soft); line-height: 1.6; margin: 0; }
.series-confirm-msg { font-size: var(--font-sm); color: var(--ink); line-height: 1.6; white-space: pre-line; margin: 0; }

.series-empty-icon { opacity: 0.25; }

.series-check-icon { color: var(--accent); }

.star-rating {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.star-slot {
  width: 18px;
  height: 18px;
  display: inline-grid;
  place-items: center;
  color: var(--ink-faint);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: transform 0.1s, color 0.1s;
}
.star-slot:hover {
  color: var(--accent);
  transform: scale(1.2);
}
.star-slot:active {
  transform: scale(0.95);
}
.star-rating.is-readonly .star-slot {
  cursor: default;
  pointer-events: none;
}

.star-half-emoji {
  width: 1em;
  height: 1em;
  display: inline-grid;
  place-items: center;
  color: currentColor;
  font-family: "Segoe UI Symbol", "Noto Sans Symbols 2", "Apple Symbols", sans-serif;
  line-height: 1;
  font-size: var(--star-size, 1em);
}

.star-value {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-soft);
  margin-left: 4px;
}

/* ── Mobile (max-width: 767px) ──────────────────────────────── */
@media (max-width: 767px) {
  /* 18px is below the ~44px touch-target guideline for an interactive
     control — widen the tap area without growing the visible star. */
  .star-slot {
    width: 32px;
    height: 32px;
  }
}


/* ── Admin screen ─────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: no-preference) {

  .adm-root { animation: screen-push 280ms var(--ease-snap); }
}




.adm-root {
  display: flex;
  flex-direction: column;
  /* Management now mounts its own AppHeader (breadcrumb + tab switcher
     merged into one bar, see AdminScreen) instead of sitting under a
     separate app.tsx-owned .app-header + its own second .adm-topbar
     stacked below it -- same "owns its own fixed header, pads for it
     directly" pattern as the reader screens (reader.css). */
  height: 100dvh;
  padding-top: var(--bar-h);
  background: var(--bg);
  font-family: 'Pretendard', -apple-system, sans-serif;
  font-size: var(--font-sm);
  color: var(--ink);
}



.adm-nav {
  display: flex;
  gap: 2px;
}



.adm-nav button {
  background: none;
  border: none;
  color: var(--ink-soft);
  font-size: var(--font-compact);
  font-weight: 400;
  padding: 5px 11px;
  border-radius: var(--r-base);
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, color 0.15s;
}



.adm-nav button:hover {
  background: color-mix(in srgb, var(--ink) 7%, var(--surface));
  color: var(--ink);
}



.adm-nav button.is-active {
  background: var(--ink);
  color: var(--bg);
  font-weight: 600;
}



.adm-auto-rebuild-toggle {
  margin-left: auto;
  font-size: var(--font-xs);
  font-family: inherit;
  font-weight: 500;
  padding: 4px 10px;
  border-radius: var(--r-md);
  border: 1px solid color-mix(in srgb, var(--line) 80%, transparent);
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}


.adm-auto-rebuild-toggle.is-active {
  background: var(--surface);
  border-color: var(--line);
  color: var(--ink);
}



/* Body */
.adm-content-shell {
  flex: 1;
  min-height: 0;
  display: flex;
  overflow: hidden;
}



.adm-body {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  display: flex;
}


.adm-book-row.is-active { background: var(--surface); }



.adm-btn {
  padding: 9px 20px;
  border: none;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
  font-weight: 400;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s, transform 0.12s var(--ease);
}


.adm-btn:disabled { opacity: 0.45; cursor: not-allowed; }


.adm-btn:active:not(:disabled) { transform: scale(0.95); }


.adm-btn--sm { padding: 4px 10px; font-size: var(--font-xs); height: 28px; }



.adm-msg {
  font-size: var(--font-compact);
}


.adm-msg--ok  { color: var(--ok); }


.adm-msg--err { color: var(--danger); }


.adm-chapter-row.is-active {
  background: var(--surface);
  color: var(--ink);
}


.adm-chapter-row.is-active .adm-ch-num,
.adm-chapter-row.is-active .adm-ch-title { color: var(--ink); font-weight: 600; }



.cep__nav {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}



.cep__dirty {
  font-size: var(--font-2xs);
  color: var(--warn);
}



.cep__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-shrink: 0;
}



.cep__label {
  font-size: var(--font-2xs);
  color: var(--ink-sub);
}



.cep__toolbar {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  padding: 2px 0;
}



.cep__sep {
  width: 1px;
  height: 16px;
  background: var(--line);
  margin: 0 4px;
}



.cep__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 10px 12px;
  font-size: var(--font-sm);
  line-height: 1.8;
  outline: none;
  cursor: text;
  word-break: break-all;
}



.cep__body:focus { border-color: var(--accent); }



.cep__body p { margin: 0 0 0.8em; }


.cep__body p:last-child { margin-bottom: 0; }



.cep__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-shrink: 0;
}



.adm-op-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 10px;
}



.adm-op-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 80px;
  padding: var(--adm-card-pad);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  color: var(--ink);
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}



.adm-op-card:hover:not(:disabled) {
  border-color: var(--ink-faint);
  background: var(--surface);
}



.adm-op-card:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}



.adm-op-card-title {
  font-size: var(--font-sm);
  font-weight: 600;
}



.adm-op-card-desc {
  color: var(--ink-faint);
  font-size: var(--font-xs);
  line-height: 1.45;
}



/* ── Admin dark mode ─────────────────────────────────────────── */

[data-theme="dark"] .adm-root { background: var(--bg); color: var(--ink); }


[data-theme="dark"] .adm-book-row.is-active { background: var(--surface); }


[data-theme="dark"] .adm-msg--ok  { color: var(--ok); }


[data-theme="dark"] .adm-msg--err { color: var(--danger); }



.adm-btn--ghost:hover:not(:disabled) { background: var(--surface); }



.adm-btn--danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  border-color: var(--danger);
}


.adm-btn--danger:disabled { opacity: 0.4; }



/* ── Op grid variants ───────────────────────────────────────────────────── */

.adm-op-grid--2 {
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
}



.adm-op-card--danger {
  border-color: color-mix(in srgb, var(--danger) 38%, var(--line));
  color: var(--danger);
}


.adm-op-card--danger .adm-op-card-title { color: var(--danger); }


.adm-op-card--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 6%, var(--bg-card)); }



.adm-op-card--full {
  grid-column: 1 / -1;
  min-height: auto;
  padding: 12px 16px;
  flex-direction: row;
  align-items: center;
  gap: 10px;
}


.adm-op-card--full .adm-op-card-desc { margin-left: auto; font-size: var(--font-xs); }



.adm-modal--plan {
  width: min(760px, calc(100vw - 32px));
  max-width: 760px;
  max-height: min(780px, calc(100vh - 48px));
  display: flex;
  flex-direction: column;
}



.adm-plan-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}



.adm-plan-risk {
  flex: 0 0 auto;
  padding: 4px 8px;
  border-radius: var(--r-pill);
  font-size: var(--font-2xs);
  font-weight: 700;
  text-transform: uppercase;
  background: var(--bg-2);
  color: var(--ink-soft);
}



.adm-plan-risk--high {
  background: color-mix(in srgb, var(--danger) 12%, var(--bg-2));
  color: var(--danger);
}



.adm-plan-warnings {
  margin-top: 4px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--danger) 8%, var(--bg-2));
  color: var(--danger);
  font-size: var(--font-xs);
  line-height: 1.45;
}



.adm-plan-list {
  min-height: 0;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}



.adm-plan-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: start;
  padding: 14px;
  border-bottom: 1px solid var(--line-2);
}



.adm-plan-item:last-child { border-bottom: 0; }



.adm-plan-item__title {
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--ink);
}



.adm-plan-item__summary {
  margin-top: 3px;
  color: var(--ink-soft);
  font-size: var(--font-xs);
  line-height: 1.45;
}



.adm-plan-actions {
  margin: 8px 0 0;
  padding-left: 18px;
  color: var(--ink-soft);
  font-size: var(--font-xs);
  line-height: 1.55;
}



.adm-plan-item__warnings {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}



.adm-plan-item__warnings span {
  padding: 3px 7px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--danger) 8%, var(--bg-2));
  color: var(--danger);
  font-size: var(--font-2xs);
}



.adm-plan-empty {
  padding: 28px;
  text-align: center;
  color: var(--ink-faint);
  font-size: var(--font-compact);
}



.adm-log-line {
  font-family: 'Pretendard', -apple-system, sans-serif;
  font-size: var(--font-compact);
  color: var(--ink-soft);
  line-height: 1.6;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  overflow: hidden;
}



/* ── Tab scroll layout ──────────────────────────────────────────────────── */

/* .adm-root is a fixed-height flex column (viewport minus the shared
   header), so col-scroll scrolls internally here instead of the page. */
.adm-root .col-scroll {
  flex: 1;
  overflow-y: auto;
  outline: none;
}



/* Inner list rows: dividers only — outer adm-merge-panel provides the container box */
.adm-merge-list .adm-card,
.adm-merge-list .adm-card--subtle {
  border: none;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}



/* Card-level accept/consolidate: outline accent so "모두 묶기" stays the only solid-blue CTA */
.adm-merge-card .adm-btn--primary {
  background: transparent;
  border-color: color-mix(in srgb, var(--accent) 40%, var(--line));
  color: var(--accent);
}


.adm-merge-card .adm-btn--primary:hover:not(:disabled) {
  background: var(--accent-bg);
  border-color: var(--accent);
  filter: none;
}



.adm-stat-badge--warn {
  background: color-mix(in srgb, var(--warn) 10%, var(--surface));
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 22%, var(--line));
}



.adm-btn--ghost {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--ink-soft);
}


.op-autocomplete__option:hover,
.op-autocomplete__option.is-active { background: var(--accent-bg); }

@media (max-width: 900px) {

  .adm-content-shell {
    position: relative;
    flex-direction: column;
  }
}




/* ── Admin shared design system ────────────────────────────────────────────
   --adm-* tokens are declared in 0-reset.css :root. */

.adm-card {
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--ink) 4%, transparent);
}



.adm-card--subtle {
  background: var(--surface);
  box-shadow: none;
}



.adm-section-title,
.ops-section__title,
.platform-section__title {
  margin: 0;
  padding: 0;
  color: var(--ink-soft);
  font-size: var(--font-sm);
  font-weight: 650;
  line-height: 1.35;
  letter-spacing: -0.12px;
  text-transform: none;
}



.adm-btn,
.op-item__run,
.op-item__run-inline {
  min-height: var(--adm-control-h);
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font: 600 12px/1 'Pretendard', -apple-system, sans-serif;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .15s, border-color .15s, color .15s, opacity .15s, transform .12s;
}



.adm-btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}


.adm-btn--primary:hover:not(:disabled) { background: var(--accent-focus); }



.adm-btn--secondary {
  background: var(--surface-raised);
  border-color: var(--line);
  color: var(--ink);
}


.adm-btn--secondary:hover:not(:disabled) { background: var(--accent-bg, var(--surface)); border-color: color-mix(in srgb, var(--accent) 30%, var(--line)); }



.adm-btn--danger {
  background: transparent;
  border-color: color-mix(in srgb, var(--danger) 45%, var(--line));
  color: var(--danger);
}



.adm-icon-btn,
.op-item__toggle {
  width: var(--adm-control-h);
  height: var(--adm-control-h);
  min-width: var(--adm-control-h);
  padding: 0;
  display: inline-grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-raised);
  color: var(--ink-soft);
  font-size: var(--font-xs);
  font-weight: 600;
  font-family: inherit;
  line-height: 1;
  cursor: pointer;
}



.adm-btn:disabled,
.adm-icon-btn:disabled { opacity: .45; cursor: not-allowed; }



.adm-stat-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-soft);
  font-size: var(--font-compact);
  font-weight: 600;
  line-height: 1;
}



.adm-stat-badge::before {
  content: "";
  width: 7px;
  height: 7px;
  flex: 0 0 7px;
  border-radius: 50%;
  background: currentColor;
}


.adm-stat-badge--success { color: #2A533C; background: #CFE1D6; }


.adm-stat-badge--success::before { background: #46A171; }


.adm-stat-badge--pending { color: #30537A; background: #C1DEF5; }


.adm-stat-badge--pending::before { background: #2783DE; }


.adm-stat-badge--neutral { color: var(--ink-faint); }


.adm-stat-badge .adm-status-chip__label { color: currentColor; opacity: .8; }


.adm-stat-badge .adm-status-chip__value { color: currentColor; }



/* Shared page frame: every tab uses the same full-width canvas and gutters. */
.adm-root .col-scroll { padding: 16px 20px; }


.adm-root .col,
.adm-root .col--wide,
.adm-root .col--narrow {
  width: 100%;
  max-width: var(--adm-content-max);
  margin-inline: auto;
}


.adm-crawl-tab { gap: 20px; }



/* tabs that wrap content in .col need flex+gap on the col itself */
.adm-crawl-tab > .col,
.adm-series-tab > .col {
  display: flex;
  flex-direction: column;
  gap: 20px;
}


.ops-section__list,
.adm-op-grid { gap: 10px; }



.op-item,
.adm-primary-btn { border-color: var(--line); border-radius: var(--r-lg); }



/* .op-item--danger's base border-color/title color come from
   components/OpItem.css (loaded later in scripts/css-layers.mjs, so it wins
   at equal specificity) -- this file used to also declare them with
   non-danger values, which never took visible effect but was confusing
   dead code (found via npm run lint:css:dup, devlogs/TODO.md [Cleaning+Bug]
   2026-08-19 entry, resolved 2026-08-21). Only the hover state below is
   genuinely unique to this file. */
.op-item--danger:hover {
  border-color: color-mix(in srgb, var(--danger) 20%, var(--line));
  background: var(--surface-raised);
}

@media (max-width: 767px) {

  .adm-root .col-scroll { padding: 10px; }

  .adm-root { --adm-card-pad: 14px; }
}



/* ── Ops tab layout ─────────────────────────────────────────────────────── */

.adm-ops-tab-layout {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-bottom: 32px;
}



.ops-frequent {
  padding: var(--adm-card-pad);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}



.ops-frequent__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
}



.ops-frequent__title { color: var(--ink); }



.ops-frequent__hint {
  color: var(--ink-faint);
  font-size: var(--font-2xs);
}



.ops-frequent__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 10px;
}


.adm-crawl-form {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}



.adm-url-input {
  flex: 1;
  padding: 9px 12px;
  border-radius: var(--r-md);
  font-size: var(--font-sm);
}



/* OR divider */
.adm-import-or {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--ink-faint);
  font-size: var(--font-xs);
}


.adm-import-or::before,
.adm-import-or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line-1);
}



/* ── Primary ops grid ───────────────────────────────────────────────────── */

.adm-primary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 10px;
  flex-shrink: 0;
}



.adm-primary-btn {
  display: flex;
  flex-direction: column;
  gap: 5px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  color: var(--ink);
  text-align: left;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}


.adm-primary-btn:hover:not(:disabled) {
  background: var(--surface);
  border-color: color-mix(in srgb, var(--ink-soft) 30%, var(--line));
}


.adm-primary-btn:active:not(:disabled) { transform: scale(0.95); }


.adm-primary-btn:disabled { opacity: 0.45; cursor: not-allowed; }


.adm-primary-btn[data-kind="run"] {
  background: color-mix(in srgb, var(--accent) 7%, var(--bg-card));
  border-color: color-mix(in srgb, var(--accent) 22%, var(--line));
}


.adm-primary-btn[data-kind="run"]:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 13%, var(--bg-card));
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line));
}



.adm-primary-btn__title { font-size: var(--font-sm); font-weight: 600; line-height: 1.3; letter-spacing: -0.224px; }


.adm-primary-btn__desc  { font-size: var(--font-xs); color: var(--ink-soft); line-height: 1.4; letter-spacing: -0.12px; }



/* ── Crawl tab internals ────────────────────────────────────────────────── */

.adm-crawl-tab {
  display: flex;
  flex-direction: column;
  gap: 20px;
}



.adm-crawl-section { display: flex; flex-direction: column; }



.adm-crawl-msg {
  font-size: var(--font-compact);
  color: var(--ink-soft);
  padding: 2px 0;
}


.adm-crawl-msg--err { color: var(--danger); }

/* ── Mobile overrides ───────────────────────────────────────────────────── */

@media (max-width: 767px) {

  .adm-primary-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}



.adm-primary-btn { min-height: 72px; padding: var(--adm-card-pad); align-items: flex-start; }


/* ── Books layout ──────────────────────────────────────────────────────────── */

.adm-books-layout {
  display: flex;
  flex: 1;
  overflow: hidden;
  gap: 0;
}



/* List column */
.adm-list-col {
  display: flex;
  flex-direction: column;
  width: 100%;
  flex-shrink: 0;
  border-right: 1px solid var(--line);
  background: var(--bg-2);
  overflow: hidden;
}



.adm-books-layout.has-panel .adm-list-col {
  width: 300px;
}



.adm-search-wrap {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-2);
  flex-shrink: 0;
}



.adm-search {
  width: 100%;
  padding: 8px 12px;
  border-radius: var(--r-md);
  font-size: var(--font-compact);
  background: var(--surface);
}



.adm-book-list {
  flex: 1;
  overflow-y: auto;
}



.adm-list-loading {
  padding: 16px;
  color: var(--ink-faint);
  font-size: var(--font-compact);
}



.adm-book-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  text-align: left;
  padding: 10px 14px;
  border: none;
  border-bottom: 1px solid var(--line-2);
  background: none;
  font-family: inherit;
}



.adm-book-row-title {
  font-size: var(--font-compact);
  font-weight: 400;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 5px;
}



.adm-book-row-meta {
  font-size: var(--font-xs);
  color: var(--ink-faint);
}



.adm-ch-count { color: var(--ink-faint); }



/* Panel column */
.adm-panel-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg-card);
}



.adm-panel-placeholder {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
  font-size: var(--font-sm);
  background: var(--bg-card);
}

/* ── Mobile overrides ─────────────────────────────────────────────────────── */

@media (max-width: 767px) {

  .adm-books-layout.has-panel .adm-list-col { display: none; }

  .adm-books-layout.has-panel .adm-list-col.is-hidden-mobile { display: none; }

  .adm-panel-placeholder { display: none; }

  .adm-books-layout.has-panel .adm-panel-col { width: 100%; }
}



[data-theme="dark"] .adm-list-col { background: var(--bg-2); border-right-color: var(--line); }


[data-theme="dark"] .adm-panel-col { background: var(--bg); }


[data-theme="dark"] .adm-panel-placeholder { background: var(--bg); color: var(--ink-faint); }


[data-theme="dark"] .adm-search-wrap { border-bottom-color: var(--line); }



[data-theme="dark"] .adm-book-row { border-bottom-color: var(--line-2); }


[data-theme="dark"] .adm-book-row:hover { background: var(--bg-2); }


[data-theme="dark"] .adm-book-row-title { color: var(--ink); }


[data-theme="dark"] .adm-book-row-meta { color: var(--ink-soft); }


[data-theme="dark"] .adm-ch-count { color: var(--ink-faint); }



/* ── Danger zone ────────────────────────────────────────────────────────── */

.adm-danger-zone {
  border-top: 1px solid color-mix(in srgb, var(--danger) 28%, var(--line));
  padding-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}



.adm-danger-zone-label {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--danger);
  opacity: 0.8;
}



/* ── Organize tab internals ─────────────────────────────────────────────── */

.adm-list-col .adm-organize-ops {
  flex-shrink: 0;
  border-top: 1px solid var(--line-2);
  display: flex;
  flex-direction: column;
  gap: 0;
  overflow-y: auto;
  padding: 10px 8px;
}



.adm-books-layout.has-panel .adm-list-col .adm-organize-ops {
  max-height: 380px;
}

/* ── Mobile overrides ───────────────────────────────────────────────────── */

@media (max-width: 767px) {

  .adm-list-col .adm-organize-ops { padding: 8px 6px; }
}




.adm-body > .adm-books-layout {
  max-width: var(--adm-content-max);
  margin-inline: auto;
  width: 100%;
}



.adm-body > .adm-books-layout.has-panel {
  max-width: none;
}



.adm-body > .adm-books-layout.has-panel .adm-list-col { width: 220px; }



.adm-list-col,
.adm-panel-col,
.adm-panel-placeholder { background: var(--bg); }


/* ── Series tab internals ───────────────────────────────────────────────── */

.adm-series-tab {
  flex: 1;
}



.adm-series-ops {
  padding: 0 0 12px;
  display: flex;
  flex-direction: column;
}


/* Bad-title diagnostic list (CrawlTab) */
.adm-bad-title-list { display: flex; flex-direction: column; gap: 6px; }


.adm-bad-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  background: color-mix(in srgb, var(--warn, #d97706) 6%, var(--bg-card));
  border-radius: var(--r-base);
  border: 1px solid color-mix(in srgb, var(--warn, #d97706) 20%, transparent);
}


.adm-bad-title-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }


.adm-bad-title-id { font-size: var(--font-xs); font-family: var(--font-mono, monospace); color: var(--ink); }


.adm-bad-title-src {
  font-size: var(--font-xs); color: var(--ink-faint);
  text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}


.adm-bad-title-src:hover { text-decoration: underline; color: var(--accent); }


.adm-bad-title-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }


.adm-empty {
  padding: 24px 16px;
  color: var(--ink-faint);
  font-size: var(--font-compact);
  text-align: center;
}



.adm-panel-loading {
  padding: 24px;
  color: var(--ink-faint);
  font-size: var(--font-compact);
}



/* Bad-title badge (BookPanel header) */
.adm-bad-title-badge {
  margin-top: 2px;
  font-size: var(--font-xs);
  color: var(--warn, #d97706);
  font-weight: 500;
}



/* ── Book panel ──────────────────────────────────────────────────────────── */

.adm-book-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}



.adm-book-panel-header {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--line-2);
  flex-shrink: 0;
}



.adm-book-panel-title { flex: 1; min-width: 0; }



.adm-panel-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}



.adm-book-panel-title h2 {
  font-size: var(--font-sm);
  font-weight: 600;
  margin: 0;
  line-height: 1.4;
}



.adm-book-panel-author {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  margin-top: 2px;
}



.adm-back-btn {
  background: var(--surface);
  border: none;
  border-radius: var(--r-md);
  padding: 5px 10px;
  font-size: var(--font-compact);
  cursor: pointer;
  font-family: inherit;
  color: var(--ink-soft);
  white-space: nowrap;
  flex-shrink: 0;
}


.adm-back-btn:hover { background: var(--bg-2); }



/* mobile only */
.adm-back-btn--mobile { display: none; }




/* ── ChapterEditorPanel (shared WYSIWYG editor, now hosted inside
   BookEditPage.tsx rather than this file's own meta-form/chapter-list) ── */

.cep {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 14px 16px;
  gap: 10px;
  background: var(--surface-raised);
}

/* ── Mobile overrides ─────────────────────────────────────────────────────── */

@media (max-width: 767px) {

  .adm-back-btn--mobile { display: block; }

  .adm-book-panel { overflow-y: auto; }
}



[data-theme="dark"] .adm-book-panel-header { border-bottom-color: var(--line); }



[data-theme="dark"] .adm-search,
[data-theme="dark"] .adm-url-input {
  background: var(--surface); border-color: var(--line); color: var(--ink);
}


[data-theme="dark"] .adm-search::placeholder,
[data-theme="dark"] .adm-url-input::placeholder { color: var(--ink-faint); }


[data-theme="dark"] .adm-search:focus { border-color: var(--ink-faint); background: var(--surface); }


[data-theme="dark"] .adm-list-loading,
[data-theme="dark"] .adm-empty,
[data-theme="dark"] .adm-panel-loading { color: var(--ink-faint); }



[data-theme="dark"] .adm-book-panel-author { color: var(--ink-soft); }


[data-theme="dark"] .adm-back-btn { background: var(--surface); color: var(--ink-soft); }


[data-theme="dark"] .adm-back-btn:hover { background: var(--bg-2); }


.adm-body > .adm-books-layout.has-panel .adm-book-panel { overflow-y: auto; }


.adm-search-wrap,
.adm-book-panel-header { background: var(--surface-raised); border-color: var(--line); }


.adm-input {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 6px 10px;
  font-size: var(--font-sm);
  background: var(--bg);
  color: var(--ink);
  outline: none;
}



.adm-input:focus { border-color: var(--accent); }



/* Compact labeled setting row (inside accordion) — translation engine,
   Postype worker count, etc. all share this layout. */
.adm-setting-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 12px;
  margin-top: 8px;
  border-top: 1px solid var(--line-2);
  flex-wrap: wrap;
}


.adm-setting-label {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
}


.adm-setting-row .adm-input {
  width: 64px;
  flex: none;
}



.adm-select {
  height: 32px;
  padding: 0 8px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-1);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--font-compact);
  cursor: pointer;
}


.adm-select:disabled { opacity: 0.5; cursor: not-allowed; }


.adm-setting-hint {
  font-size: var(--font-xs);
  color: var(--ink-faint);
}


/* ── Merge suggestion panel ─────────────────────────────────────────────── */

.adm-merge-panel {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  margin-bottom: 16px;
  overflow: hidden;
}



.adm-merge-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}



.adm-merge-panel-title {
  font-size: var(--font-compact);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 6px;
}



.adm-merge-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--r-lg);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--font-2xs);
  font-weight: 700;
}



.adm-merge-panel-actions {
  display: flex;
  gap: 6px;
}



.adm-merge-btn {
  padding: 5px 10px;
  border-radius: var(--r-md);
  font-size: var(--font-xs);
  font-weight: 500;
  border: 1px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  transition: background 0.15s;
}


.adm-merge-btn:disabled { opacity: 0.45; cursor: default; }


.adm-merge-btn--reload {
  width: 30px;
  padding: 0;
  font-size: var(--font-icon);
  line-height: 1;
}



.adm-merge-empty, .adm-merge-error {
  padding: 16px 14px;
  font-size: var(--font-compact);
  color: var(--ink-faint);
  margin: 0;
}


.adm-merge-error { color: var(--danger); }



.adm-merge-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}



.adm-merge-card {
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
}


.adm-merge-card:last-child { border-bottom: none; }



.adm-merge-card-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 6px;
}



.adm-merge-series {
  font-size: var(--font-compact);
  font-weight: 600;
}



.adm-merge-author {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
}



.adm-merge-reason {
  font-size: var(--font-2xs);
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--line);
  padding: 1px 6px;
  border-radius: var(--r-sm);
  white-space: nowrap;
}



.adm-merge-expand-btn {
  margin-left: auto;
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  background: none;
  border: none;
  padding: 2px 4px;
  cursor: pointer;
  flex-shrink: 0;
  line-height: 1;
}


.adm-merge-expand-btn:hover { color: var(--ink); }



.adm-merge-detail {
  margin-bottom: 8px;
  overflow-x: auto;
}



.adm-merge-detail-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-2xs);
}



.adm-merge-detail-table th {
  text-align: left;
  padding: 3px 6px;
  color: var(--ink-faint);
  font-weight: 600;
  border-bottom: 1px solid var(--line-2);
  white-space: nowrap;
}



.adm-merge-detail-table td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--line-2);
  vertical-align: top;
}



.adm-merge-detail-table tr:last-child td { border-bottom: none; }



.adm-merge-detail-title {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}



.adm-merge-detail-title a {
  color: var(--accent);
  text-decoration: none;
}


.adm-merge-detail-title a:hover { text-decoration: underline; }



/* row states */
.adm-merge-row--excluded { opacity: 0.38; }


.adm-merge-row--added td:first-child + td { color: var(--ok); }



.adm-merge-include-check {
  cursor: pointer;
  accent-color: var(--accent);
}



/* selection hint "3/5 선택" */
.adm-merge-selection-hint {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  margin-right: auto;
}



/* add-file button below table */
.adm-merge-add-btn {
  margin-top: 6px;
  font-size: var(--font-2xs);
  color: var(--accent);
  background: none;
  border: 1px dashed var(--accent);
  border-radius: var(--r-sm);
  padding: 3px 10px;
  cursor: pointer;
  width: 100%;
}


.adm-merge-add-btn:hover { background: var(--accent-bg); }



/* add-file panel */
.adm-merge-add-panel {
  margin-top: 6px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  background: var(--surface-2, var(--surface));
}



.adm-merge-add-head {
  display: flex;
  gap: 6px;
  margin-bottom: 6px;
}



.adm-merge-add-search {
  flex: 1;
  font-size: var(--font-2xs);
  padding: 3px 7px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
}



.adm-merge-add-empty {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  padding: 4px 2px;
  margin: 0;
}



.adm-merge-candidate-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 200px;
  overflow-y: auto;
}



.adm-merge-candidate-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 2px;
  border-bottom: 1px solid var(--line-2);
}


.adm-merge-candidate-row:last-child { border-bottom: none; }



.adm-merge-candidate-title {
  flex: 1;
  font-size: var(--font-2xs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}



.adm-merge-candidate-meta {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  white-space: nowrap;
  flex-shrink: 0;
}


.adm-merge-candidate-meta em {
  font-style: normal;
  color: var(--ink-soft);
}



.adm-merge-candidate-add {
  flex-shrink: 0;
  font-size: var(--font-2xs);
  padding: 2px 8px;
}



/* collapsed view: added books shown with + prefix */
.adm-merge-title--added { color: var(--ok); }



.adm-merge-titles {
  list-style: none;
  padding: 0;
  margin: 0 0 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}



.adm-merge-titles li {
  font-size: var(--font-xs);
  color: var(--ink-dim);
  padding-left: 10px;
  position: relative;
}


.adm-merge-titles li::before {
  content: "·";
  position: absolute;
  left: 2px;
  color: var(--ink-faint);
}



.adm-merge-card-actions {
  display: flex;
  gap: 6px;
}



.adm-merge-card--failed {
  border-left: 3px solid var(--danger);
  opacity: 0.85;
}



.adm-merge-fail-reason {
  font-size: var(--font-2xs);
  color: var(--danger);
  margin: 2px 0 6px;
}



.adm-merge-failed-section {
  margin-top: 16px;
  border-top: 1px dashed var(--line);
  padding-top: 12px;
}



.adm-merge-failed-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}



.adm-merge-failed-title {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-soft);
}



.adm-merge-failed-hint {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
}


.adm-merge-count::before { display: none; }


.adm-merge-panel { padding: 0; background: var(--surface-raised); border-color: var(--line); border-radius: var(--r-lg); }


.adm-merge-card { padding: 16px; gap: 10px; }


.ops-section { display: flex; flex-direction: column; gap: 8px; }



.ops-section__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
}



.ops-frequent .op-item { background: var(--surface-raised); }



.op-item__rank {
  width: 19px;
  height: 19px;
  flex: 0 0 19px;
  display: inline-grid;
  place-items: center;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: var(--font-2xs);
  font-weight: 750;
}



.op-item__caution {
  display: inline-flex;
  align-items: center;
  min-height: 18px;
  margin-left: 7px;
  padding: 0 6px;
  border: 1px solid color-mix(in srgb, var(--danger) 24%, var(--line));
  border-radius: var(--r-pill);
  color: color-mix(in srgb, var(--danger) 68%, var(--ink-soft));
  font-size: var(--font-nano);
  font-weight: 650;
}



/* ── Op item ─────────────────────────────────────────────────────────────── */

.op-item {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  overflow: hidden;
  transition: border-color 0.12s, box-shadow 0.12s;
}


.op-item:hover { border-color: color-mix(in srgb, var(--ink-soft) 20%, var(--line)); }


.op-item.is-open { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 8%, transparent); }


.op-item--danger { border-color: color-mix(in srgb, var(--danger) 22%, var(--line)); }


.op-item--danger .op-item__title { color: var(--danger); }



.op-item__row {
  display: flex;
  align-items: center;
  gap: 8px;
}



.op-item__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }



.op-item__title {
  font-size: var(--font-sm);
  font-weight: 600;
  letter-spacing: -0.224px;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}



.op-item__desc {
  font-size: var(--font-xs);
  letter-spacing: -0.12px;
  color: var(--ink-faint);
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}



.op-item__run {
  flex-shrink: 0;
  height: 28px;
  padding: 0 12px;
  border: none;
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--font-xs);
  font-weight: 500;
  letter-spacing: -0.12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s, transform 0.1s;
  white-space: nowrap;
}


.op-item__run:hover:not(:disabled) { background: var(--accent-focus); }


.op-item__run:active:not(:disabled) { transform: scale(0.95); }


.op-item__run:disabled { opacity: 0.35; cursor: not-allowed; }


.op-item--danger .op-item__run { background: var(--danger); }


.op-item--danger .op-item__run:hover:not(:disabled) { background: color-mix(in srgb, var(--danger) 88%, black); }



.op-item__toggle {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink-soft);
  font-size: var(--font-2xs);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s, border-color 0.12s;
}


.op-item__toggle:hover { background: var(--line-2); border-color: var(--ink-faint); }


.op-item.is-open .op-item__toggle { background: var(--accent-bg); border-color: var(--accent); color: var(--accent); }



.op-item__form {
  display: flex;
  gap: 6px;
  padding: 8px 10px 10px 12px;
  border-top: 1px solid var(--line-2);
}



.op-item__input {
  flex: 1;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-size: var(--font-xs);
  font-family: 'JetBrains Mono', monospace;
  background: var(--bg-card);
  color: var(--ink);
  outline: none;
  letter-spacing: -0.08px;
}


.op-item__input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent);
}



.op-autocomplete {
  flex: 1;
  position: relative;
}


.op-autocomplete .op-item__input {
  width: 100%;
}


.op-autocomplete__dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: 0 2px 12px color-mix(in srgb, var(--ink) 8%, transparent);
  z-index: 200;
  overflow: hidden;
  max-height: 280px;
  overflow-y: auto;
}


.op-autocomplete__option {
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--line-2);
  cursor: pointer;
  gap: 2px;
}


.op-autocomplete__option:last-child { border-bottom: none; }


.op-autocomplete__name {
  display: flex;
  gap: 6px;
  align-items: baseline;
}


.op-autocomplete__author {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  flex-shrink: 0;
}


.op-autocomplete__title {
  font-size: var(--font-compact);
  color: var(--ink);
  font-weight: 500;
}


.op-autocomplete__id {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: -0.2px;
}



.op-item__run-inline {
  padding: 6px 14px;
  border: none;
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--font-xs);
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, transform 0.1s;
}


.op-item__run-inline:hover:not(:disabled) { background: var(--accent-focus); }


.op-item__run-inline:active:not(:disabled) { transform: scale(0.95); }


.op-item__run-inline:disabled { opacity: 0.4; cursor: not-allowed; }


.ops-section,
.adm-crawl-section,
.adm-series-ops { gap: var(--adm-section-gap); }


.op-item__row { min-height: 60px; padding: 12px var(--adm-card-pad); }



/* Operation panels stay neutral; semantic red is reserved for confirmation. */
.op-item .op-item__run,
.op-item--danger .op-item__run {
  width: 30px;
  height: 30px;
  min-width: 30px;
  min-height: 30px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-raised);
  color: var(--ink-faint);
  box-shadow: none;
}



.op-item .op-item__run:hover:not(:disabled),
.op-item--danger .op-item__run:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--ink-soft) 28%, var(--line));
  background: var(--surface);
  color: var(--ink);
}


/* ── Platform connection section ────────────────────────────────────────── */

.platform-section {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  display: flex;
  flex-direction: column;
  gap: 10px;
}



.platform-row {
  display: flex;
  align-items: center;
  gap: 10px;
}



.platform-row__name {
  font-size: var(--font-sm);
  font-weight: 600;
  min-width: 80px;
}



.platform-row__status {
  flex: 1;
  font-size: var(--font-compact);
}



.platform-row__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}



.platform-action-hint {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  line-height: 1.4;
}



.platform-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  font-size: var(--font-xs);
  font-weight: 500;
}




.platform-btn {
  padding: 5px 12px;
  border-radius: var(--r-md);
  font-size: var(--font-compact);
  font-weight: 500;
  border: none;
  cursor: pointer;
  white-space: nowrap;
}



.platform-btn:disabled { opacity: 0.5; cursor: not-allowed; }




.platform-btn--disconnect {
  background: transparent;
  color: var(--ink-soft);
  border: 1px solid var(--line);
}



.platform-btn--disconnect:hover:not(:disabled) {
  background: var(--surface);
}



.platform-hint {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  line-height: 1.5;
}




.platform-connecting-hint {
  font-size: var(--font-xs);
  color: var(--ink-soft);
  font-style: italic;
}



.platform-infotip {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  margin-left: 6px;
}



.platform-infotip__icon {
  width: 16px;
  height: 16px;
  padding: 0;
  display: inline-grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface-raised);
  color: var(--ink-soft);
  font: italic 700 10px/1 Georgia, serif;
  cursor: pointer;
}



.platform-infotip__icon:hover,
.platform-infotip__icon:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}



.platform-infotip__bubble {
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  left: 0;
  width: 240px;
  max-width: calc(100vw - 32px);
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-raised);
  box-shadow: var(--shadow-2);
  color: var(--ink-soft);
  font-size: var(--font-2xs);
  font-weight: 400;
  line-height: 1.5;
  white-space: pre-line;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-2px);
  transition: opacity .12s, transform .12s, visibility .12s;
  pointer-events: none;
}



.platform-infotip__icon:hover + .platform-infotip__bubble,
.platform-infotip__icon:focus-visible + .platform-infotip__bubble,
.platform-infotip__bubble--open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}



.platform-section { padding: var(--adm-card-pad); background: var(--surface-raised); border-color: var(--line); border-radius: var(--r-lg); }


.adm-log {
  flex: 1;
  overflow-y: auto;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 12px;
  font-family: 'JetBrains Mono', 'Consolas', monospace;
  font-size: var(--font-xs);
  line-height: 1.6;
}



/* ── Status bar ─────────────────────────────────────────────────────────── */

.adm-status-bar {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  flex-shrink: 0;
  padding: 0 0 4px;
}



.adm-status-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--line-2);
  font-size: var(--font-xs);
  letter-spacing: -0.12px;
}



.adm-status-chip__label { color: var(--ink-faint); }


.adm-status-chip__value { font-weight: 600; color: var(--ink); }



.adm-status-chip--danger .adm-status-chip__value { color: color-mix(in srgb, var(--danger) 60%, var(--ink-soft)); }


.adm-status-chip--ok     .adm-status-chip__value { color: #2A533C; }


.adm-status-chip--running { animation: adm-pulse 1.2s ease-in-out infinite; }


.adm-status-chip--running .adm-status-chip__value { color: var(--ink-soft); }


.adm-status-chip--dim .adm-status-chip__value { color: var(--ink-faint); }



@keyframes adm-pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.55; }
}



/* ── Accordion ──────────────────────────────────────────────────────────── */

.adm-accordion {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  flex-shrink: 0;
}



.adm-accordion-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 10px 14px;
  background: var(--surface);
  border: none;
  font-family: inherit;
  font-size: var(--font-compact);
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 0.12s;
}


.adm-accordion-head:hover { background: var(--bg-2); }



.adm-accordion-chevron { color: var(--ink-faint); font-size: var(--font-2xs); }



.adm-accordion-body {
  padding: 12px;
  background: var(--bg-card);
  border-top: 1px solid var(--line-2);
  display: flex;
  flex-direction: column;
  gap: 10px;
}



/* ── Confirm modal ───────────────────────────────────────────────────────── */

.adm-modal-overlay {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--ink) 32%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9000;
  padding: 24px;
}



.adm-modal {
  background: var(--bg-card);
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  padding: 24px;
  max-width: 400px;
  width: 100%;
  box-shadow: 0 4px 20px color-mix(in srgb, var(--ink) 8%, transparent);
  display: flex;
  flex-direction: column;
  gap: 10px;
}



.adm-modal-title {
  margin: 0;
  font-size: var(--font-md);
  font-weight: 600;
  color: var(--ink);
}



.adm-modal-desc {
  margin: 0;
  font-size: var(--font-compact);
  color: var(--ink-soft);
  line-height: 1.55;
}



.adm-modal-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding-top: 8px;
}




/* ── Mobile overrides ───────────────────────────────────────────────────── */

@media (max-width: 767px) {

  .adm-status-bar {
    gap: 4px;
  }

  .adm-status-chip {
    font-size: var(--font-2xs);
    padding: 4px 8px;
  }
}




.adm-btn--ink {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}


.adm-btn--ink:hover:not(:disabled) { background: var(--ink-soft); border-color: var(--ink-soft); }


.adm-stat-badge--danger  { color: #7A3030; background: #F5CFCF; }


.adm-stat-badge--danger::before  { background: #C94747; }


/* Drop zone card */
.adm-dropzone-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 32px 24px;
  border: 1.5px dashed var(--line-1);
  border-radius: var(--r-lg);
  cursor: pointer;
  background: var(--surface);
  transition: border-color 0.15s, background 0.15s;
  user-select: none;
  text-align: center;
}


.adm-dropzone-card:hover,
.adm-dropzone-card.is-over {
  border-color: var(--accent);
  background: var(--accent-bg);
}


.adm-dropzone-card.is-uploading {
  opacity: 0.6;
  pointer-events: none;
}


.adm-dropzone-card__icon { color: var(--ink-faint); }


.adm-dropzone-card__label {
  font-size: var(--font-compact);
  color: var(--ink-soft);
  line-height: 1.5;
}


.adm-dropzone-card__browse {
  margin-top: 4px;
  padding: 7px 18px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-base);
  background: var(--bg-card);
  font-size: var(--font-sm);
  color: var(--ink);
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, border-color 0.15s;
}


.adm-dropzone-card__browse:hover {
  background: var(--bg-card);
  border-color: color-mix(in srgb, var(--ink-soft) 30%, var(--line));
}


.adm-dropzone-card__browse:disabled { opacity: 0.5; cursor: not-allowed; }



/* Uploading file row (progress bar) */
.adm-upload-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-lg);
  background: var(--bg-card);
}


.adm-upload-row__icon { flex: 0 0 auto; color: var(--ink-faint); }


.adm-upload-row__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}


.adm-upload-row__name {
  font-size: var(--font-compact);
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


.adm-upload-row__track {
  height: 4px;
  border-radius: 2px;
  background: var(--line-1);
  overflow: hidden;
}


.adm-upload-row__bar {
  height: 100%;
  border-radius: 2px;
  background: var(--accent);
  width: 40%;
  animation: adm-progress-slide 1.4s ease-in-out infinite;
}


@keyframes adm-progress-slide {
  0%   { transform: translateX(-150%); }
  100% { transform: translateX(400%); }
}


.adm-upload-row__status {
  font-size: var(--font-xs);
  color: var(--ink-faint);
  white-space: nowrap;
  flex: 0 0 auto;
}



/* Warnings */
.adm-import-warning {
  font-size: var(--font-xs);
  padding: 8px 12px;
  border-radius: var(--r-md);
  border-left: 3px solid;
}


.adm-import-warning--enc {
  background: color-mix(in srgb, var(--warn) 8%, var(--bg-card));
  border-color: var(--warn);
  color: color-mix(in srgb, var(--warn) 72%, var(--ink));
}


.adm-import-warning--series {
  background: var(--surface);
  border-color: var(--line);
  color: var(--ink-soft);
}



/* Staged file list */
.adm-staged-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}



.adm-staged-footer {
  display: flex;
  justify-content: flex-end;
  padding-top: 4px;
}



/* Staged card */
.adm-staged-card {
  border: 1px solid var(--line-1);
  border-radius: var(--r-lg);
  background: var(--bg-card);
  overflow: hidden;
  transition: border-color 0.15s;
}


.adm-staged-card.is-done  { border-color: var(--ok); }


.adm-staged-card.is-error { border-color: var(--danger); }



.adm-staged-card__header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--line-2);
}


.adm-staged-card__filename {
  flex: 1;
  font-size: var(--font-compact);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--ink);
}


.adm-staged-card__stats {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
  white-space: nowrap;
}


.adm-staged-card__close {
  background: none;
  border: none;
  font-size: var(--font-sm);
  color: var(--ink-faint);
  cursor: pointer;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  line-height: 1;
}


.adm-staged-card__close:hover { background: var(--line-2); color: var(--ink); }



.adm-staged-card__result {
  padding: 10px 14px;
  font-size: var(--font-compact);
  font-weight: 400;
}


.adm-staged-card__result--ok   { color: var(--ok); }


.adm-staged-card__result--skip { color: var(--ink-soft); }


.adm-staged-card__result--err  { color: var(--danger); }


.adm-staged-card__result code  { font-family: monospace; font-size: var(--font-xs); opacity: 0.8; }


.adm-split-result-list { list-style: none; margin-top: 6px; display: flex; flex-direction: column; gap: 3px; }


.adm-split-result-item { display: flex; align-items: center; justify-content: space-between; font-size: var(--font-xs); gap: 8px; }


.adm-split-result-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }


.adm-split-result-status { flex-shrink: 0; color: var(--ink-faint); }



/* Split editor ??????????????????????????????????????????????????????????? */
.adm-split-editor { display: flex; flex-direction: column; gap: 12px; padding: 12px 0; }


.adm-split-editor__summary { display: flex; align-items: center; gap: 8px; font-size: var(--font-compact); font-weight: 600; color: var(--ink); padding-bottom: 4px; border-bottom: 1px solid var(--line); }


.adm-split-editor__count { color: var(--ink-soft); font-weight: 700; }


.adm-split-editor__actions { display: flex; gap: 8px; padding-top: 4px; }



.adm-split-review__hint {
  margin: 0;
  color: var(--ink-soft);
  font-size: var(--font-xs);
}



.adm-split-review__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 10px;
}



.adm-split-review__work {
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}



.adm-split-review__work-head {
  color: var(--ink);
  font-size: var(--font-xs);
  font-weight: 700;
}



.adm-split-review__work label {
  display: flex;
  flex-direction: column;
  gap: 5px;
}



.adm-split-review__work label > span {
  color: var(--ink-soft);
  font-size: var(--font-2xs);
  font-weight: 600;
}



.adm-split-review__work input {
  width: 100%;
  min-height: 36px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-raised);
  color: var(--ink);
  font: inherit;
}



.adm-split-review__work input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent);
}



.adm-split-candidate { border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }


.adm-split-candidate--off { opacity: 0.55; }


.adm-split-candidate__header { display: flex; align-items: center; gap: 8px; padding: 8px 10px; background: var(--bg-2); }


.adm-split-candidate__label { font-size: var(--font-xs); font-weight: 600; color: var(--ink); flex: 1; }


.adm-split-candidate__hint { font-size: var(--font-2xs); color: var(--ink-faint); }



.adm-split-toggle { font-size: var(--font-2xs); font-weight: 600; padding: 3px 8px; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface); color: var(--ink-faint); cursor: pointer; white-space: nowrap; }


.adm-split-toggle--on { background: var(--surface); color: var(--ink); border-color: var(--line); }



.adm-split-context { display: flex; flex-direction: column; }


.adm-split-context-line { display: flex; align-items: baseline; gap: 6px; padding: 3px 10px; cursor: pointer; font-size: var(--font-xs); font-family: 'Pretendard', -apple-system, sans-serif; transition: background 0.1s; }


.adm-split-context-line:hover { background: var(--surface); }


.adm-split-context-line--before { background: var(--bg); color: var(--ink-faint); }


.adm-split-context-line--after { background: var(--bg-2); color: var(--ink); }


.adm-split-context-line--split { background: var(--surface); color: var(--ink); border-left: 3px solid var(--ink-faint); font-weight: 600; }


.adm-split-context-line__marker { color: var(--ink-soft); font-size: var(--font-2xs); flex-shrink: 0; width: 10px; }


.adm-split-context-line__num { color: var(--ink-faint); font-size: var(--font-2xs); flex-shrink: 0; width: 28px; text-align: right; user-select: none; }


.adm-split-context-line__text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.adm-split-editor__empty { font-size: var(--font-xs); color: var(--ink-faint); line-height: 1.6; padding: 12px; background: var(--bg-2); border-radius: var(--r-md); border: 1px dashed var(--line); }


.adm-split-jumps {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--bg-card) 92%, transparent);
}


.adm-split-jump {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 54px;
  height: 28px;
  padding: 0 9px;
  border: 1px solid color-mix(in srgb, var(--accent) 32%, var(--line));
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--accent) 10%, var(--bg));
  color: var(--accent);
  font-size: var(--font-2xs);
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}


.adm-split-jump span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--font-2xs);
}


.adm-split-jump b {
  font-weight: 700;
}


.adm-split-full-lines {
  max-height: min(62dvh, 680px);
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg);
}


.adm-split-full-line {
  width: 100%;
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 3px 10px;
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line-2) 55%, transparent);
  background: var(--bg);
  color: var(--ink-soft);
  cursor: pointer;
  font-family: 'Pretendard', -apple-system, sans-serif;
  font-size: var(--font-xs);
  text-align: left;
}


.adm-split-full-line:hover:not(:disabled) {
  background: var(--surface);
}


.adm-split-full-line--split {
  background: var(--surface);
  color: var(--ink);
  border-left: 3px solid var(--ink-faint);
  font-weight: 600;
}



/* Editable fields */
.adm-staged-card__body {
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}



.adm-import-preview {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--surface);
}



.adm-import-preview__head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink);
}



.adm-import-preview__count,
.adm-import-preview__flag {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  font-size: var(--font-2xs);
  font-weight: 500;
  white-space: nowrap;
}



.adm-import-preview__count {
  background: var(--surface);
  color: var(--ink-soft);
}



.adm-import-preview__flag {
  background: color-mix(in srgb, var(--warn) 10%, var(--bg-card));
  color: color-mix(in srgb, var(--warn) 72%, var(--ink));
}



.adm-import-preview__warning {
  font-size: var(--font-xs);
  line-height: 1.45;
  color: var(--ink-soft);
}



.adm-import-preview__works {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 6px;
}



.adm-import-preview__work {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--bg-card);
}



.adm-import-preview__work-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--font-xs);
  color: var(--ink);
}



.adm-import-preview__work-count {
  flex-shrink: 0;
  font-size: var(--font-2xs);
  color: var(--ink-faint);
}



.adm-import-preview__chapters {
  display: flex;
  flex-direction: column;
  gap: 1px;
  max-height: 264px;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}



.adm-import-preview__chapter {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 52px;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  padding: 4px 0;
  border-top: 1px solid color-mix(in srgb, var(--line-2) 70%, transparent);
}



.adm-import-preview__chapter:first-child {
  border-top: none;
}



.adm-import-preview__chapter-index,
.adm-import-preview__chapter-size {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
}



.adm-import-preview__chapter-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--font-xs);
  color: var(--ink-soft);
}



.adm-import-preview__chapter-size {
  text-align: right;
}



.adm-import-preview__more {
  font-size: var(--font-2xs);
  color: var(--ink-faint);
}



.adm-staged-row {
  display: grid;
  grid-template-columns: 72px 1fr;
  align-items: center;
  gap: 10px;
}


.adm-staged-row label {
  font-size: var(--font-xs);
  font-weight: 600;
  color: var(--ink-soft);
  text-align: right;
}


.adm-staged-row--check {
  grid-template-columns: 72px auto;
  justify-content: start;
}


.adm-staged-row--check label {
  display: flex;
  align-items: center;
  gap: 6px;
  text-align: left;
  font-weight: 400;
  cursor: pointer;
}


.adm-staged-input {
  width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  font-size: var(--font-compact);
  font-family: inherit;
  background: var(--bg);
  color: var(--ink);
  outline: none;
  transition: border-color 0.15s;
  box-sizing: border-box;
}


.adm-staged-input:focus  { border-color: var(--accent); }


.adm-staged-input:disabled { opacity: 0.5; }



.adm-staged-card__actions {
  display: flex;
  gap: 8px;
  padding-top: 4px;
  justify-content: flex-end;
}
/* ============================================================
   Layer 6: Platform layout rules

   Mobile web: compact, thumb-first.
   Desktop web: wider information surfaces.
   Installed app/PWA: safe-area aware.
   ============================================================ */

/* ── Global ─────────────────────────────────────────────────── */

.read-foot__pos {
  letter-spacing: 0;
}

/* ── Mobile (max-width: 767px) ──────────────────────────────── */

@media (max-width: 767px) {
  :root {
    --platform-grid-min: 108px;
    --bar-h: 52px;
  }

  /* Every non-reader screen's .col (library/detail/search/add/notes/
     settings/author/series/admin -- see design/css/1-primitives.css:423)
     used the fixed 24px --pad-lg side padding at every viewport, unlike
     the reader's own mobile-tuned --reader-pad (design/app.tsx). Tightened
     to the standard 16px --pad token here so mobile side margins read
     consistently across the whole app (user request, 2026-08-21). Reader
     screens are unaffected: .reader-screen .reader-pref-scroll .col
     (reader.css) is more specific and always wins regardless of source
     order. */
  .col {
    padding-left: var(--pad);
    padding-right: var(--pad);
  }

  .page-bar {
    flex: 0 0 var(--bar-h);
    left: 0;
    right: 0;
  }

  .det-cover,
  .det-cover > * {
    width: 104px;
  }

  .det-cover > * {
    height: 146px;
  }

  .read-title {
    font-size: var(--font-2xl);
    line-height: 1.2;
    margin-bottom: 16px;
  }

  .read-meta {
    margin-bottom: 8px;
  }

  .read-body {
    line-height: max(var(--reader-leading), 1.82);
  }

  .reader-para {
    margin-bottom: max(var(--reader-para-gap), 0.5em);
  }

  .read-foot__btn {
    width: clamp(88px, 30vw, 124px);
    min-height: 38px;
  }

  .read-foot__pos {
    font-size: 10px;
    opacity: 0.72;
  }

  .detail-screen .det-cta {
    position: sticky;
    bottom: 12px;
    z-index: 8;
    margin-top: 18px;
  }

  .detail-screen .col {
    padding-bottom: 104px;
  }

  .det-info {
    min-width: 0;
  }

  .det-title {
    font-size: var(--font-xl);
    line-height: 1.18;
  }

  .det-author,
  .det-subtitle {
    font-size: var(--font-compact);
  }

  .book-grid-card__cover {
    aspect-ratio: 2 / 3;
  }

  .sheet-card {
    border-radius: var(--r-lg) var(--r-lg) 0 0;
  }

  .sheet-head {
    padding-left: 18px;
    padding-right: 18px;
  }

  .book-grid {
    grid-template-columns: repeat(auto-fill, minmax(var(--platform-grid-min), 1fr));
    gap: 16px 10px;
  }

  .continue-card--new {
    margin-left: 0;
    margin-right: 0;
  }
}

/* ── Desktop (min-width: 768px) ─────────────────────────────── */

@media (min-width: 768px) {
  :root {
    --platform-grid-min: 148px;
    --platform-content-max: 810px;
    --platform-reader-max: 730px;
  }

  .library-screen .col,
  .search-screen .col,
  .add-screen .col,
  .notes-screen .col,
  .settings-screen .col,
  .author-screen .col {
    max-width: var(--platform-content-max);
  }

  .detail-screen .col {
    max-width: var(--platform-content-max);
  }

  .reader-screen .col {
    max-width: var(--platform-reader-max);
  }

  /* Desktop keeps nav-toggle/spacer visible next to the search box
     (App.tsx only hides them on mobile), so this can go back to a small
     right-aligned pill instead of the mobile full-row takeover above. */
  .app-header__inline--compact {
    flex: 0 0 auto;
    width: 300px;
  }

  .reader-head-page {
    font-size: var(--font-2xs);
  }

  .reader-pref-scroll .col {
    padding-top: calc(var(--bar-h) + 42px);
    padding-bottom: 132px;
  }

  .read-title {
    font-size: 32px;
    line-height: 1.18;
    margin-bottom: 24px;
  }

  .read-meta {
    margin-bottom: 10px;
  }

  .read-body {
    line-height: max(var(--reader-leading), 1.9);
    font-size: var(--font-md);
  }

  .reader-para {
    margin-bottom: max(var(--reader-para-gap), 0.5em);
  }

  .book-grid {
    grid-template-columns: repeat(auto-fill, minmax(var(--platform-grid-min), 1fr));
    gap: 34px 24px;
  }

  .continue-card--new {
    margin: 8px 0 26px;
    padding: 0 0 24px;
    border: none;
    border-bottom: 1px solid var(--line-2);
    border-radius: 0;
    background: transparent;
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr);
    grid-template-areas:
      "cover src"
      "cover title"
      "cover chap"
      "cover pct"
      "bar bar";
    gap: 5px 20px;
    align-items: center;
  }

  .continue-card__cover { width: 92px; border-radius: var(--r-md); }
  .continue-card--new .src-col { grid-area: src; margin: 0; }
  .continue-card--new .ttl { grid-area: title; font-size: var(--font-2xl); line-height: 1.12; margin: 0; }
  .continue-card--new .chap { grid-area: chap; margin: 0; }
  .continue-card--new .pct { grid-area: pct; font-size: var(--font-md); font-weight: 600; margin: 2px 0 0; justify-self: start; }
  .continue-card--new .bar { grid-area: bar; height: 2px; margin-top: 12px; }

  .lib-section-head {
    margin-left: 0;
    margin-right: 0;
  }

  .coll-row-wrap {
    padding: 2px 0 4px;
  }

  .coll-row {
    padding-left: 0;
    padding-right: 0;
    gap: 6px;
  }

  .coll {
    width: 76px;
  }

  .coll__icon {
    width: 52px;
    height: 52px;
  }

  .library-screen .lib-kind-pills {
    padding: 0 0 10px;
  }

  .library-screen .feed-list {
    margin-top: 0;
    padding-top: 2px;
  }

  .lib-section-head {
    padding: 34px 0 12px;
  }

  .book-list {
    border: none;
    border-radius: 0;
    overflow: hidden;
    background: transparent;
  }

  .book-grid-card__cover {
    border-radius: var(--r-lg);
    aspect-ratio: 2 / 3;
    transition: box-shadow 0.18s var(--ease), transform 0.18s var(--ease), opacity 0.18s var(--ease);
  }

  .book-grid-card:hover .book-grid-card__cover {
    transform: translateY(-1px);
  }

  .book-grid-card__progress {
    height: 2px;
  }

  .book-grid-card__title {
    font-size: var(--font-xs);
    line-height: 1.35;
  }

  .book-grid-card__bottom {
    font-size: var(--font-2xs);
  }

  .det-title {
    font-size: var(--font-3xl);
    line-height: 1.12;
    letter-spacing: 0;
    margin-bottom: 12px;
  }

  .det-author {
    margin-top: 8px;
  }

  .det-rating {
    margin-top: 14px;
  }

  .det-meta-section {
    padding: 30px 0;
    border-top: none;
    border-bottom-color: var(--line-2);
    gap: 14px;
  }

  .det-memo__textarea {
    border-radius: var(--r-lg);
    padding: 12px 14px;
  }

  .det-memo {
    margin-top: 18px;
  }

  .read-foot {
    justify-content: center;
    gap: 10px;
    width: min(420px, calc(100vw - 64px));
  }

  .read-foot__btn {
    width: auto;
    min-width: 94px;
    height: 36px;
  }

  .read-foot:hover .read-foot__btn,
  .read-foot__btn:focus-visible {
    opacity: 1;
  }

  .read-foot__pos {
    flex-basis: 70px;
    font-size: 10px;
    opacity: 0.58;
  }

  .toc-panel--desktop {
    width: 300px;
    border-left: 1px solid var(--line);
  }

  .toc-panel__inner {
    padding: 18px 18px 24px;
  }

  .toc-panel__head {
    font-size: var(--font-compact);
  }

  .toc-panel__list {
    gap: 2px;
  }

  .toc-item {
    min-height: 36px;
    padding: 8px 10px;
    border-radius: var(--r-md);
  }

  .adm-body {
    max-width: none;
  }

  .adm-books-layout.has-panel .adm-list-col {
    width: min(34vw, 380px);
  }

  .adm-panel-col {
    min-width: 0;
  }

  .adm-op-grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  }

  .adm-op-card {
    border-radius: var(--r-lg);
    transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), transform 0.12s var(--ease);
  }

  .adm-op-card:hover:not(:disabled) {
    transform: translateY(-1px);
    border-color: color-mix(in srgb, var(--accent) 36%, var(--line));
    background: var(--bg-card);
  }

  .adm-op-card--danger {
    background: color-mix(in srgb, var(--danger) 4%, var(--bg-card));
  }

  .adm-op-card--danger:hover:not(:disabled) {
    border-color: color-mix(in srgb, var(--danger) 56%, var(--line));
    background: color-mix(in srgb, var(--danger) 7%, var(--bg-card));
  }

  .adm-empty,
  .adm-list-loading {
    display: grid;
    place-items: center;
    min-height: 96px;
    border: 1px dashed var(--line);
    border-radius: var(--r-lg);
    background: color-mix(in srgb, var(--surface) 42%, transparent);
  }

  .adm-log {
    border-color: var(--line);
  }

  .sheet {
    align-items: center;
    justify-content: center;
    padding: 32px;
  }

  .sheet-card {
    width: min(640px, calc(100vw - 64px));
    max-height: min(760px, calc(100dvh - 64px));
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
  }

  .sheet-card--settings {
    width: min(720px, calc(100vw - 64px));
  }

  .sheet-card--settings .reader-settings,
  .sheet-card--settings .tts-settings {
    padding: 4px 24px 20px;
  }

  .sheet-card--settings .reader-settings .section-lbl,
  .sheet-card--settings .tts-settings .section-lbl {
    margin-top: 10px;
    padding: 18px 0 10px;
  }

  .sheet-card--settings .reader-settings > *,
  .sheet-card--settings .tts-settings > * {
    max-width: 100%;
  }

  .sheet-card--settings .font-stepper,
  .sheet-card--settings .seg-control,
  .settings-screen .seg-control {
    min-height: 32px;
  }

  .settings-screen .util-row {
    display: grid;
    grid-template-columns: minmax(160px, 1fr) auto;
    gap: 18px;
    align-items: center;
    padding: 14px 18px;
  }

  .settings-screen .util-row-head {
    min-width: 0;
  }

  .settings-screen .util-card {
    border-radius: var(--r-lg);
  }

  .danger-zone {
    opacity: 0.76;
    background: color-mix(in srgb, var(--danger) 3%, transparent);
  }

  .sheet-card--confirm {
    width: min(520px, calc(100vw - 64px));
  }

  .sheet-card--action {
    width: min(420px, calc(100vw - 64px));
  }
}

/* ── det-hero: shown at ≥900px ──────────────────────────────── */

@media (min-width: 900px) {
  .det-hero {
    display: grid;
    grid-template-columns: 180px minmax(0, 1fr);
    gap: 34px;
    align-items: start;
    padding: 42px 0 46px;
    border: none;
    border-bottom: 1px solid var(--line-2);
    border-radius: 0;
    background: transparent;
  }

  .det-cover,
  .det-cover > * {
    width: 180px;
  }

  .det-cover > * {
    height: 252px;
  }
}

/* ── Reader TOC ─────────────────────────────────────────────── */

@media (min-width: 768px) and (max-width: 1179px) {
  .reader-body--toc .reader-pref-scroll .col {
    max-width: var(--platform-reader-max);
  }

  .reader-body--toc .toc-panel--desktop {
    width: min(320px, 34vw);
    background: var(--bg-card);
    border-right: 1px solid var(--line);
  }
}

@media (min-width: 1180px) {
  .reader-body--toc .reader-pref-scroll .col {
    max-width: min(var(--platform-reader-max), calc(100vw - 360px));
  }
}

/* ── Large desktop (1280px+) ────────────────────────────────── */

@media (min-width: 1280px) {
  :root {
    --platform-grid-min: 172px;
  }

  .detail-screen .col,
  .library-screen .col,
  .search-screen .col,
  .add-screen .col,
  .notes-screen .col,
  .settings-screen .col,
  .author-screen .col {
    max-width: var(--platform-content-max);
  }
}

@media (min-width: 768px) and (max-width: 1179px) {
  .library-screen .col {
    max-width: 730px;
  }
}

.ctx-col-new--modal {
  padding: 8px 12px 12px;
}

.ctx-col-new--modal .ctx-col-new__btn {
  width: 100%;
  min-height: 34px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--font-sm);
  font-weight: 600;
}

.ctx-col-new--modal .ctx-col-new__btn:hover {
  background: var(--bg-2);
}

/* ── PWA / standalone ───────────────────────────────────────── */

@media (display-mode: standalone) {
  body {
    overscroll-behavior-y: none;
  }

  .phone {
    height: 100dvh;
  }

  .screen-scroll,
  .col-scroll,
  .det-body {
    overscroll-behavior-y: contain;
  }
}

[data-app-mode="standalone"] body {
  overscroll-behavior-y: none;
}

[data-app-mode="standalone"] .screen-scroll,
[data-app-mode="standalone"] .col-scroll,
[data-app-mode="standalone"] .det-body {
  overscroll-behavior-y: contain;
}

@media (display-mode: standalone) and (max-width: 767px) {
  .page-bar,
  .app-header {
    height: calc(var(--bar-h) + env(safe-area-inset-top, 0px));
    padding-top: env(safe-area-inset-top, 0px);
  }

  .reader-topbar {
    height: calc(var(--bar-h) + env(safe-area-inset-top, 0px));
    padding-top: env(safe-area-inset-top, 0px);
  }

  .toast,
  .sync-toast {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  }

  .read-foot {
    bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 12px));
  }
}
